mirror of
https://github.com/ElCeejo/creatura.git
synced 2025-04-30 13:51:41 -04:00
Minor improvements and fixes to movement methods
This commit is contained in:
parent
c5af6c9590
commit
4516bac65f
5 changed files with 59 additions and 31 deletions
5
api.lua
5
api.lua
|
@ -92,11 +92,6 @@ local function is_under_solid(pos)
|
||||||
return (walkable(pos2) or ((get_node_height(pos2) or 0) < 1.5))
|
return (walkable(pos2) or ((get_node_height(pos2) or 0) < 1.5))
|
||||||
end
|
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)
|
local function is_value_in_table(tbl, val)
|
||||||
for _, v in pairs(tbl) do
|
for _, v in pairs(tbl) do
|
||||||
if v == val then
|
if v == val then
|
||||||
|
|
|
@ -116,7 +116,7 @@ function creatura.get_boid_angle(self, boid, range) -- calculates boid angle bas
|
||||||
local boid_yaw = boid:get_yaw()
|
local boid_yaw = boid:get_yaw()
|
||||||
table.insert(positions, boid_pos)
|
table.insert(positions, boid_pos)
|
||||||
if boid ~= self.object then
|
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())
|
table.insert(angles, boid:get_yaw())
|
||||||
if not closest_pos
|
if not closest_pos
|
||||||
or vec_dist(pos, boid_pos) < vec_dist(pos, closest_pos) then
|
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)
|
local alignment = average_angle(angles)
|
||||||
center = vec_add(center, yaw2dir(alignment))
|
center = vec_add(center, yaw2dir(alignment))
|
||||||
local dir2center = vec_dir(pos, center)
|
local dir2center = vec_dir(pos, center)
|
||||||
local seperation = dir2yaw(vector.multiply(dir2center, -1))
|
local seperation = yaw + -(dir2yaw(dir2closest) - yaw)
|
||||||
local cohesion = dir2yaw(dir2center)
|
local cohesion = dir2yaw(dir2center)
|
||||||
local params = {alignment}
|
local params = {alignment}
|
||||||
if self.boid_heading then
|
if self.boid_heading then
|
||||||
table.insert(params, yaw + self.boid_heading)
|
table.insert(params, yaw + self.boid_heading)
|
||||||
end
|
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)
|
table.insert(params, seperation)
|
||||||
elseif dist_2d(pos, center) > (#boids * 0.33) * (self.boid_seperation or self.width * 3) then
|
elseif dist_2d(pos, center) > (#boids * 0.33) * (self.boid_seperation or self.width * 3) then
|
||||||
table.insert(params, cohesion)
|
table.insert(params, cohesion)
|
||||||
|
|
24
methods.lua
24
methods.lua
|
@ -171,7 +171,7 @@ creatura.register_movement_method("creatura:pathfind", function(self, pos2)
|
||||||
end
|
end
|
||||||
local yaw = self.object:get_yaw()
|
local yaw = self.object:get_yaw()
|
||||||
local tgt_yaw = dir2yaw(dir2waypoint)
|
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))
|
local yaw_diff = abs(diff(yaw, tgt_yaw))
|
||||||
-- Moving
|
-- Moving
|
||||||
self:set_gravity(-9.8)
|
self:set_gravity(-9.8)
|
||||||
|
@ -183,7 +183,9 @@ creatura.register_movement_method("creatura:pathfind", function(self, pos2)
|
||||||
turn_rate = turn_rate * 1.5
|
turn_rate = turn_rate * 1.5
|
||||||
end
|
end
|
||||||
self:turn_to(tgt_yaw, turn_rate)
|
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()
|
self:halt()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -216,7 +218,7 @@ creatura.register_movement_method("creatura:theta_pathfind", function(self, pos2
|
||||||
end
|
end
|
||||||
local yaw = self.object:get_yaw()
|
local yaw = self.object:get_yaw()
|
||||||
local tgt_yaw = dir2yaw(dir2waypoint)
|
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))
|
local yaw_diff = abs(diff(yaw, tgt_yaw))
|
||||||
-- Moving
|
-- Moving
|
||||||
self:set_gravity(-9.8)
|
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
|
turn_rate = turn_rate * 1.5
|
||||||
end
|
end
|
||||||
self:turn_to(tgt_yaw, turn_rate)
|
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()
|
self:halt()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -254,7 +258,7 @@ creatura.register_movement_method("creatura:neighbors", function(self, pos2)
|
||||||
end
|
end
|
||||||
local yaw = self.object:get_yaw()
|
local yaw = self.object:get_yaw()
|
||||||
local tgt_yaw = dir2yaw(dir2waypoint)
|
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))
|
local yaw_diff = abs(diff(yaw, tgt_yaw))
|
||||||
-- Moving
|
-- Moving
|
||||||
self:set_gravity(-9.8)
|
self:set_gravity(-9.8)
|
||||||
|
@ -266,7 +270,9 @@ creatura.register_movement_method("creatura:neighbors", function(self, pos2)
|
||||||
turn_rate = turn_rate * 1.5
|
turn_rate = turn_rate * 1.5
|
||||||
end
|
end
|
||||||
self:turn_to(tgt_yaw, turn_rate)
|
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()
|
self:halt()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -322,7 +328,7 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self,
|
||||||
end
|
end
|
||||||
local yaw = self.object:get_yaw()
|
local yaw = self.object:get_yaw()
|
||||||
local tgt_yaw = dir2yaw(dir2waypoint)
|
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))
|
local yaw_diff = abs(diff(yaw, tgt_yaw))
|
||||||
-- Moving
|
-- Moving
|
||||||
self:set_gravity(-9.8)
|
self:set_gravity(-9.8)
|
||||||
|
@ -334,7 +340,9 @@ creatura.register_movement_method("creatura:obstacle_avoidance", function(self,
|
||||||
turn_rate = turn_rate * 1.5
|
turn_rate = turn_rate * 1.5
|
||||||
end
|
end
|
||||||
self:turn_to(tgt_yaw, turn_rate)
|
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()
|
self:halt()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
10
mob_meta.lua
10
mob_meta.lua
|
@ -407,7 +407,6 @@ end
|
||||||
|
|
||||||
function mob:get_wander_pos_3d(min_range, max_range, dir, vert_bias)
|
function mob:get_wander_pos_3d(min_range, max_range, dir, vert_bias)
|
||||||
local pos = vec_center(self.object:get_pos())
|
local pos = vec_center(self.object:get_pos())
|
||||||
pos.y = floor(pos.y + 0.5)
|
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if get_node_def(node.name).walkable then -- Occurs if small mob is touching a fence
|
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))
|
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
|
for i = 1, outset do
|
||||||
local a_pos = vec_add(pos2, vec_multi(move_dir, i))
|
local a_pos = vec_add(pos2, vec_multi(move_dir, i))
|
||||||
local a_node = minetest.get_node(a_pos)
|
local a_node = minetest.get_node(a_pos)
|
||||||
local b_pos = {x = a_pos.x, y = a_pos.y - 1, z = a_pos.z}
|
if get_node_def(a_node.name).walkable then
|
||||||
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
|
|
||||||
a_pos = get_ground_level(a_pos, floor(self.stepheight or 1))
|
a_pos = get_ground_level(a_pos, floor(self.stepheight or 1))
|
||||||
end
|
end
|
||||||
if not get_node_def(a_node.name).walkable then
|
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)
|
local node = minetest.get_node(pos)
|
||||||
if not node then return false end
|
if not node then return false end
|
||||||
if minetest.get_item_group(node.name, "igniter") > 0
|
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
|
local fall_safe = false
|
||||||
if self.max_fall ~= 0 then
|
if self.max_fall ~= 0 then
|
||||||
for i = 1, self.max_fall or 3 do
|
for i = 1, self.max_fall or 3 do
|
||||||
|
@ -681,6 +678,7 @@ function mob:set_utility(func)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mob:get_utility()
|
function mob:get_utility()
|
||||||
|
if not self._utility_data then return end
|
||||||
return self._utility_data.utility
|
return self._utility_data.utility
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
45
spawning.lua
45
spawning.lua
|
@ -82,6 +82,15 @@ function creatura.register_mob_spawn(name, def)
|
||||||
creatura.registered_mob_spawns[name] = spawn
|
creatura.registered_mob_spawns[name] = spawn
|
||||||
end
|
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 --
|
-- Utility Functions --
|
||||||
|
|
||||||
|
@ -187,11 +196,11 @@ function execute_spawns(player)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local light_pos = spawn_pos
|
|
||||||
if not spawn.spawn_in_nodes then
|
if not spawn.spawn_in_nodes then
|
||||||
light_pos = vec_raise(spawn_pos, 1)
|
spawn_pos = vec_raise(spawn_pos, 1)
|
||||||
end
|
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
|
if light > spawn.max_light
|
||||||
or light < spawn.min_light then
|
or light < spawn.min_light then
|
||||||
|
@ -257,18 +266,27 @@ minetest.register_abm({
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local name = meta:get_string("mob")
|
local name = meta:get_string("mob")
|
||||||
local amount = meta:get_int("cluster")
|
local amount = meta:get_int("cluster")
|
||||||
|
local obj
|
||||||
if amount > 0 then
|
if amount > 0 then
|
||||||
for i = 1, amount do
|
for i = 1, amount do
|
||||||
minetest.add_entity(pos, name)
|
obj = minetest.add_entity(pos, name)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.add_entity(pos, name)
|
obj = minetest.add_entity(pos, name)
|
||||||
end
|
end
|
||||||
minetest.remove_node(pos)
|
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,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_lbm({
|
--[[minetest.register_lbm({
|
||||||
name = "creatura:spawning",
|
name = "creatura:spawning",
|
||||||
nodenames = {"creatura:spawn_node"},
|
nodenames = {"creatura:spawn_node"},
|
||||||
run_at_every_load = true,
|
run_at_every_load = true,
|
||||||
|
@ -276,13 +294,22 @@ minetest.register_lbm({
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local name = meta:get_string("mob")
|
local name = meta:get_string("mob")
|
||||||
local amount = meta:get_int("cluster")
|
local amount = meta:get_int("cluster")
|
||||||
|
local obj
|
||||||
if amount > 0 then
|
if amount > 0 then
|
||||||
for i = 1, amount do
|
for i = 1, amount do
|
||||||
minetest.add_entity(pos, name)
|
obj = minetest.add_entity(pos, name)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.add_entity(pos, name)
|
obj = minetest.add_entity(pos, name)
|
||||||
end
|
end
|
||||||
minetest.remove_node(pos)
|
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,
|
end,
|
||||||
})
|
})]]
|
Loading…
Add table
Reference in a new issue