diff --git a/api.lua b/api.lua index fcc4799..c30f9d7 100644 --- a/api.lua +++ b/api.lua @@ -80,13 +80,13 @@ function creatura.is_alive(mob) return false end if type(mob) == "table" then - return mob.hp > 0 + return (mob.hp or mob.health or 0) > 0 end if mob:is_player() then return mob:get_hp() > 0 else local ent = mob:get_luaentity() - return ent and ent.hp and ent.hp > 0 + return ent and (ent.hp or ent.health or 0) > 0 end end @@ -360,8 +360,8 @@ local get_objects = minetest.get_objects_inside_radius function creatura.get_nearby_player(self, range) local pos = self.object:get_pos() if not pos then return end - local stored_objs = self._nearby_objs or {} - local objects = (#stored_objs > 0 and stored_objs) or get_objects(pos, range or self.tracking_range) + local stored = self._nearby_obj or {} + local objects = (#stored > 0 and stored) or self:store_nearby_objects(range) for _, object in ipairs(objects) do if object:is_player() and creatura.is_alive(object) then @@ -373,8 +373,8 @@ end function creatura.get_nearby_players(self, range) local pos = self.object:get_pos() if not pos then return end - local stored_objs = self._nearby_objs or {} - local objects = (#stored_objs > 0 and stored_objs) or get_objects(pos, range or self.tracking_range) + local stored = self._nearby_obj or {} + local objects = (#stored > 0 and stored) or self:store_nearby_objects(range) local nearby = {} for _, object in ipairs(objects) do if object:is_player() @@ -388,8 +388,8 @@ end function creatura.get_nearby_object(self, name, range) local pos = self.object:get_pos() if not pos then return end - local stored_objs = self._nearby_objs or {} - local objects = (#stored_objs > 0 and stored_objs) or get_objects(pos, range or self.tracking_range) + local stored = self._nearby_obj or {} + local objects = (#stored > 0 and stored) or self:store_nearby_objects(range) for _, object in ipairs(objects) do local ent = creatura.is_alive(object) and object:get_luaentity() if ent @@ -405,8 +405,8 @@ end function creatura.get_nearby_objects(self, name, range) local pos = self.object:get_pos() if not pos then return end - local stored_objs = self._nearby_objs or {} - local objects = (#stored_objs > 0 and stored_objs) or get_objects(pos, range or self.tracking_range) + local stored = self._nearby_obj or {} + local objects = (#stored > 0 and stored) or self:store_nearby_objects(range) local nearby = {} for _, object in ipairs(objects) do local ent = creatura.is_alive(object) and object:get_luaentity() diff --git a/methods.lua b/methods.lua index 10e39cf..0acd80c 100644 --- a/methods.lua +++ b/methods.lua @@ -142,7 +142,6 @@ local function get_avoidance_dir(self) local avoidance_force = vector.subtract(ahead, col_pos) avoidance_force.y = 0 avoidance_force = vec_multi(vec_normal(avoidance_force), (vel_len > 1 and vel_len) or 1) - --debugpart(vec_add(ahead, avoidance_force)) return vec_dir(pos, vec_add(ahead, avoidance_force)) end end @@ -247,7 +246,6 @@ end creatura.register_movement_method("creatura:pathfind", function(self) local path = {} local box = clamp(self.width, 0.5, 1.5) - self:set_gravity(-9.8) local trimmed = false local init_path = false local function func(_self, goal, speed_factor) @@ -258,6 +256,7 @@ creatura.register_movement_method("creatura:pathfind", function(self) _self:halt() return true end + self:set_gravity(-9.8) -- Get movement direction local steer_to = get_avoidance_dir(self, goal) local goal_dir = vec_dir(pos, goal) @@ -303,7 +302,6 @@ end) creatura.register_movement_method("creatura:theta_pathfind", function(self) local path = {} local box = clamp(self.width, 0.5, 1.5) - self:set_gravity(-9.8) local function func(_self, goal, speed_factor) local pos = _self.object:get_pos() if not pos then return end @@ -313,6 +311,7 @@ creatura.register_movement_method("creatura:theta_pathfind", function(self) _self:halt() return true end + self:set_gravity(-9.8) -- Get movement direction local steer_to = get_avoidance_dir(_self, goal) local goal_dir = vec_dir(pos, goal) @@ -351,10 +350,12 @@ end) creatura.register_movement_method("creatura:obstacle_avoidance", function(self) local box = clamp(self.width, 0.5, 1.5) - self:set_gravity(-9.8) + local avd_step = 5 + local steer_to local function func(_self, goal, speed_factor) local pos = _self.object:get_pos() if not pos then return end + self:set_gravity(-9.8) goal.y = creatura.get_ground_level(goal, 2).y pos.y = creatura.get_ground_level(pos, 2).y -- Return true when goal is reached @@ -363,11 +364,9 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self) return true end -- Get movement direction - local goal_dir = vec_dir(pos, goal) - local steer_to = get_avoidance_dir(self, goal) - if steer_to then - goal_dir = steer_to - end + avd_step = (avd_step <= 0 and 5) or avd_step - 1 + steer_to = (avd_step > 1 and steer_to) or (avd_step <= 0 and get_avoidance_dir(self, goal)) + local goal_dir = steer_to or vec_dir(pos, goal) local yaw = _self.object:get_yaw() local goal_yaw = dir2yaw(goal_dir) local speed = abs(_self.speed or 2) * speed_factor or 0.5 diff --git a/mob_meta.lua b/mob_meta.lua index 1f0fa00..827f856 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -58,15 +58,6 @@ end -- Physics/Vitals Tick -- ------------------------- -local step_tick = 0.15 - -minetest.register_globalstep(function(dtime) - if step_tick <= 0 then - step_tick = 0.15 - end - step_tick = step_tick - dtime -end) - local mob = { max_health = 20, armor_groups = {fleshy = 100}, @@ -215,9 +206,8 @@ function mob:do_velocity() local vel = self.object:get_velocity() local yaw = self.object:get_yaw() if not yaw then return end - local horz_vel = data.horz_vel - local vert_vel = data.vert_vel - if horz_vel and horz_vel < 1 then horz_vel = 1 end + local horz_vel = data.horz_vel or (data.gravity == 0 and 0) + local vert_vel = data.vert_vel or (data.gravity == 0 and 0) vel.x = (horz_vel and (sin(yaw) * -horz_vel)) or vel.x vel.y = vert_vel or vel.y vel.z = (horz_vel and (cos(yaw) * horz_vel)) or vel.z @@ -440,6 +430,7 @@ function mob:animate(animation) if not self._anim or self._anim ~= animation then local anim = self.animations[animation] + if anim[2] then anim = anim[random(#anim)] end self.object:set_animation(anim.range, anim.speed, anim.frame_blend, anim.loop) self._anim = animation end @@ -629,10 +620,12 @@ function mob:get_target(target) return true, line_of_sight, tpos end -function mob:store_nearby_objects() +function mob:store_nearby_objects(radius) local pos = self.object:get_pos() if not pos then return end - local objects = minetest.get_objects_inside_radius(pos, self.tracking_range or 8) + local track_radius = self.tracking_range or 8 + if track_radius < 8 then track_radius = 8 end + local objects = minetest.get_objects_inside_radius(pos, radius or track_radius) if #objects < 1 then return end local objs = {} for _, object in ipairs(objects) do @@ -648,6 +641,7 @@ function mob:store_nearby_objects() end end self._nearby_objs = objs + return objs end -- Actions @@ -668,6 +662,7 @@ function mob:clear_action() end function mob:set_utility(func) + if not self._utility_data then return end self._utility_data.func = func end @@ -831,7 +826,9 @@ function mob:on_step(dtime, moveresult) end local stand_pos local stand_node - if step_tick <= 0 then + local prop_tick = self._prop_tick or 0 + prop_tick = prop_tick - 1 + if prop_tick <= 0 then stand_pos = self.object:get_pos() if not stand_pos then return end stand_node = minetest.get_node(stand_pos) @@ -839,7 +836,9 @@ function mob:on_step(dtime, moveresult) self.properties = self.object:get_properties() self.width = self:get_hitbox()[4] or 0.5 self.height = self:get_height() or 1 + prop_tick = 6 end + self._prop_tick = prop_tick if stand_pos and stand_node then if self._vitals then @@ -1175,8 +1174,14 @@ function mob:_execute_utilities() end local dtime = self.dtime self.dtime = dtime + (self.step_delay or 0) - self:set_forward_velocity(nil) - self:set_vertical_velocity(nil) + if self.horz_vel + and self.horz_vel ~= 0 then + self:set_forward_velocity(nil) + end + if self.vert_vel + and self.vert_vel ~= 0 then + self:set_vertical_velocity(nil) + end if func(self) then self._utility_data = { utility = nil, @@ -1200,7 +1205,6 @@ end function mob:_vitals(pos, node) if not pos or not node then return end - local stand_def = creatura.get_node_def(node.name) local max_fall = self.max_fall or 0 local in_liquid = self.in_liquid local on_ground = self.touching_ground @@ -1221,6 +1225,7 @@ function mob:_vitals(pos, node) end end if self:timer(1) then + local stand_def = creatura.get_node_def(node.name) local head_pos = vec_raise(pos, self.height) local head_node = minetest.get_node(head_pos) if minetest.get_item_group(head_node.name, "liquid") > 0 then