1
0
mirror of https://codeberg.org/tenplus1/mobs_redo.git synced 2025-08-26 19:20:28 +02:00

use moveresult for arrows, add drop_item

This commit is contained in:
tenplus1
2025-08-24 12:19:21 +01:00
parent aebd9d03db
commit 4f49aa0e47
2 changed files with 40 additions and 60 deletions

108
api.lua
View File

@ -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)
--print("hit player", thing.ref:get_player_name())
self.object:remove() ; return
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
local node = core.get_node(pos)
local def = core.registered_nodes[node.name]
if def and def.walkable then
self:hit_node(pos, node)
self:hit_node(pos, node) ; --print("-- hit node", node.name)
if (type(self.drop) == "boolean" and self.drop)
or (type(self.drop) == "number" and random(self.drop) == 1) then
pos.y = pos.y + 1
local drop = self.drop_item or self.object:get_luaentity().name
core.add_item(self.lastpos,
self.object:get_luaentity().name)
end
--print("hit node", node.name)
self.object:remove() ; return
core.add_item(pos, drop) ; --print("-- arrow drop", drop)
end
end
thing = cast:next()
if def.type == "object" then
end -- end thing loop
local obj = def.object
self.lastpos = pos
if is_player(obj) and self.hit_player then
self:hit_player(obj) ; --print("-- hit player", obj:get_player_name())
end
local entity = obj:get_luaentity()
if entity then
if entity._cmi_is_mob and self.hit_mob then
self:hit_mob(obj) ; --print("-- hit mob", entity.name)
elseif self.hit_object then
self:hit_object(obj) ; --print("-- hit object", entity.name)
end
end
end
self.object:remove() ; return -- remove arrow after hitting solid item
end
end
})
end

View File

@ -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
----------