commit
1eb151dc14
226
init.lua
226
init.lua
|
@ -12,6 +12,7 @@ mobkit.friction = 0.4 -- less is more
|
||||||
local abs = math.abs
|
local abs = math.abs
|
||||||
local pi = math.pi
|
local pi = math.pi
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
|
local ceil = math.ceil
|
||||||
local random = math.random
|
local random = math.random
|
||||||
local sqrt = math.sqrt
|
local sqrt = math.sqrt
|
||||||
local max = math.max
|
local max = math.max
|
||||||
|
@ -45,6 +46,11 @@ function mobkit.dot(v1,v2)
|
||||||
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
|
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mobkit.minmax(v,m)
|
||||||
|
return min(abs(v),m)*sign(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function mobkit.dir2neighbor(dir)
|
function mobkit.dir2neighbor(dir)
|
||||||
dir.y=0
|
dir.y=0
|
||||||
dir=vector.round(vector.normalize(dir))
|
dir=vector.round(vector.normalize(dir))
|
||||||
|
@ -103,6 +109,16 @@ function mobkit.get_stand_pos(thing) -- thing can be luaentity or objectref.
|
||||||
return mobkit.pos_shift(pos,{y=colbox[2]+0.01}), pos
|
return mobkit.pos_shift(pos,{y=colbox[2]+0.01}), pos
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mobkit.set_acceleration(thing,vec,limit)
|
||||||
|
limit = limit or 100
|
||||||
|
if type(thing) == 'table' then thing=thing.object end
|
||||||
|
vec.x=mobkit.minmax(vec.x,limit)
|
||||||
|
vec.y=mobkit.minmax(vec.y,limit)
|
||||||
|
vec.z=mobkit.minmax(vec.z,limit)
|
||||||
|
|
||||||
|
thing:set_acceleration(vec)
|
||||||
|
end
|
||||||
|
|
||||||
function mobkit.nodeatpos(pos)
|
function mobkit.nodeatpos(pos)
|
||||||
local node = minetest.get_node_or_nil(pos)
|
local node = minetest.get_node_or_nil(pos)
|
||||||
if node then return minetest.registered_nodes[node.name] end
|
if node then return minetest.registered_nodes[node.name] end
|
||||||
|
@ -379,17 +395,6 @@ function mobkit.heal(luaent,dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function mobkit.animate(self,anim)
|
|
||||||
-- if self.animation and self.animation[anim] then
|
|
||||||
-- local crange = self.object:get_animation().range
|
|
||||||
-- if not crange
|
|
||||||
-- or crange.x ~= self.animation[anim].range.x
|
|
||||||
-- or crange.y ~= self.animation[anim].range.y then
|
|
||||||
-- self.object:set_animation(self.animation[anim].range,self.animation[anim].speed,0,self.animation[anim].loop)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
function mobkit.animate(self,anim)
|
function mobkit.animate(self,anim)
|
||||||
if self.animation and self.animation[anim] then
|
if self.animation and self.animation[anim] then
|
||||||
if self._anim == anim then return end
|
if self._anim == anim then return end
|
||||||
|
@ -746,6 +751,88 @@ function mobkit.default_brain(self)
|
||||||
if mobkit.is_queue_empty_high(self) then mobkit.hq_roam(self,0) end
|
if mobkit.is_queue_empty_high(self) then mobkit.hq_roam(self,0) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mobkit.physics(self)
|
||||||
|
local vel=self.object:get_velocity()
|
||||||
|
-- dumb friction
|
||||||
|
if self.isonground and not self.isinliquid then
|
||||||
|
self.object:set_velocity({x= vel.x> 0.2 and vel.x*mobkit.friction or 0,
|
||||||
|
y=vel.y,
|
||||||
|
z=vel.z > 0.2 and vel.z*mobkit.friction or 0})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- bounciness
|
||||||
|
if self.springiness and self.springiness > 0 then
|
||||||
|
local vnew = vector.new(vel)
|
||||||
|
|
||||||
|
if not self.collided then -- ugly workaround for inconsistent collisions
|
||||||
|
for _,k in ipairs({'y','z','x'}) do
|
||||||
|
if vel[k]==0 and abs(self.lastvelocity[k])> 0.1 then
|
||||||
|
vnew[k]=-self.lastvelocity[k]*self.springiness
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not vector.equals(vel,vnew) then
|
||||||
|
self.collided = true
|
||||||
|
else
|
||||||
|
if self.collided then
|
||||||
|
vnew = vector.new(self.lastvelocity)
|
||||||
|
end
|
||||||
|
self.collided = false
|
||||||
|
end
|
||||||
|
|
||||||
|
self.object:set_velocity(vnew)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- buoyancy
|
||||||
|
local spos = mobkit.get_stand_pos(self)
|
||||||
|
spos.y = spos.y+0.01
|
||||||
|
-- get surface height
|
||||||
|
local surface = nil
|
||||||
|
local snodepos = mobkit.get_node_pos(spos)
|
||||||
|
local surfnode = mobkit.nodeatpos(spos)
|
||||||
|
while surfnode and surfnode.drawtype == 'liquid' do
|
||||||
|
surface = snodepos.y+0.5
|
||||||
|
if surface > spos.y+self.height then break end
|
||||||
|
snodepos.y = snodepos.y+1
|
||||||
|
surfnode = mobkit.nodeatpos(snodepos)
|
||||||
|
end
|
||||||
|
if surface then -- standing in liquid
|
||||||
|
self.isinliquid = true
|
||||||
|
local submergence = min(surface-spos.y,self.height)
|
||||||
|
local balance = self.buoyancy*self.height
|
||||||
|
local buoyacc = mobkit.gravity*((balance - submergence)^2/balance^2*sign(balance - submergence))
|
||||||
|
mobkit.set_acceleration(self.object,
|
||||||
|
{x=-vel.x*self.water_drag,y=buoyacc-vel.y*abs(vel.y)*0.7,z=-vel.z*self.water_drag})
|
||||||
|
else
|
||||||
|
self.isinliquid = false
|
||||||
|
self.object:set_acceleration({x=0,y=mobkit.gravity,z=0})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function mobkit.vitals(self)
|
||||||
|
-- vitals: fall damage
|
||||||
|
vel = self.object:get_velocity()
|
||||||
|
local velocity_delta = abs(self.lastvelocity.y - vel.y)
|
||||||
|
if velocity_delta > mobkit.safe_velocity then
|
||||||
|
self.hp = self.hp - floor(self.max_hp * min(1, velocity_delta/mobkit.terminal_velocity))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- vitals: oxygen
|
||||||
|
if self.lung_capacity then
|
||||||
|
local colbox = self.object:get_properties().collisionbox
|
||||||
|
local headnode = mobkit.nodeatpos(mobkit.pos_shift(self.object:get_pos(),{y=colbox[5]})) -- node at hitbox top
|
||||||
|
if headnode and headnode.drawtype == 'liquid' then
|
||||||
|
self.oxygen = self.oxygen - self.dtime
|
||||||
|
else
|
||||||
|
self.oxygen = self.lung_capacity
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.oxygen <= 0 then self.hp=0 end -- drown
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function mobkit.statfunc(self)
|
function mobkit.statfunc(self)
|
||||||
local tmptab={}
|
local tmptab={}
|
||||||
tmptab.memory = self.memory
|
tmptab.memory = self.memory
|
||||||
|
@ -755,6 +842,10 @@ function mobkit.statfunc(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mobkit.actfunc(self, staticdata, dtime_s)
|
function mobkit.actfunc(self, staticdata, dtime_s)
|
||||||
|
|
||||||
|
self.logic = self.logic or self.brainfunc
|
||||||
|
self.physics = self.physics or mobkit.physics
|
||||||
|
|
||||||
self.lqueue = {}
|
self.lqueue = {}
|
||||||
self.hqueue = {}
|
self.hqueue = {}
|
||||||
self.nearby_objects = {}
|
self.nearby_objects = {}
|
||||||
|
@ -805,7 +896,7 @@ function mobkit.actfunc(self, staticdata, dtime_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mobkit.stepfunc(self,dtime) -- not intended to be modified
|
function mobkit.stepfunc(self,dtime) -- not intended to be modified
|
||||||
self.dtime = dtime
|
self.dtime = max(dtime,0.05)
|
||||||
self.height = mobkit.get_box_height(self)
|
self.height = mobkit.get_box_height(self)
|
||||||
-- physics comes first
|
-- physics comes first
|
||||||
-- self.object:set_acceleration({x=0,y=mobkit.gravity,z=0})
|
-- self.object:set_acceleration({x=0,y=mobkit.gravity,z=0})
|
||||||
|
@ -818,108 +909,16 @@ function mobkit.stepfunc(self,dtime) -- not intended to be modified
|
||||||
self.isonground = false
|
self.isonground = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- dumb friction
|
self:physics()
|
||||||
if self.isonground and not self.isinliquid then
|
|
||||||
self.object:set_velocity({x= vel.x> 0.2 and vel.x*mobkit.friction or 0,
|
|
||||||
y=vel.y,
|
|
||||||
z=vel.z > 0.2 and vel.z*mobkit.friction or 0})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- bounciness
|
|
||||||
if self.springiness and self.springiness > 0 then
|
|
||||||
local vnew = vector.new(vel)
|
|
||||||
|
|
||||||
if not self.collided then -- ugly workaround for inconsistent collisions
|
|
||||||
for _,k in ipairs({'y','z','x'}) do
|
|
||||||
if vel[k]==0 and abs(self.lastvelocity[k])> 0.1 then
|
|
||||||
vnew[k]=-self.lastvelocity[k]*self.springiness
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not vector.equals(vel,vnew) then
|
|
||||||
self.collided = true
|
|
||||||
else
|
|
||||||
if self.collided then
|
|
||||||
vnew = vector.new(self.lastvelocity)
|
|
||||||
end
|
|
||||||
self.collided = false
|
|
||||||
end
|
|
||||||
|
|
||||||
self.object:set_velocity(vnew)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- buoyancy
|
|
||||||
local spos = mobkit.get_stand_pos(self)
|
|
||||||
spos.y = spos.y+0.01
|
|
||||||
-- get surface height
|
|
||||||
-- local surface = mobkit.get_node_pos(spos).y+0.5
|
|
||||||
local surface = nil
|
|
||||||
local snodepos = mobkit.get_node_pos(spos)
|
|
||||||
local surfnode = mobkit.nodeatpos(spos)
|
|
||||||
while surfnode and surfnode.drawtype == 'liquid' do
|
|
||||||
surface = snodepos.y+0.5
|
|
||||||
if surface > spos.y+self.height then break end
|
|
||||||
snodepos.y = snodepos.y+1
|
|
||||||
surfnode = mobkit.nodeatpos(snodepos)
|
|
||||||
end
|
|
||||||
if surface then -- standing in liquid
|
|
||||||
self.isinliquid = true
|
|
||||||
local submergence = min(surface-spos.y,self.height)
|
|
||||||
local balance = self.buoyancy*self.height
|
|
||||||
local buoyacc = mobkit.gravity*((balance - submergence)^2/balance^2*sign(balance - submergence))
|
|
||||||
self.object:set_acceleration({x=-vel.x*self.water_drag,y=buoyacc-vel.y*abs(vel.y)*0.7,z=-vel.z*self.water_drag})
|
|
||||||
else
|
|
||||||
self.isinliquid = false
|
|
||||||
self.object:set_acceleration({x=0,y=mobkit.gravity,z=0})
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- local footnode = mobkit.nodeatpos(spos)
|
|
||||||
-- local headnode
|
|
||||||
-- if footnode and footnode.drawtype == 'liquid' then
|
|
||||||
|
|
||||||
-- vel = self.object:get_velocity()
|
|
||||||
-- headnode = mobkit.nodeatpos(mobkit.pos_shift(spos,{y=self.height or 0})) -- TODO: height may be nil
|
|
||||||
-- local submergence = headnode.drawtype=='liquid'
|
|
||||||
-- and self.buoyancy-1
|
|
||||||
-- or (self.buoyancy*self.height-(1-(spos.y+0.5)%1))^2/(self.buoyancy*self.height)^2*sign(self.buoyancy*self.height-(1-(spos.y+0.5)%1))
|
|
||||||
|
|
||||||
-- local buoyacc = submergence * mobkit.gravity
|
if self.logic then
|
||||||
-- self.object:set_acceleration({x=-vel.x,y=buoyacc-vel.y*abs(vel.y)*0.5,z=-vel.z})
|
|
||||||
|
|
||||||
-- end
|
|
||||||
|
|
||||||
if self.brainfunc then
|
|
||||||
-- vitals: fall damage
|
|
||||||
vel = self.object:get_velocity()
|
|
||||||
local velocity_delta = abs(self.lastvelocity.y - vel.y)
|
|
||||||
if velocity_delta > mobkit.safe_velocity then
|
|
||||||
self.hp = self.hp - floor((self.max_hp-100) * min(1, velocity_delta/mobkit.terminal_velocity))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- vitals: oxygen
|
|
||||||
if self.lung_capacity then
|
|
||||||
local colbox = self.object:get_properties().collisionbox
|
|
||||||
local headnode = mobkit.nodeatpos(mobkit.pos_shift(self.object:get_pos(),{y=colbox[5]})) -- node at hitbox top
|
|
||||||
if headnode and headnode.drawtype == 'liquid' then
|
|
||||||
self.oxygen = self.oxygen - self.dtime
|
|
||||||
else
|
|
||||||
self.oxygen = self.lung_capacity
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.oxygen <= 0 then self.hp=0 end -- drown
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if self.view_range then self:sensefunc() end
|
if self.view_range then self:sensefunc() end
|
||||||
self:brainfunc()
|
self:logic()
|
||||||
execute_queues(self)
|
execute_queues(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.lastvelocity = self.object:get_velocity()
|
self.lastvelocity = self.object:get_velocity()
|
||||||
self.time_total=self.time_total+self.dtime
|
self.time_total=self.time_total+dtime
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
@ -1007,7 +1006,7 @@ function mobkit.lq_dumbjump(self,height,anim)
|
||||||
dir = vector.multiply(dir,3)
|
dir = vector.multiply(dir,3)
|
||||||
end
|
end
|
||||||
dir.y = vel.y
|
dir.y = vel.y
|
||||||
self.object:set_velocity(dir,yaw)
|
self.object:set_velocity(dir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mobkit.queue_low(self,func)
|
mobkit.queue_low(self,func)
|
||||||
|
@ -1051,6 +1050,7 @@ end
|
||||||
|
|
||||||
function mobkit.lq_jumpattack(self,height,target)
|
function mobkit.lq_jumpattack(self,height,target)
|
||||||
local phase=1
|
local phase=1
|
||||||
|
local timer=0.5
|
||||||
local tgtbox = target:get_properties().collisionbox
|
local tgtbox = target:get_properties().collisionbox
|
||||||
local func=function(self)
|
local func=function(self)
|
||||||
if not mobkit.is_alive(target) then return true end
|
if not mobkit.is_alive(target) then return true end
|
||||||
|
@ -1062,6 +1062,7 @@ function mobkit.lq_jumpattack(self,height,target)
|
||||||
mobkit.make_sound(self,'charge')
|
mobkit.make_sound(self,'charge')
|
||||||
phase=2
|
phase=2
|
||||||
else
|
else
|
||||||
|
mobkit.lq_idle(self,0.3)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
elseif phase==2 then
|
elseif phase==2 then
|
||||||
|
@ -1114,7 +1115,7 @@ end
|
||||||
-- HIGH LEVEL QUEUE FUNCTIONS
|
-- HIGH LEVEL QUEUE FUNCTIONS
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
function mobkit.dumbstep(self,height,tpos,speed_factor)
|
function mobkit.dumbstep(self,height,tpos,speed_factor,idle_duration)
|
||||||
if height <= 0.001 then
|
if height <= 0.001 then
|
||||||
mobkit.lq_turn2pos(self,tpos)
|
mobkit.lq_turn2pos(self,tpos)
|
||||||
mobkit.lq_dumbwalk(self,tpos,speed_factor)
|
mobkit.lq_dumbwalk(self,tpos,speed_factor)
|
||||||
|
@ -1122,7 +1123,8 @@ function mobkit.dumbstep(self,height,tpos,speed_factor)
|
||||||
mobkit.lq_turn2pos(self,tpos)
|
mobkit.lq_turn2pos(self,tpos)
|
||||||
mobkit.lq_dumbjump(self,height)
|
mobkit.lq_dumbjump(self,height)
|
||||||
end
|
end
|
||||||
mobkit.lq_idle(self,random(1,6))
|
idle_duration = idle_duration or 6
|
||||||
|
mobkit.lq_idle(self,random(ceil(idle_duration*0.5),idle_duration))
|
||||||
end
|
end
|
||||||
|
|
||||||
function mobkit.hq_roam(self,prty)
|
function mobkit.hq_roam(self,prty)
|
||||||
|
@ -1289,7 +1291,7 @@ function mobkit.hq_die(self)
|
||||||
local func = function(self)
|
local func = function(self)
|
||||||
if start then
|
if start then
|
||||||
mobkit.lq_fallover(self)
|
mobkit.lq_fallover(self)
|
||||||
self.brainfunc = function(self) end -- brain dead as well
|
self.logic = function(self) end -- brain dead as well
|
||||||
start=false
|
start=false
|
||||||
end
|
end
|
||||||
timer = timer-self.dtime
|
timer = timer-self.dtime
|
||||||
|
|
Loading…
Reference in New Issue