From 4f49aa0e4785b740a221226d231685e4bbcf5d76 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Sun, 24 Aug 2025 12:19:21 +0100 Subject: [PATCH] use moveresult for arrows, add drop_item --- api.lua | 96 ++++++++++++++++++++++----------------------------------- api.txt | 4 +++ 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/api.lua b/api.lua index c1286af..a369cf2 100644 --- a/api.lua +++ b/api.lua @@ -18,7 +18,7 @@ end -- global table mobs = { - mod = "redo", version = "20250821", + mod = "redo", version = "20250824", spawning_mobs = {}, translate = S, node_snow = has(core.registered_aliases["mapgen_snow"]) or has("mcl_core:snow") or has("default:snow") or "air", @@ -3767,8 +3767,8 @@ function mobs:register_arrow(name, def) core.register_entity(":" .. name, { initial_properties = { - physical = def.physical, - collide_with_objects = def.collide_with_objects or false, + physical = def.physical ~= false, + collide_with_objects = def.collide_with_objects ~= false, static_save = false, visual = def.visual, visual_size = def.visual_size, @@ -3786,6 +3786,7 @@ function mobs:register_arrow(name, def) hit_mob = def.hit_mob, hit_object = def.hit_object, drop = def.drop, -- chance of dropping arrow as registered item + drop_item = def.drop_item, -- custom item drop timer = 0, lifetime = def.lifetime or 4.5, owner_id = def.owner_id, @@ -3796,15 +3797,15 @@ function mobs:register_arrow(name, def) on_punch = def.on_punch or function(self, hitter, tflp, tool_capabilities, dir) end, - on_step = def.on_step or function(self, dtime) + on_step = def.on_step or function(self, dtime, moveresult) self.timer = self.timer + dtime - local pos = self.object:get_pos() + local pos = self.object:get_pos() ; self.lastpos = pos if self.timer > self.lifetime then - self.object:remove() ; -- print("removed arrow") + self.object:remove() ; -- print("-- removed arrow") return end @@ -3833,87 +3834,62 @@ function mobs:register_arrow(name, def) if core.line_of_sight(self.object:get_pos(), p) then - self.object:set_velocity( - vector.direction(self.object:get_pos(), p) * self.velocity) + self.object:set_velocity(vector.direction( + self.object:get_pos(), p) * self.velocity) end else self._homing_target = nil end end - self.lastpos = self.lastpos or pos + -- did a solid arrow hit a solid thing? + if moveresult and moveresult.collides then - local cast = core.raycast(self.lastpos, pos, true, true) - local thing = cast:next() + local def = moveresult.collisions and moveresult.collisions[1] or {} - while thing do -- loop through things + self.moveresult = moveresult -- pass moveresult into arrow entity - -- if inside object that isn't arrow - if thing.type == "object" and thing.ref ~= self.object - and tostring(thing.ref) ~= self.owner_id then + -- hit node + if def.type == "node" and self.hit_node then - if self.hit_player and is_player(thing.ref) then + local node = core.get_node(def.node_pos) - self:hit_player(thing.ref) + self:hit_node(pos, node) ; --print("-- hit node", node.name) ---print("hit player", thing.ref:get_player_name()) + if (type(self.drop) == "boolean" and self.drop) + or (type(self.drop) == "number" and random(self.drop) == 1) then - self.object:remove() ; return + local drop = self.drop_item or self.object:get_luaentity().name + core.add_item(pos, drop) ; --print("-- arrow drop", drop) end - - local entity = thing.ref:get_luaentity() - - if entity and self.hit_mob and entity._cmi_is_mob then - - self:hit_mob(thing.ref) - ---print("hit mob", entity.name) - - self.object:remove() ; return - end - - if entity and self.hit_object and (not entity._cmi_is_mob) then - - self:hit_object(thing.ref) - ---print("hit object", entity.name) - - self.object:remove() ; return - end - end - -- if inside node - if thing.type == "node" and self.hit_node then + if def.type == "object" then - local node = core.get_node(pos) - local def = core.registered_nodes[node.name] + local obj = def.object - if def and def.walkable then + if is_player(obj) and self.hit_player then + self:hit_player(obj) ; --print("-- hit player", obj:get_player_name()) + end - self:hit_node(pos, node) + local entity = obj:get_luaentity() - if (type(self.drop) == "boolean" and self.drop) - or (type(self.drop) == "number" and random(self.drop) == 1) then + if entity then - pos.y = pos.y + 1 + if entity._cmi_is_mob and self.hit_mob then - core.add_item(self.lastpos, - self.object:get_luaentity().name) + self:hit_mob(obj) ; --print("-- hit mob", entity.name) + + elseif self.hit_object then + + self:hit_object(obj) ; --print("-- hit object", entity.name) end - ---print("hit node", node.name) - - self.object:remove() ; return end end - thing = cast:next() - - end -- end thing loop - - self.lastpos = pos + self.object:remove() ; return -- remove arrow after hitting solid item + end end }) end diff --git a/api.txt b/api.txt index 42f5165..496bb4f 100644 --- a/api.txt +++ b/api.txt @@ -592,6 +592,7 @@ This function registers a arrow for mobs with the attack type shoot. 'drop' if set to true any arrows hitting a node will drop as item, if number given then chance (1/num) of item dropping will be used. arrow "mymob:myarrow" will use item of same name. + 'drop_item' name of custom item to drop instead of arrow. 'hit_player' a function that is called when the arrow hits a player; this function should hurt the player, the parameters are (self, player) @@ -617,6 +618,9 @@ This function registers a arrow for mobs with the attack type shoot. 'lifetime' contains float value for how many seconds arrow exists in world before being removed (default is 4.5 seconds). +Note: When an arrow hits a solid item moveresult is copied into the arrow + self.moveresult for use inside the hit functions. + Spawn Eggs ----------