ikea/mods/ikea_staff/behaviors.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