From e8e774566b5cab274ee39ef5b37c0edfd837f732 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Sat, 14 Sep 2024 12:25:52 +0100 Subject: [PATCH] tweak collision, falling and arrow drops. --- api.lua | 37 ++++++++++++++++++------------------- api.txt | 4 +++- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/api.lua b/api.lua index 1b37d83..50fa9b0 100644 --- a/api.lua +++ b/api.lua @@ -276,15 +276,13 @@ function mob_class:collision() local width = -prop.collisionbox[1] + prop.collisionbox[4] + 0.5 local pos2, vec, force - for _,player in pairs(minetest.get_connected_players()) do + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - pos2 = player:get_pos() - - if get_distance(pos2, pos) < width then + if object:is_player() then + pos2 = object:get_pos() vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} - - force = (width + 0.5) - vector.distance( + force = width - vector.distance( {x = pos.x, y = 0, z = pos.z}, {x = pos2.x, y = 0, z = pos2.z}) x = x + (vec.x * force) @@ -583,14 +581,7 @@ local function effect( radius = radius or 2 gravity = gravity or -10 - - if fall == true then - fall = 0 - elseif fall == false then - fall = radius - else - fall = -radius - end + fall = fall == true and 0 or fall == false and radius or -radius minetest.add_particlespawner({ amount = amount, @@ -976,7 +967,7 @@ function mob_class:is_at_cliff() return (not def and def.walkable) end --- check for nodes or groups inside mob +-- check for nodes or groups inside mob collision area function mob_class:is_inside(itemtable) @@ -2581,11 +2572,18 @@ function mob_class:falling(pos) -- fall damage onto solid ground if self.fall_damage and self.object:get_velocity().y == 0 then - local d = (self.old_y or 0) - self.object:get_pos().y + local d = (self.old_y or self.object:get_pos().y) - self.object:get_pos().y if d > 5 then - self.health = self.health - floor(d - 5) + local add = minetest.get_item_group(self.standing_on, "fall_damage_add_percent") + local damage = d - 5 + + if add ~= 0 then + damage = damage + damage * (add / 100) + end + + self.health = self.health - floor(damage) effect(pos, 5, "tnt_smoke.png", 1, 2, 2, nil) @@ -4003,7 +4001,7 @@ function mobs:register_arrow(name, def) hit_node = def.hit_node, hit_mob = def.hit_mob, hit_object = def.hit_object, - drop = def.drop or false, -- drops arrow as registered item when true + drop = def.drop, -- chance of dropping arrow as registered item timer = 0, lifetime = def.lifetime or 4.5, owner_id = def.owner_id, @@ -4120,7 +4118,8 @@ function mobs:register_arrow(name, def) self:hit_node(pos, node) - if self.drop == true then + if (type(self.drop) == "boolean" and self.drop == true) + or (type(self.drop) == "number" and random(self.drop) == 1) then pos.y = pos.y + 1 diff --git a/api.txt b/api.txt index 9c41f8f..7ece4e4 100644 --- a/api.txt +++ b/api.txt @@ -560,7 +560,9 @@ This function registers a arrow for mobs with the attack type shoot. 'textures' same is in minetest.register_entity() 'collide_with_objects' same as above 'velocity' the velocity of the arrow - 'drop' if set to true any arrows hitting a node will drop as item + '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. 'hit_player' a function that is called when the arrow hits a player; this function should hurt the player, the parameters are (self, player)