mobf_core/mobf/movement_generic.lua
2012-09-19 23:30:14 +02:00

133 lines
4.2 KiB
Lua

-------------------------------------------------------------------------------
-- Mob Framework Mod by Sapier
--
-- You may copy, use, modify or do nearly anything except removing this
-- copyright notice.
-- And of course you are NOT allow to pretend you have written it.
--
--! @file movement_generic.lua
--! @brief generic movement related functions
--! @copyright Sapier
--! @author Sapier
--! @date 2012-08-09
--
--! @defgroup generic_movement Generic movement functions
--! @brief Movement related functions used by different movement generators
--! @ingroup framework_int
--! @{
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
movement_generic = {}
--!@}
-------------------------------------------------------------------------------
-- name: get_accel_to(new_pos,entity)
--
--! @brief calculate a random speed directed to new_pos
--
--! @param new_pos position to go to
--! @param entity mob to move
--! @return { x,y,z } random speed directed to new_pos
-------------------------------------------------------------------------------
--
function movement_generic.get_accel_to(new_pos,entity)
if new_pos == nil or entity == nil then
minetest.log(LOGLEVEL_CRITICAL,"MOBF: movement_generic.get_accel_to : Invalid parameters")
end
local old_pos = entity.object:getpos()
local node = minetest.env:get_node(old_pos)
local maxaccel = entity.data.movement.max_accel
local minaccel = entity.data.movement.min_accel
local yaccel = environment.get_default_gravity(old_pos,
entity.environment.media,
entity.data.movement.canfly)
-- calc y speed for flying mobs
local x_diff = new_pos.x - old_pos.x
local z_diff = new_pos.z - old_pos.z
local rand_x = (math.random() * (maxaccel - minaccel)) + minaccel
local rand_z = (math.random() * (maxaccel - minaccel)) + minaccel
if x_diff < 0 then
rand_x = rand_x * -1
end
if z_diff < 0 then
rand_z = rand_z * -1
end
return { x=rand_x,y=yaccel,z=rand_z }
end
-------------------------------------------------------------------------------
-- name: calc_new_pos(pos,acceleration,prediction_time)
--
--! @brief calc the position a mob would be after a specified time
-- this doesn't handle velocity changes due to colisions
--
--! @param pos position
--! @param acceleration acceleration to predict pos
--! @param prediction_time time to predict pos
--! @param current_velocity current velocity of mob
--! @return { x,y,z } position after specified time
-------------------------------------------------------------------------------
function movement_generic.calc_new_pos(pos,acceleration,prediction_time,current_velocity)
local predicted_pos = {x=pos.x,y=pos.y,z=pos.z}
predicted_pos.x = predicted_pos.x + current_velocity.x * prediction_time + (acceleration.x/2)*math.pow(prediction_time,2)
predicted_pos.z = predicted_pos.z + current_velocity.z * prediction_time + (acceleration.z/2)*math.pow(prediction_time,2)
return predicted_pos
end
-------------------------------------------------------------------------------
-- name: predict_next_block(pos,velocity,acceleration)
--
--! @brief predict next block based on pos velocity and acceleration
--
--! @param pos current position
--! @param velocity current velocity
--! @param acceleration current acceleration
--! @return { x,y,z } position of next block
-------------------------------------------------------------------------------
function movement_generic.predict_next_block(pos,velocity,acceleration)
local prediction_time = 2
local pos_predicted = movement_generic.calc_new_pos(pos,
acceleration,
prediction_time,
velocity
)
local count = 1
--check if after prediction time we would have traveled more than one block and adjust to not predict to far
while mobf_calc_distance(pos,pos_predicted) > 1 do
pos_predicted = movement_generic.calc_new_pos(pos,
acceleration,
prediction_time - (count*0.1),
velocity
)
if (prediction_time - (count*0.1)) < 0 then
minetest.log(LOGLEVEL_WARNING,"MOBF: Bug!!!! didn't find a suitable prediction time. Mob will move more than one block within prediction period")
break
end
count = count +1
end
return pos_predicted
end