From 872cc080f19023a47789fd1185b3021533b86101 Mon Sep 17 00:00:00 2001 From: teknomunk Date: Sun, 20 Oct 2024 13:15:47 -0500 Subject: [PATCH] Change mcl_bows to use standard vl_projectile on_step handler, move burning behavior to vl_projectile --- mods/ITEMS/mcl_bows/arrow.lua | 97 +++++++++++++++---------------- mods/ITEMS/vl_projectile/api.md | 1 + mods/ITEMS/vl_projectile/init.lua | 17 ++++++ 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index d90d5a13d..1c4194de0 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -133,6 +133,53 @@ local arrow_entity = { return { fleshy = self._damage } end, behaviors = { + vl_projectile.burns, + + -- Custom arrow behaviors + function(self, dtime) + -- Stuck handling + if self._stuck then + stuck_arrow_on_step(self, dtime) + return + end + + local pos = self.object:get_pos() + self._allow_punch = self._allow_punch or not self._owner or not self._startpos or pos and vector.distance(self._startpos, pos) > 1.5 + + -- Add tracer + if self._damage >= 9 and self._in_player == false then + minetest.add_particlespawner({ + amount = 20, + time = .2, + minpos = vector.zero(), + maxpos = vector.zero(), + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + attached = self.object, + collisiondetection = false, + vertical = false, + texture = "mobs_mc_arrow_particle.png", + glow = 1, + }) + end + + -- Give the arrows a maximum flight time + self._time_in_air = (self._time_in_air or 0) + dtime + if self._time_in_air > ARROW_TIMEOUT then + self._removed = true + self.object:remove() + return true + end + + if self._deflection_cooloff > 0 then + self._deflection_cooloff = self._deflection_cooloff - dtime + end + end, + vl_projectile.collides_with_solids, vl_projectile.raycast_collides_with_entities, }, @@ -214,7 +261,6 @@ local arrow_entity = { end if obj:get_hp() > 0 then - -- Check if there is no solid node between arrow and object if lua then local entity_name = lua.name -- Achievement for hitting skeleton, wither skeleton or stray (TODO) with an arrow at least 50 meters away @@ -245,55 +291,6 @@ local arrow_entity = { self.object:remove() end }, - on_step = function(self, dtime) - mcl_burning.tick(self.object, dtime, self) - - -- mcl_burning.tick may remove object immediately - if not self.object:get_pos() then return end - - self._time_in_air = (self._time_in_air or 0) + dtime - - -- Give the arrows a maximum flight time - if self._time_in_air > ARROW_TIMEOUT then - self._removed = true - self.object:remove() - end - - local pos = self.object:get_pos() - self._allow_punch = self._allow_punch or not self._owner or not self._startpos or pos and vector.distance(self._startpos, pos) > 1.5 - - if self._stuck then - return stuck_arrow_on_step(self, dtime) - end - - -- Add tracer - if self._damage >= 9 and self._in_player == false then - minetest.add_particlespawner({ - amount = 20, - time = .2, - minpos = vector.zero(), - maxpos = vector.zero(), - minvel = vector.new(-0.1,-0.1,-0.1), - maxvel = vector.new(0.1,0.1,0.1), - minexptime = 0.5, - maxexptime = 0.5, - minsize = 2, - maxsize = 2, - attached = self.object, - collisiondetection = false, - vertical = false, - texture = "mobs_mc_arrow_particle.png", - glow = 1, - }) - end - - if self._deflection_cooloff > 0 then - self._deflection_cooloff = self._deflection_cooloff - dtime - end - - -- Process as projectile - vl_projectile.update_projectile(self, dtime) - end, -- Force recheck of stuck arrows when punched. -- Otherwise, punching has no effect. diff --git a/mods/ITEMS/vl_projectile/api.md b/mods/ITEMS/vl_projectile/api.md index b77099cad..b132546af 100644 --- a/mods/ITEMS/vl_projectile/api.md +++ b/mods/ITEMS/vl_projectile/api.md @@ -62,6 +62,7 @@ Arguments: The projectile API supports specifying the behaviors that a projectile will exhibit. There are several standard behaviors provided with the API: +* `vl_projectile.burns`: Projectiles can be set on fire * `vl_projectile.collides_with_solids`: handles collisions between projectiles and solid nodes * `vl_projectile.collides_with_entities`: handles collisions between projectiles and entities by checking nearby entities * `vl_projectile.raycast_collides_with_entities`: handles collisions between projectils and entities by performing a raycast diff --git a/mods/ITEMS/vl_projectile/init.lua b/mods/ITEMS/vl_projectile/init.lua index 8b85a9895..f8107de3c 100644 --- a/mods/ITEMS/vl_projectile/init.lua +++ b/mods/ITEMS/vl_projectile/init.lua @@ -186,6 +186,23 @@ local function handle_player_sticking(self, entity_def, projectile_def, entity) ) end +function mod.burns(self, dtime, entity_def, projectile_def) + mcl_burning.tick(self.object, dtime, self) + + -- mcl_burning.tick may remove object immediately + local pos = self.object:get_pos() + if not pos then return true end + + -- Handle getting set on fire + local node = minetest.get_node(vector.round(pos)) + if not node or node.name == "ignore" then return end + + local set_on_fire = minetest.get_item_group(node.name, "set_on_fire") + if set_on_fire ~= 0 then + mcl_burning.set_on_fire(self.object, set_on_fire) + end +end + function mod.collides_with_solids(self, dtime, entity_def, projectile_def) local pos = self.object:get_pos() if not pos then return end