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 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)
|
||||
if positions == "x" then
|
||||
return math.random(-4, 4)
|
||||
|
@ -123,6 +118,7 @@ local arrow_entity = {
|
|||
textures = {"mcl_bows_arrow.png"},
|
||||
collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19},
|
||||
collide_with_objects = false,
|
||||
liquid_drag = true,
|
||||
_fire_damage_resistant = true,
|
||||
|
||||
_save_fields = {
|
||||
|
@ -348,35 +344,11 @@ local arrow_entity = {
|
|||
self._deflection_cooloff = self._deflection_cooloff - dtime
|
||||
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
|
||||
vl_projectile.update_projectile(self, dtime)
|
||||
|
||||
-- Update yaw
|
||||
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,
|
||||
|
||||
-- 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)
|
||||
|
||||
-- Ender pearl entity
|
||||
minetest.register_entity("mcl_throwing:ender_pearl_entity",{
|
||||
vl_projectile.register("mcl_throwing:ender_pearl_entity",{
|
||||
physical = false,
|
||||
timer=0,
|
||||
textures = {"mcl_throwing_ender_pearl.png"},
|
||||
|
|
|
@ -10,19 +10,21 @@ Arguments:
|
|||
* `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
|
||||
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.
|
||||
* `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)`
|
||||
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)`.
|
||||
* `behaviors`: a list of behavior callbacks that define the projectile's behavior. This mod provides two
|
||||
behaviors: `vl_projectiles.collides_with_solids`, `vl_projectiles.collides_with_entities` and `vl_projectiles_raycast_collieds_with_entities`
|
||||
* `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 the following
|
||||
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
|
||||
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_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"`
|
||||
* `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"`
|
||||
* `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.
|
||||
|
|
|
@ -1,9 +1,64 @@
|
|||
local 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 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)
|
||||
if self._removed then return end
|
||||
|
||||
|
@ -22,6 +77,8 @@ function mod.update_projectile(self, dtime)
|
|||
return
|
||||
end
|
||||
end
|
||||
|
||||
mod.projectile_physics(self.object, entity_def)
|
||||
end
|
||||
|
||||
local function no_op()
|
||||
|
@ -300,14 +357,13 @@ function mod.raycast_collides_with_entities(self, dtime, entity_def, projectile_
|
|||
end
|
||||
|
||||
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
|
||||
obj:set_velocity(vector.multiply(options.dir or vector.zero(), options.velocity or 0))
|
||||
obj:set_acceleration(vector.add(
|
||||
vector.multiply(options.dir or vector.zero(), -math.abs(options.drag)),
|
||||
vector.new(0,-GRAVITY,0)
|
||||
))
|
||||
-- Set initial velocity and acceleration
|
||||
local v = vector.multiply(options.dir or vector.zero(), options.velocity or 0)
|
||||
local a = vector.multiply(v, -math.abs(options.drag))
|
||||
mod.projectile_physics(obj, entity_def, v, a)
|
||||
|
||||
-- Update projectile parameters
|
||||
local luaentity = obj:get_luaentity()
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
name = vl_projectile
|
||||
depends = mcl_util
|
||||
optional_depends = vl_physics
|
||||
|
|
Loading…
Reference in New Issue