From 4516bac65f9a51f48157472603d022810015eb29 Mon Sep 17 00:00:00 2001 From: ElCeejo Date: Thu, 31 Mar 2022 18:46:48 -0700 Subject: [PATCH] Minor improvements and fixes to movement methods --- api.lua | 5 ----- boids.lua | 6 +++--- methods.lua | 24 ++++++++++++++++-------- mob_meta.lua | 10 ++++------ spawning.lua | 45 ++++++++++++++++++++++++++++++++++++--------- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/api.lua b/api.lua index 50cfacc..9377922 100644 --- a/api.lua +++ b/api.lua @@ -92,11 +92,6 @@ local function is_under_solid(pos) return (walkable(pos2) or ((get_node_height(pos2) or 0) < 1.5)) end -local function is_node_walkable(name) - local def = minetest.registered_nodes[name] - return def and def.walkable -end - local function is_value_in_table(tbl, val) for _, v in pairs(tbl) do if v == val then diff --git a/boids.lua b/boids.lua index e690c51..1c6be5a 100644 --- a/boids.lua +++ b/boids.lua @@ -116,7 +116,7 @@ function creatura.get_boid_angle(self, boid, range) -- calculates boid angle bas local boid_yaw = boid:get_yaw() table.insert(positions, boid_pos) if boid ~= self.object then - table.insert(lifts, boid:get_velocity().y) + table.insert(lifts, vec_normal(boid:get_velocity()).y) table.insert(angles, boid:get_yaw()) if not closest_pos or vec_dist(pos, boid_pos) < vec_dist(pos, closest_pos) then @@ -132,13 +132,13 @@ function creatura.get_boid_angle(self, boid, range) -- calculates boid angle bas local alignment = average_angle(angles) center = vec_add(center, yaw2dir(alignment)) local dir2center = vec_dir(pos, center) - local seperation = dir2yaw(vector.multiply(dir2center, -1)) + local seperation = yaw + -(dir2yaw(dir2closest) - yaw) local cohesion = dir2yaw(dir2center) local params = {alignment} if self.boid_heading then table.insert(params, yaw + self.boid_heading) end - if dist_2d(pos, closest_pos) < (self.boid_seperation or self.width * 3) then -- seperation is causing north issue + if dist_2d(pos, closest_pos) < (self.boid_seperation or self.width * 3) then table.insert(params, seperation) elseif dist_2d(pos, center) > (#boids * 0.33) * (self.boid_seperation or self.width * 3) then table.insert(params, cohesion) diff --git a/methods.lua b/methods.lua index 77bd578..034d34b 100644 --- a/methods.lua +++ b/methods.lua @@ -171,7 +171,7 @@ creatura.register_movement_method("creatura:pathfind", function(self, pos2) end local yaw = self.object:get_yaw() local tgt_yaw = dir2yaw(dir2waypoint) - local turn_rate = abs(self.turn_rate) or 5 + local turn_rate = abs(self.turn_rate or 5) local yaw_diff = abs(diff(yaw, tgt_yaw)) -- Moving self:set_gravity(-9.8) @@ -183,7 +183,9 @@ creatura.register_movement_method("creatura:pathfind", function(self, pos2) turn_rate = turn_rate * 1.5 end self:turn_to(tgt_yaw, turn_rate) - if self:pos_in_box(pos2) then + if self:pos_in_box(pos2) + or (waypoint + and not self:is_pos_safe(waypoint)) then self:halt() end end) @@ -216,7 +218,7 @@ creatura.register_movement_method("creatura:theta_pathfind", function(self, pos2 end local yaw = self.object:get_yaw() local tgt_yaw = dir2yaw(dir2waypoint) - local turn_rate = abs(self.turn_rate) or 5 + local turn_rate = abs(self.turn_rate or 5) local yaw_diff = abs(diff(yaw, tgt_yaw)) -- Moving self:set_gravity(-9.8) @@ -228,7 +230,9 @@ creatura.register_movement_method("creatura:theta_pathfind", function(self, pos2 turn_rate = turn_rate * 1.5 end self:turn_to(tgt_yaw, turn_rate) - if self:pos_in_box(pos2) then + if self:pos_in_box(pos2) + or (waypoint + and not self:is_pos_safe(waypoint)) then self:halt() end end) @@ -254,7 +258,7 @@ creatura.register_movement_method("creatura:neighbors", function(self, pos2) end local yaw = self.object:get_yaw() local tgt_yaw = dir2yaw(dir2waypoint) - local turn_rate = self.turn_rate or 5 + local turn_rate = abs(self.turn_rate or 5) local yaw_diff = abs(diff(yaw, tgt_yaw)) -- Moving self:set_gravity(-9.8) @@ -266,7 +270,9 @@ creatura.register_movement_method("creatura:neighbors", function(self, pos2) turn_rate = turn_rate * 1.5 end self:turn_to(tgt_yaw, turn_rate) - if self:pos_in_box(pos2) then + if self:pos_in_box(pos2) + or (waypoint + and not self:is_pos_safe(waypoint)) then self:halt() end end) @@ -322,7 +328,7 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self, end local yaw = self.object:get_yaw() local tgt_yaw = dir2yaw(dir2waypoint) - local turn_rate = self.turn_rate or 5 + local turn_rate = abs(self.turn_rate or 5) local yaw_diff = abs(diff(yaw, tgt_yaw)) -- Moving self:set_gravity(-9.8) @@ -334,7 +340,9 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self, turn_rate = turn_rate * 1.5 end self:turn_to(tgt_yaw, turn_rate) - if self:pos_in_box(pos2) then + if self:pos_in_box(pos2) + or (waypoint + and not self:is_pos_safe(waypoint)) then self:halt() end end) \ No newline at end of file diff --git a/mob_meta.lua b/mob_meta.lua index b7c86d8..fa546a1 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -407,7 +407,6 @@ end function mob:get_wander_pos_3d(min_range, max_range, dir, vert_bias) local pos = vec_center(self.object:get_pos()) - pos.y = floor(pos.y + 0.5) local node = minetest.get_node(pos) if get_node_def(node.name).walkable then -- Occurs if small mob is touching a fence local offset = vector.add(pos, vec_multi(vec_dir(pos, self.object:get_pos()), 1.5)) @@ -443,10 +442,7 @@ function mob:get_wander_pos_3d(min_range, max_range, dir, vert_bias) for i = 1, outset do local a_pos = vec_add(pos2, vec_multi(move_dir, i)) local a_node = minetest.get_node(a_pos) - local b_pos = {x = a_pos.x, y = a_pos.y - 1, z = a_pos.z} - local b_node = minetest.get_node(b_pos) - if get_node_def(a_node.name).walkable - or not get_node_def(b_node.name).walkable then + if get_node_def(a_node.name).walkable then a_pos = get_ground_level(a_pos, floor(self.stepheight or 1)) end if not get_node_def(a_node.name).walkable then @@ -463,7 +459,8 @@ function mob:is_pos_safe(pos) local node = minetest.get_node(pos) if not node then return false end if minetest.get_item_group(node.name, "igniter") > 0 - or get_node_def(node.name).drawtype == "liquid" then return false end + or get_node_def(node.name).drawtype == "liquid" + or get_node_def(minetest.get_node(vec_raise(pos, -1)).name).drawtype == "liquid" then return false end local fall_safe = false if self.max_fall ~= 0 then for i = 1, self.max_fall or 3 do @@ -681,6 +678,7 @@ function mob:set_utility(func) end function mob:get_utility() + if not self._utility_data then return end return self._utility_data.utility end diff --git a/spawning.lua b/spawning.lua index 1f61dff..eff35ec 100644 --- a/spawning.lua +++ b/spawning.lua @@ -82,6 +82,15 @@ function creatura.register_mob_spawn(name, def) creatura.registered_mob_spawns[name] = spawn end +creatura.registered_on_spawns = {} + +function creatura.register_on_spawn(name, func) + if not creatura.registered_on_spawns[name] then + creatura.registered_on_spawns[name] = {} + end + table.insert(creatura.registered_on_spawns[name], func) +end + -- Utility Functions -- @@ -187,11 +196,11 @@ function execute_spawns(player) return end - local light_pos = spawn_pos if not spawn.spawn_in_nodes then - light_pos = vec_raise(spawn_pos, 1) + spawn_pos = vec_raise(spawn_pos, 1) end - local light = minetest.get_node_light(light_pos) or 7 + + local light = minetest.get_node_light(spawn_pos) or 7 if light > spawn.max_light or light < spawn.min_light then @@ -257,18 +266,27 @@ minetest.register_abm({ local meta = minetest.get_meta(pos) local name = meta:get_string("mob") local amount = meta:get_int("cluster") + local obj if amount > 0 then for i = 1, amount do - minetest.add_entity(pos, name) + obj = minetest.add_entity(pos, name) end else - minetest.add_entity(pos, name) + obj = minetest.add_entity(pos, name) end minetest.remove_node(pos) + if obj + and creatura.registered_on_spawns[name] + and #creatura.registered_on_spawns[name] > 0 then + for i = 1, #creatura.registered_on_spawns[name] do + local func = creatura.registered_on_spawns[name][i] + func(obj:get_luaentity(), pos) + end + end end, }) -minetest.register_lbm({ +--[[minetest.register_lbm({ name = "creatura:spawning", nodenames = {"creatura:spawn_node"}, run_at_every_load = true, @@ -276,13 +294,22 @@ minetest.register_lbm({ local meta = minetest.get_meta(pos) local name = meta:get_string("mob") local amount = meta:get_int("cluster") + local obj if amount > 0 then for i = 1, amount do - minetest.add_entity(pos, name) + obj = minetest.add_entity(pos, name) end else - minetest.add_entity(pos, name) + obj = minetest.add_entity(pos, name) end minetest.remove_node(pos) + if obj + and creatura.registered_on_spawns[name] + and #creatura.registered_on_spawns[name] > 0 then + for i = 1, #creatura.registered_on_spawns[name] do + local func = creatura.registered_on_spawns[name][i] + func(obj:get_luaentity(), pos) + end + end end, -}) \ No newline at end of file +})]] \ No newline at end of file