192 lines
4.9 KiB
Lua
192 lines
4.9 KiB
Lua
local PATH = minetest.get_modpath(minetest.get_current_modname()) .. "/"
|
|
local behaviors = dofile(PATH .. "behaviors2override.lua")
|
|
|
|
local abs = math.abs
|
|
local floor = math.floor
|
|
local ceil = math.ceil
|
|
local random = math.random
|
|
local sqrt = math.sqrt
|
|
local max = math.max
|
|
local min = math.min
|
|
local tan = math.tan
|
|
local pow = math.pow
|
|
|
|
local dbg = minetest.chat_send_all
|
|
|
|
local pi = math.pi
|
|
local abr = tonumber(minetest.get_mapgen_setting("active_block_range")) or 3
|
|
|
|
local neighbors = {
|
|
{ x = 1, z = 0 },
|
|
{ x = 1, z = 1 },
|
|
{ x = 0, z = 1 },
|
|
{ x = -1, z = 1 },
|
|
{ x = -1, z = 0 },
|
|
{ x = -1, z = -1 },
|
|
{ x = 0, z = -1 },
|
|
{ x = 1, z = -1 },
|
|
}
|
|
|
|
-- Movement --
|
|
function behaviors.lq_yeet(self, tpos)
|
|
local timer = (self.animation.attack.range.y - self.animation.attack.range.x)
|
|
/ self.animation.attack.speed
|
|
local stage = 1
|
|
local func = function(self)
|
|
if stage == 1 then
|
|
local node = minetest.get_node_or_nil(tpos)
|
|
if node and (minetest.get_item_group(node.name, "falling_node") >= 1) then
|
|
mobkit.animate(self, "yeet")
|
|
stage = 3
|
|
else
|
|
return true
|
|
end
|
|
elseif stage == 2 then
|
|
if timer < 0.9 then -- correspond to the animation
|
|
stage = 3
|
|
end
|
|
elseif stage == 3 then
|
|
local success, obj = minetest.spawn_falling_node(tpos)
|
|
if success then
|
|
local dir = vector.subtract(mobkit.get_stand_pos(self), tpos)
|
|
dir.y = 1
|
|
minetest.after(0, function()
|
|
obj:set_velocity(vector.multiply(dir, 5))
|
|
end)
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
timer = timer - self.dtime
|
|
if timer < 0 then
|
|
return true
|
|
end
|
|
end
|
|
mobkit.queue_low(self, func)
|
|
end
|
|
|
|
function behaviors.lq_dumbwalk(self, dest, speed_factor)
|
|
local timer = 3 -- failsafe
|
|
speed_factor = speed_factor or 1
|
|
local func = function(self)
|
|
mobkit.animate(self, "walk")
|
|
timer = timer - self.dtime
|
|
if timer < 0 then
|
|
return true
|
|
end
|
|
|
|
local pos = mobkit.get_stand_pos(self)
|
|
local y = self.object:get_velocity().y
|
|
|
|
if mobkit.is_there_yet2d(pos, minetest.yaw_to_dir(self.object:get_yaw()), dest) then
|
|
if not self.isonground or abs(dest.y - pos.y) > 0.1 then -- prevent uncontrolled fall when velocity too high
|
|
self.object:set_velocity({ x = 0, y = y, z = 0 })
|
|
end
|
|
return true
|
|
end
|
|
|
|
if self.isonground then
|
|
local dir = vector.direction(
|
|
{ x = pos.x, y = 0, z = pos.z },
|
|
{ x = dest.x, y = 0, z = dest.z }
|
|
)
|
|
dir = vector.multiply(dir, self.max_speed * speed_factor)
|
|
mobkit.turn2yaw(self, minetest.dir_to_yaw(dir))
|
|
dir.y = y
|
|
self.object:set_velocity(dir)
|
|
end
|
|
|
|
if self.moveresult.collides then
|
|
for i, v in ipairs(self.moveresult.collisions) do
|
|
if v.type == "node" and v.axis ~= "y" then
|
|
behaviors.lq_turn2pos(self, v.node_pos)
|
|
behaviors.lq_yeet(self, v.node_pos)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
mobkit.queue_low(self, func)
|
|
end
|
|
|
|
function behaviors.goto_next_waypoint(self, tpos)
|
|
local height, pos2 = behaviors.get_next_waypoint(self, tpos)
|
|
|
|
if not height then
|
|
local pos = mobkit.get_stand_pos(self)
|
|
local ypos = vector.add(vector.direction(pos, tpos), pos)
|
|
behaviors.lq_turn2pos(self, tpos)
|
|
behaviors.lq_yeet(self, ypos)
|
|
return false
|
|
end
|
|
|
|
if height <= 0.01 then
|
|
local yaw = self.object:get_yaw()
|
|
local tyaw = minetest.dir_to_yaw(vector.direction(self.object:get_pos(), pos2))
|
|
if abs(tyaw - yaw) > 1 then
|
|
behaviors.lq_turn2pos(self, pos2)
|
|
end
|
|
behaviors.lq_dumbwalk(self, pos2)
|
|
else
|
|
behaviors.lq_turn2pos(self, pos2)
|
|
behaviors.lq_dumbjump(self, height)
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Death --
|
|
function behaviors.lq_fallover(self)
|
|
local timer = (self.animation.fallover.range.y - self.animation.fallover.range.x)
|
|
/ self.animation.fallover.speed
|
|
local init = true
|
|
local func = function(self)
|
|
if init then
|
|
local yaw = math.rad(90 * math.floor((math.deg(self.object:get_yaw()) / 90) + 0.5))
|
|
local pos = mobkit.get_stand_pos(self)
|
|
|
|
mobkit.turn2yaw(self, yaw, 10)
|
|
mobkit.animate(self, "fallover")
|
|
|
|
self.object:set_pos({
|
|
x = math.floor(pos.x + 0.5),
|
|
y = pos.y,
|
|
z = math.floor(pos.z + 0.5),
|
|
})
|
|
self.object:set_velocity({ x = 0, y = 0, z = 0 })
|
|
end
|
|
timer = timer - self.dtime
|
|
if timer >= 0 then
|
|
return true
|
|
end
|
|
end
|
|
mobkit.queue_low(self, func)
|
|
end
|
|
|
|
function behaviors.hq_die(self)
|
|
local timer = (self.animation.fallover.range.y - self.animation.fallover.range.x)
|
|
/ self.animation.fallover.speed
|
|
local start = true
|
|
local func = function(self)
|
|
if start then
|
|
behaviors.lq_fallover(self)
|
|
self.logic = function(self) end -- brain dead as well
|
|
start = false
|
|
end
|
|
timer = timer - self.dtime
|
|
if timer < 0 then
|
|
local pos = mobkit.get_stand_pos(self)
|
|
local height = mobkit.get_terrain_height(pos)
|
|
local npos = vector.offset(self.object:get_pos(), 0, height, 0)
|
|
local yaw = self.object:get_yaw()
|
|
minetest.set_node(npos, {
|
|
name = "ikea_staff:corpse",
|
|
param2 = minetest.dir_to_facedir(minetest.yaw_to_dir(yaw)),
|
|
})
|
|
self.object:remove()
|
|
end
|
|
end
|
|
mobkit.queue_high(self, func, 100)
|
|
end
|
|
|
|
return behaviors
|