Update
parent
dc4ef98f27
commit
cfd42b4868
|
@ -77,12 +77,12 @@ function mobs.default_prototype:on_step(dtime)
|
|||
|
||||
-- Disable collision when far enough
|
||||
if self.collide_with_objects then
|
||||
if nearest.distance > 8 then
|
||||
if nearest.distance > 6 then
|
||||
self.collide_with_objects = false
|
||||
self.object:set_properties({collide_with_objects = self.collide_with_objects})
|
||||
end
|
||||
else
|
||||
if nearest.distance < 3 then
|
||||
if nearest.distance < 1.5 then
|
||||
self.collide_with_objects = true
|
||||
self.object:set_properties({collide_with_objects = self.collide_with_objects})
|
||||
end
|
||||
|
@ -146,14 +146,7 @@ function mobs.default_prototype:hunt()
|
|||
end
|
||||
|
||||
if direction then
|
||||
local sx = self.collisionbox[4] - self.collisionbox[1]
|
||||
local sy = self.collisionbox[5] - self.collisionbox[2]
|
||||
local sz = self.collisionbox[6] - self.collisionbox[3]
|
||||
local r = math.sqrt(sx*sx + sy*sy + sz*sz)/2 + 1
|
||||
local x = pos.x + direction.x * r
|
||||
local y = pos.y + direction.y * r
|
||||
local z = pos.z + direction.z * r
|
||||
self.destination = {x=x, y=y, z=z}
|
||||
self.destination = vector.add(pos, vector.multiply(direction, 1.25))
|
||||
else
|
||||
local r = math.max(0, self.attack_range - 2)
|
||||
local dir = vector.direction(nearest.position, self.object:getpos())
|
||||
|
@ -339,11 +332,16 @@ function mobs.move_method:ground(dtime, destination)
|
|||
self.object:setvelocity(v2)
|
||||
|
||||
-- Check for jump
|
||||
local jump = false
|
||||
local jump = nil
|
||||
if self.smart_path then
|
||||
local p = self.object:getpos()
|
||||
if destination.y > p.y + 0.5 then
|
||||
jump = true
|
||||
if destination.y > p.y + 1 then
|
||||
for y=p.y,p.y+self.jump_height do
|
||||
jump = defense.pathfinder:get_direction(self.name, {x=p.x, y=y, z=p.z})
|
||||
if jump and (jump.x ~= 0 or jump.z ~= 0) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if dist > 1 then
|
||||
|
@ -361,7 +359,7 @@ function mobs.move_method:ground(dtime, destination)
|
|||
for _,f in ipairs(fronts) do
|
||||
local node = minetest.get_node_or_nil(vector.add(p, f))
|
||||
if not node or minetest.registered_nodes[node.name].walkable then
|
||||
jump = true
|
||||
jump = vector.direction(self.object:getpos(), destination)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -369,7 +367,7 @@ function mobs.move_method:ground(dtime, destination)
|
|||
end
|
||||
|
||||
if jump then
|
||||
self:jump(vector.direction(self.object:getpos(), destination))
|
||||
self:jump(jump)
|
||||
elseif self:is_standing() then
|
||||
if speed > self.move_speed * 0.06 then
|
||||
local yaw = self.object:getyaw()
|
||||
|
|
|
@ -19,37 +19,12 @@ defense.mobs.register_mob("defense:paniki", {
|
|||
attack_range = 1.1,
|
||||
attack_interval = 1.2,
|
||||
|
||||
rank = 0,
|
||||
leader = nil,
|
||||
last_hp = 3,
|
||||
flee_timer = 0,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
defense.mobs.default_prototype.on_activate(self, staticdata)
|
||||
self.rank = math.random()
|
||||
local pos = self.object:getpos()
|
||||
local radius = 2
|
||||
minetest.after(1, function()
|
||||
local greatest_paniki = self
|
||||
local greatest_rank = self.rank
|
||||
for _,o in pairs(minetest.get_objects_inside_radius(pos, radius)) do
|
||||
if self.object ~= o then
|
||||
local e = o:get_luaentity()
|
||||
if e and e.name == self.name then
|
||||
if greatest_rank < e.rank then
|
||||
greatest_paniki = e
|
||||
greatest_rank = e.rank
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.leader = greatest_paniki
|
||||
end)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
defense.mobs.default_prototype.on_step(self, dtime)
|
||||
if self.flee_timer > 0 or (self.leader and self.leader.flee_timer > 0) then
|
||||
if self.flee_timer > 0 then
|
||||
local nearest = self:find_nearest_player()
|
||||
local pos = self.object:getpos()
|
||||
local delta = vector.subtract(pos, nearest.player:getpos())
|
||||
|
|
|
@ -46,13 +46,13 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
|
||||
on_step = function(self, dtime)
|
||||
defense.mobs.default_prototype.on_step(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
if self.charging then
|
||||
if self.charge_power > 0.5 then
|
||||
self:hunt()
|
||||
end
|
||||
|
||||
-- Break obstacles
|
||||
local pos = self.object:getpos()
|
||||
pos.y = pos.y + 1.5
|
||||
local v = self.object:getvelocity()
|
||||
v.y = 0
|
||||
|
@ -69,13 +69,13 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
else
|
||||
local nearest = self:find_nearest_player()
|
||||
if nearest then
|
||||
if nearest.distance > 4 and math.random() < 0.1 then
|
||||
if nearest.distance > 4 and math.abs(nearest.position.y - pos.y) < 4 and math.random() < 0.1 then
|
||||
self:set_charging_state(true)
|
||||
self.destination = nil
|
||||
elseif nearest.distance < 4 then
|
||||
self:hunt()
|
||||
else
|
||||
local dir = vector.direction(nearest.position, self.object:getpos())
|
||||
local dir = vector.direction(nearest.position, pos)
|
||||
self.destination = vector.add(nearest.position, vector.multiply(dir, 12))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -61,7 +61,7 @@ defense.mobs.register_mob("defense:unggoy", {
|
|||
return true
|
||||
else
|
||||
local vel = self.object:getvelocity()
|
||||
if math.abs(vel.y) > 0.05 then
|
||||
if math.abs(vel.y) > 0.2 then
|
||||
return false
|
||||
end
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ function music:update()
|
|||
last_intensity = intensity
|
||||
intensity = intensity + math.max(0, intensity - last_intensity) * 3
|
||||
|
||||
local il = {0.1, 0.45, 0.7, 0.85}
|
||||
local il = {0.05, 0.35, 0.6, 0.8}
|
||||
local last_level = current_level
|
||||
if intensity <= il[1] then
|
||||
if current_level > 0 then
|
||||
|
@ -68,7 +68,7 @@ function music:update()
|
|||
loop = true,
|
||||
})
|
||||
end
|
||||
if current_level > 1 or last_level > 1 then
|
||||
if last_level > 0 then
|
||||
minetest.sound_play("defense_music_transit", {
|
||||
gain = 0.2 + last_level * 0.1
|
||||
})
|
||||
|
|
|
@ -37,6 +37,15 @@ end
|
|||
|
||||
-- Returns a vector
|
||||
function pathfinder:get_direction(class, position)
|
||||
local directions = {
|
||||
{x=0, y=-1, z=0},
|
||||
{x=0, y=1, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=1, y=0, z=0},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=0, z=1},
|
||||
}
|
||||
|
||||
local total = vector.new(0, 0, 0)
|
||||
local count = 0
|
||||
local time = minetest.get_gametime()
|
||||
|
@ -54,21 +63,14 @@ function pathfinder:get_direction(class, position)
|
|||
local field = self:get_field(class, p)
|
||||
if field then
|
||||
local last_time = player_last_update[field.player] or field.time
|
||||
if last_time + field.distance > time then
|
||||
local direction = ({{x=-1, y=0, z=0},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
{x=0, y=1, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=0, y=0, z=1}})
|
||||
[field.direction]
|
||||
if last_time + field.distance * 4 > time then
|
||||
local direction = directions[field.direction]
|
||||
total = vector.add(total, direction)
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if count > 0 then
|
||||
if total.x ~= 0 or total.y ~= 0 or total.z ~= 0 then
|
||||
return vector.normalize(total)
|
||||
else
|
||||
return nil
|
||||
|
@ -78,9 +80,9 @@ end
|
|||
-- Returns a table {time, distance}
|
||||
function pathfinder:get_field(class, position)
|
||||
local collisionbox = self.classes[class].collisionbox
|
||||
local x = math.floor(position.x + collisionbox[1])
|
||||
local y = math.floor(position.y + collisionbox[2])
|
||||
local z = math.floor(position.z + collisionbox[3])
|
||||
local x = math.floor(position.x + collisionbox[1] + 0.01)
|
||||
local y = math.floor(position.y + collisionbox[2] + 0.01)
|
||||
local z = math.floor(position.z + collisionbox[3] + 0.01)
|
||||
|
||||
local chunk_key = math.floor(x/chunk_size) ..
|
||||
":" .. math.floor(y/chunk_size) ..
|
||||
|
@ -99,9 +101,9 @@ end
|
|||
|
||||
function pathfinder:set_field(class, position, player, distance, direction, time)
|
||||
local collisionbox = self.classes[class].collisionbox
|
||||
local x = math.floor(position.x + collisionbox[1])
|
||||
local y = math.floor(position.y + collisionbox[2])
|
||||
local z = math.floor(position.z + collisionbox[3])
|
||||
local x = math.floor(position.x + collisionbox[1] + 0.01)
|
||||
local y = math.floor(position.y + collisionbox[2] + 0.01)
|
||||
local z = math.floor(position.z + collisionbox[3] + 0.01)
|
||||
|
||||
local chunk_key = math.floor(x/chunk_size) ..
|
||||
":" .. math.floor(y/chunk_size) ..
|
||||
|
@ -119,6 +121,27 @@ function pathfinder:set_field(class, position, player, distance, direction, time
|
|||
chunk[index] = {time=time, direction=direction, distance=distance, player=player}
|
||||
end
|
||||
|
||||
function pathfinder:delete_field(class, position)
|
||||
local collisionbox = self.classes[class].collisionbox
|
||||
local x = math.floor(position.x + collisionbox[1] + 0.01)
|
||||
local y = math.floor(position.y + collisionbox[2] + 0.01)
|
||||
local z = math.floor(position.z + collisionbox[3] + 0.01)
|
||||
|
||||
local chunk_key = math.floor(x/chunk_size) ..
|
||||
":" .. math.floor(y/chunk_size) ..
|
||||
":" .. math.floor(z/chunk_size)
|
||||
local chunk = fields[class][chunk_key]
|
||||
if not chunk then
|
||||
return
|
||||
end
|
||||
|
||||
local cx = x % chunk_size
|
||||
local cy = y % chunk_size
|
||||
local cz = z % chunk_size
|
||||
local index = (cy * chunk_size + cz) * chunk_size + cx
|
||||
chunk[index] = nil
|
||||
end
|
||||
|
||||
function pathfinder:update(dtime)
|
||||
if not defense:is_dark() then
|
||||
-- reset flow fields in the morning
|
||||
|
@ -135,18 +158,19 @@ function pathfinder:update(dtime)
|
|||
morning_reset = false
|
||||
|
||||
local neighborhood = {
|
||||
{x=1, y=0, z=0},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=1, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
{x=0, y=0, z=1},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
}
|
||||
-- Update the field
|
||||
for c,class in pairs(self.classes) do
|
||||
local vq = visit_queues[c]
|
||||
local size = Queue.size(vq)
|
||||
for i=1,math.min(size,20) do
|
||||
local max_iter = 100 - math.floor(defense.director.intensity * 90)
|
||||
for i=1,math.min(size,max_iter) do
|
||||
local current = Queue.pop(vq)
|
||||
for di,n in ipairs(neighborhood) do
|
||||
local npos = vector.add(current.position, n)
|
||||
|
@ -162,15 +186,19 @@ function pathfinder:update(dtime)
|
|||
and neighbor_field.direction ~= di
|
||||
or neighbor_field.time == current.time
|
||||
and neighbor_field.distance > next_distance then
|
||||
self:set_field(c, npos, current.player, next_distance, di, current.time)
|
||||
if next_distance < self.path_max_range and size < 100 then
|
||||
Queue.push(vq, {
|
||||
position = npos,
|
||||
player = current.player,
|
||||
distance = next_distance,
|
||||
direction = di,
|
||||
time = current.time,
|
||||
})
|
||||
if next_distance < self.path_max_range then
|
||||
if size < 800 then
|
||||
self:set_field(c, npos, current.player, next_distance, di, current.time)
|
||||
Queue.push(vq, {
|
||||
position = npos,
|
||||
player = current.player,
|
||||
distance = next_distance,
|
||||
direction = di,
|
||||
time = current.time,
|
||||
})
|
||||
end
|
||||
else
|
||||
self:delete_field(c, npos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -227,11 +255,6 @@ function pathfinder.cost_method.ground(class, pos, parent)
|
|||
end
|
||||
end
|
||||
|
||||
-- Check if this is a fall
|
||||
if parent.y < pos.y then
|
||||
return 2
|
||||
end
|
||||
|
||||
-- Check if on top of solid
|
||||
local ground_distance = 9999
|
||||
for z=pos.z,pos.z+class.size.z-1 do
|
||||
|
@ -262,11 +285,16 @@ function pathfinder.cost_method.ground(class, pos, parent)
|
|||
local node = minetest.get_node_or_nil(l)
|
||||
if not node then return nil end
|
||||
if minetest.registered_nodes[node.name].walkable then
|
||||
return 1 + (ground_distance - 1)
|
||||
return ground_distance
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if this is a fall
|
||||
if parent.y < pos.y then
|
||||
return 2
|
||||
end
|
||||
|
||||
return pathfinder.path_max_range + 1
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue