From 8c55d13a292e9d7393f4d91d3f898a2ea28d48b9 Mon Sep 17 00:00:00 2001 From: teknomunk Date: Sun, 1 Sep 2024 20:41:21 -0500 Subject: [PATCH] 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 --- mods/ITEMS/mcl_bows/arrow.lua | 30 +---------- mods/ITEMS/mcl_throwing/ender_pearl.lua | 2 +- mods/ITEMS/vl_projectile/api.md | 10 ++-- mods/ITEMS/vl_projectile/init.lua | 70 ++++++++++++++++++++++--- mods/ITEMS/vl_projectile/mod.conf | 1 + 5 files changed, 72 insertions(+), 41 deletions(-) diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index e287265d4..d0e1ab4c8 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -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. diff --git a/mods/ITEMS/mcl_throwing/ender_pearl.lua b/mods/ITEMS/mcl_throwing/ender_pearl.lua index 958321f70..0693b9088 100644 --- a/mods/ITEMS/mcl_throwing/ender_pearl.lua +++ b/mods/ITEMS/mcl_throwing/ender_pearl.lua @@ -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"}, diff --git a/mods/ITEMS/vl_projectile/api.md b/mods/ITEMS/vl_projectile/api.md index b8fd8b005..be2ae4984 100644 --- a/mods/ITEMS/vl_projectile/api.md +++ b/mods/ITEMS/vl_projectile/api.md @@ -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. diff --git a/mods/ITEMS/vl_projectile/init.lua b/mods/ITEMS/vl_projectile/init.lua index cf76e5082..426dcc5fb 100644 --- a/mods/ITEMS/vl_projectile/init.lua +++ b/mods/ITEMS/vl_projectile/init.lua @@ -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() diff --git a/mods/ITEMS/vl_projectile/mod.conf b/mods/ITEMS/vl_projectile/mod.conf index b17cd8550..5d17120b3 100644 --- a/mods/ITEMS/vl_projectile/mod.conf +++ b/mods/ITEMS/vl_projectile/mod.conf @@ -1,2 +1,3 @@ name = vl_projectile depends = mcl_util +optional_depends = vl_physics