diff --git a/api.lua b/api.lua index dd7fc41..372754d 100644 --- a/api.lua +++ b/api.lua @@ -135,7 +135,8 @@ function creatura.get_node_def(node) -- Node can be name or pos return def end -function creatura.get_ground_level(pos2, max_diff) +function creatura.get_ground_level(pos, max_diff) + local pos2 = pos -- Prevent modifying table that shouldn't be changed pos2.y = math.floor(pos2.y - 0.49) local node = minetest.get_node(pos2) local node_under = minetest.get_node({ diff --git a/methods.lua b/methods.lua index 769ea3e..5c27871 100644 --- a/methods.lua +++ b/methods.lua @@ -38,7 +38,7 @@ local dir2yaw = minetest.dir_to_yaw texture = tex or "creatura_particle_red.png", expirationtime = time or 3, glow = 6, - size = 12 + size = 1 }) end]] @@ -59,20 +59,17 @@ local function raycast(pos1, pos2, liquid) end local function get_collision(self, yaw) - local width = self.width + 0.5 - local height = self.height + 0.5 + local width = self.width + local height = self.height local total_height = height + self.stepheight local pos = self.object:get_pos() if not pos then return end - local ground = creatura.get_ground_level(pos, (self.stepheight or 2)) - if ground.y > pos.y then - pos = ground - end - local pos2 = vec_add(pos, vec_multi(yaw2dir(yaw), width + 3)) - ground = creatura.get_ground_level(pos2, (self.stepheight or 2)) - if ground.y > pos2.y then - pos2 = ground - end + pos.y = pos.y + 0.1 + local speed = abs(vec_len(self.object:get_velocity())) + local pos2 = vec_add(pos, vec_multi(yaw2dir(yaw), (width + 0.5) * ((speed > 1 and speed) or 1))) + -- Localize for performance + local pos_x, pos_z = pos.x, pos.z + local pos2_x, pos2_z = pos2.x, pos2.z for x = -width, width, width / ceil(width) do local step_flag = false for y = 0, total_height, total_height / ceil(total_height) do @@ -81,14 +78,14 @@ local function get_collision(self, yaw) break end local vec1 = { - x = cos(yaw) * ((pos.x + x) - pos.x) + pos.x, + x = cos(yaw) * ((pos_x + x) - pos_x) + pos_x, y = pos.y + y, - z = sin(yaw) * ((pos.x + x) - pos.x) + pos.z + z = sin(yaw) * ((pos_x + x) - pos_x) + pos_z } local vec2 = { - x = cos(yaw) * ((pos2.x + x) - pos2.x) + pos2.x, + x = cos(yaw) * ((pos2_x + x) - pos2_x) + pos2_x, y = vec1.y, - z = sin(yaw) * ((pos2.x + x) - pos2.x) + pos2.z + z = sin(yaw) * ((pos2_x + x) - pos2_x) + pos2_z } local ray = raycast(vec1, vec2, true) if ray then @@ -101,6 +98,14 @@ local function get_collision(self, yaw) end end end + --[[if width > 0.5 + and height > 0.5 then + else + local ray = raycast(pos, pos2, true) + if ray then + return true, ray.intersection_point + end + end]] return false end @@ -112,7 +117,9 @@ local function get_avoidance_dir(self) local vel = self.object:get_velocity() local ahead = vec_add(pos, vec_normal(self.object:get_velocity())) local avoidance_force = vector.subtract(ahead, col_pos) - avoidance_force = vec_multi(vec_normal(avoidance_force), vec_len(vel)) + avoidance_force.y = 0 + local vel_len = vec_len(vel) + avoidance_force = vec_multi(vec_normal(avoidance_force), (vel_len > 1 and vel_len) or 1) return vec_dir(pos, vec_add(ahead, avoidance_force)) end end @@ -201,6 +208,7 @@ local function trim_path(pos, path) local trim = false local closest for i = #path, 1, -1 do + if not path[i] then break end if (closest and vec_dist(pos, path[i]) > vec_dist(pos, path[closest])) or trim then @@ -327,6 +335,8 @@ 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 steer_to + local steer_timer = 0.25 local function func(_self, goal, speed_factor) local pos = _self.object:get_pos() if not pos then return end @@ -337,7 +347,10 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self) _self:halt() return true end - local steer_to = get_avoidance_dir(_self, goal) + steer_timer = steer_timer - self.dtime + if steer_timer <= 0 then + steer_to = get_avoidance_dir(_self) + end -- Get movement direction local goal_dir = vec_dir(pos, goal) if steer_to then @@ -355,9 +368,7 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self) else _self:set_forward_velocity(speed * 0.33) end - if yaw_diff > 0.1 then - _self:turn_to(goal_yaw, turn_rate) - end + _self:turn_to(goal_yaw, turn_rate) end return func -end) +end) \ No newline at end of file diff --git a/mob_meta.lua b/mob_meta.lua index 56ea7fb..a48dbf3 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -67,25 +67,23 @@ minetest.register_globalstep(function(dtime) step_tick = step_tick - dtime end) --- A metatable is used to avoid issues --- With mobs performing functions outside --- their own scope - local mob = { - -- Stats max_health = 20, armor_groups = {fleshy = 100}, damage = 2, speed = 4, tracking_range = 16, despawn_after = nil, - -- Physics max_fall = 3, stepheight = 1.1, hitbox = { width = 0.5, height = 1 }, + follow = {}, + fancy_collide = false, + bouyancy_multiplier = 1, + hydrodynamics_multiplier = 1 } local mob_meta = {__index = mob} @@ -159,7 +157,7 @@ end -- Turn to specified yaw -local function lerp_rad(a, b, w) +local function interp_rad(a, b, w) local cs = (1 - w) * cos(a) + w * cos(b) local sn = (1 - w) * sin(a) + w * sin(b) return atan2(sn, cs) @@ -170,7 +168,7 @@ function mob:turn_to(tyaw, rate) rate = rate or 5 local yaw = self.object:get_yaw() local step = math.min(self.dtime * rate, abs(diff(yaw, tyaw)) % (pi2)) - self.object:set_yaw(lerp_rad(yaw, tyaw, step)) + self.object:set_yaw(interp_rad(yaw, tyaw, step)) end -- Set Gravity (default of -9.8) @@ -1093,7 +1091,6 @@ function mob:_execute_utilities() } self:clear_action() end - --local us_time = minetest.get_us_time() local action = self._action if action and type(action) ~= "table" then @@ -1101,7 +1098,6 @@ function mob:_execute_utilities() self:clear_action() end end - --minetest.chat_send_all(minetest.get_us_time() - us_time) end end diff --git a/spawning.lua b/spawning.lua index 359013b..2542941 100644 --- a/spawning.lua +++ b/spawning.lua @@ -57,7 +57,7 @@ function creatura.register_spawn_egg(name, col1, col2, inventory_image) -- depre local mobdef = minetest.registered_entities[name] local spawn_offset = abs(mobdef.collisionbox[2]) local pos = minetest.get_pointed_thing_position(pointed_thing, true) - pos.y = (pos.y - 0.49) + spawn_offset + pos.y = (pos.y - 0.4) + spawn_offset local object = minetest.add_entity(pos, name) if object then object:set_yaw(random(1, 6)) @@ -245,6 +245,14 @@ local function execute_spawns(player) return end + local mob_def = minetest.registered_entities[mob] + local mob_width = mob_def.collisionbox[4] + local mob_height = math.max(0, mob_def.collisionbox[5] - mob_def.collisionbox[2]) + + if not creatura.is_pos_moveable(spawn_pos, mob_width, mob_height) then + return + end + local group_size = random(spawn.min_group or 1, spawn.max_group or 1) if spawn.spawn_cluster then @@ -290,7 +298,8 @@ end) minetest.register_node("creatura:spawn_node", { drawtype = "airlike", - groups = {not_in_creative_inventory = 1} + groups = {not_in_creative_inventory = 1}, + walkable = false }) local spawn_interval = tonumber(minetest.settings:get("creatura_spawn_interval")) or 10 @@ -351,4 +360,4 @@ minetest.register_abm({ end end end, -})]] +})]] \ No newline at end of file