2012-09-19 23:30:14 +02:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- 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 environment.lua
|
|
|
|
--! @brief component for environment related functions
|
|
|
|
--! @copyright Sapier
|
|
|
|
--! @author Sapier
|
|
|
|
--! @date 2012-08-09
|
|
|
|
--
|
|
|
|
--! @defgroup environment Environment subcomponent
|
|
|
|
--! @brief Environment check functions used by different subcomponents
|
|
|
|
--! @ingroup framework_int
|
|
|
|
--! @{
|
|
|
|
-- Contact sapier a t gmx net
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
environment = {}
|
|
|
|
|
|
|
|
--! @brief list of known environments
|
|
|
|
--! @memberof environment
|
|
|
|
environment_list = {}
|
|
|
|
|
2013-01-27 18:07:02 +00:00
|
|
|
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: get_suitable_pos_same_level(pos_raw,maxsearcharea,entity)
|
|
|
|
--
|
|
|
|
--! @brief find a position suitable around a specific position
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param pos_raw position to look at
|
|
|
|
--! @param maxsearcharea max range to look for suitable position
|
|
|
|
--! @param entity mob to look for position
|
|
|
|
--! @param accept_possible return position thats possible only too
|
|
|
|
--! @return {x,y,z} position found or nil
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.get_suitable_pos_same_level(pos_raw,maxsearcharea,entity,accept_possible)
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl2("MOBF: --> get_suitable_pos_same_level "
|
2013-01-04 23:49:58 +00:00
|
|
|
.. printpos(pos_raw))
|
2012-09-19 23:30:14 +02:00
|
|
|
local pos = mobf_round_pos(pos_raw)
|
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: Starting pos is "..printpos(pos)
|
2013-01-04 23:49:58 +00:00
|
|
|
.." max search area is "..maxsearcharea)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
local e1 = "|"
|
|
|
|
local e2 = "|"
|
|
|
|
local e3 = "|"
|
|
|
|
local e4 = "|"
|
|
|
|
|
|
|
|
local possible_targets = {}
|
|
|
|
|
|
|
|
--search next position on solid ground
|
|
|
|
for search=1, maxsearcharea,1 do
|
|
|
|
--find along edge 1
|
|
|
|
for current=-search,search,1 do
|
|
|
|
local pos_tocheck = { x= pos.x + current,y=pos.y,z=pos.z -search}
|
|
|
|
local pos_state = environment.pos_is_ok(pos_tocheck,entity)
|
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: state of "..printpos(pos_tocheck).." is "
|
2013-01-04 23:49:58 +00:00
|
|
|
.. pos_state)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
if pos_state == "ok" then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found good pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
elseif pos_state == "possible_surface" and
|
|
|
|
accept_possible then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found acceptable pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
-- elseif pos_state == "collision_jumpabe" then
|
|
|
|
-- dbg_mobf.movement_lvl1("found new pos above")
|
|
|
|
-- return {x=pos_tocheck.x,y=pos_tocheck.y+1,z=pos_tocheck.z}
|
|
|
|
else
|
|
|
|
e1 = e1..pos_state.."|"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--find along edge 2
|
|
|
|
for current=-(search-1),(search-1),1 do
|
|
|
|
local pos_tocheck = { x= pos.x + search,y=pos.y,z=pos.z + current}
|
|
|
|
local pos_state = environment.pos_is_ok(pos_tocheck,entity)
|
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: state of "..printpos(pos_tocheck).." is "
|
2013-01-04 23:49:58 +00:00
|
|
|
.. pos_state)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
if pos_state == "ok" then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found good pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
elseif pos_state == "possible_surface" and
|
|
|
|
accept_possible then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found acceptable pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
else
|
|
|
|
e2 = e2..pos_state.."|"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--find along edge 3
|
|
|
|
|
|
|
|
for current=search,-search,-1 do
|
|
|
|
local pos_tocheck = { x= pos.x + current,y=pos.y,z=pos.z + search}
|
|
|
|
local pos_state = environment.pos_is_ok(pos_tocheck,entity)
|
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: state of "..printpos(pos_tocheck).." is "
|
2013-01-04 23:49:58 +00:00
|
|
|
.. pos_state)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
if pos_state == "ok" then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found good pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
elseif pos_state == "possible_surface" and
|
|
|
|
accept_possible then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found acceptable pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
else
|
|
|
|
e3 = e3..pos_state.."|"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--find along edge 4
|
|
|
|
for current=(search-1),-(search-1),-1 do
|
|
|
|
local pos_tocheck = { x= pos.x -search,y=pos.y,z=pos.z + current}
|
|
|
|
local pos_state = environment.pos_is_ok(pos,entity)
|
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: state of "..printpos(pos_tocheck).." is "
|
2013-01-04 23:49:58 +00:00
|
|
|
.. pos_state)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
if pos_state == "ok" then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found good pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
elseif pos_state == "possible_surface" and
|
|
|
|
accept_possible then
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl3(" -->found acceptable pos")
|
2012-09-19 23:30:14 +02:00
|
|
|
table.insert(possible_targets, pos_tocheck)
|
|
|
|
else
|
|
|
|
e4 = e4..pos_state.."|"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- print("MOBF: Bug !!! didn't find a suitable position to place mob")
|
|
|
|
-- print("Surrounding of " .. printpos(pos_raw) .. "was:")
|
|
|
|
-- print(e1)
|
|
|
|
-- print(" " .. e2)
|
|
|
|
-- print(e4)
|
|
|
|
-- print(e3)
|
|
|
|
|
|
|
|
if #possible_targets > 0 then
|
|
|
|
local i = math.random(1, #possible_targets)
|
2013-08-17 11:47:02 +02:00
|
|
|
dbg_mobf.environment_lvl2("Found " .. #possible_targets
|
|
|
|
.. " possible positions, selected: "
|
|
|
|
.. i .. ": " .. printpos(possible_targets[i]))
|
2012-09-19 23:30:14 +02:00
|
|
|
return possible_targets[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: is_media_element(nodename,environment)
|
|
|
|
--
|
|
|
|
--! @brief check if nodename is in environment
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param nodename name to check
|
|
|
|
--! @param media environment of mob
|
|
|
|
--! @return true/false
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
function environment.is_media_element( nodename, media )
|
|
|
|
|
|
|
|
--security check
|
|
|
|
if media == false then
|
2012-12-25 18:18:38 +00:00
|
|
|
mobf_bug_warning(LOGLEVEL_ERROR,"MOBF: BUG!!!! no environment specified!")
|
2012-09-19 23:30:14 +02:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
for i,v in ipairs(media) do
|
|
|
|
if v == nodename then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: " .. nodename .. " is not within environment list:")
|
|
|
|
|
|
|
|
for i,v in ipairs(media) do
|
2013-01-20 13:29:25 +00:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: \t" .. v)
|
2012-09-19 23:30:14 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: get_absolute_min_max_pos(env, pos)
|
|
|
|
--
|
|
|
|
--! @brief check if nodename is in environment
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param env environment mob should be
|
|
|
|
--! @param pos position it is currently
|
|
|
|
--! @return { minpos,maxpos }
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
function environment.get_absolute_min_max_pos(env,pos)
|
|
|
|
|
2013-05-26 13:35:33 +02:00
|
|
|
local node = minetest.get_node(pos)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
--if is not within environment it should be return current position
|
|
|
|
--as min max
|
|
|
|
if environment.is_media_element(node.name,env.media) == false then
|
|
|
|
return pos.y,pos.y
|
|
|
|
end
|
|
|
|
|
|
|
|
local min_y = env.min_height_above_ground
|
|
|
|
local max_y = env.max_height_above_ground
|
2012-12-30 01:03:09 +00:00
|
|
|
|
|
|
|
|
2012-09-19 23:30:14 +02:00
|
|
|
--a fully generic check isn't possible here so we need to use media
|
|
|
|
--specific ways ... it's ugly but works
|
|
|
|
if node.name == "air" then
|
|
|
|
min_y = min_y + ( pos.y - mobf_surface_distance(pos))
|
|
|
|
max_y = max_y + ( pos.y - mobf_surface_distance(pos))
|
|
|
|
end
|
|
|
|
|
|
|
|
if node.name == "default:water" or
|
|
|
|
node.name == "defailt:water_flowing" then
|
|
|
|
-- water mobs do use min/max directly
|
|
|
|
end
|
|
|
|
|
|
|
|
if node.name == "default:lava" or
|
|
|
|
node.name == "default:lava_flowing" then
|
2012-12-30 01:03:09 +00:00
|
|
|
--TODO e.g. lava fish
|
2012-09-19 23:30:14 +02:00
|
|
|
--not implemented by now
|
|
|
|
end
|
|
|
|
|
|
|
|
return min_y,max_y
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: is_jumpable_surface(name)
|
|
|
|
--
|
|
|
|
--! @brief check if name is a surface an mob may jump onto
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param name name to check
|
|
|
|
--! @return true/false
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.is_jumpable_surface(name)
|
|
|
|
|
|
|
|
|
|
|
|
if name == "default:dirt" or
|
|
|
|
name == "default:dirt_with_grass" or
|
|
|
|
name == "default:stone" or
|
|
|
|
name == "default:sand" or
|
|
|
|
name == "default:clay"
|
|
|
|
then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
dbg_mobf.environment_lvl1("MOBF: is "..name.." a jumpable surface?")
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: checksurfacek(pos,surfaces)
|
|
|
|
--
|
|
|
|
--! @brief check if a position is suitable for an mob
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param pos position to check
|
|
|
|
--! @param surface surfaces valid
|
|
|
|
--! @return true on valid surface false if not
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.checksurface(pos,surface)
|
|
|
|
|
|
|
|
--if no surfaces are specified any surface is treated as ok
|
|
|
|
if surface == nil then
|
|
|
|
return "ok"
|
|
|
|
end
|
|
|
|
|
|
|
|
local pos_below = {x=pos.x,y=pos.y-1,z=pos.z}
|
|
|
|
|
2013-05-26 13:35:33 +02:00
|
|
|
local node_below = minetest.get_node(pos_below)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
if node_below == nil then
|
|
|
|
return "ok"
|
|
|
|
end
|
|
|
|
|
|
|
|
for i,v in ipairs(surface.good) do
|
|
|
|
if node_below.name == v then
|
|
|
|
return "ok"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if surface.possible ~= nil then
|
|
|
|
for i,v in ipairs(surface.possible) do
|
|
|
|
if node_below.name == v then
|
|
|
|
return "possible_surface"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
return "wrong_surface",node_below.name
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2013-01-27 18:07:02 +00:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: get_min_max_ground_dist(entity)
|
|
|
|
--
|
|
|
|
--! @brief calculate absolute minimum and maximum height for a mob
|
|
|
|
--! @ingroup environment
|
|
|
|
--
|
|
|
|
--! @param entity mob to check
|
|
|
|
--! @return min y val,max y val
|
|
|
|
-------------------------------------------------------------------------------
|
2013-01-10 20:44:38 +00:00
|
|
|
function environment.get_min_max_ground_dist(entity)
|
|
|
|
local min_ground_distance = 0
|
|
|
|
local max_ground_distance = 0
|
|
|
|
|
|
|
|
if entity.environment.max_height_above_ground ~= nil then
|
|
|
|
max_ground_distance = entity.environment.max_height_above_ground
|
|
|
|
end
|
|
|
|
|
|
|
|
if entity.environment.min_height_above_ground ~= nil then
|
|
|
|
min_ground_distance = entity.environment.min_height_above_ground
|
|
|
|
end
|
|
|
|
|
|
|
|
if entity.data.movement.canfly == nil or
|
|
|
|
entity.data.movement.canfly == false then
|
|
|
|
max_ground_distance = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
return min_ground_distance,max_ground_distance
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
2013-08-17 11:47:02 +02:00
|
|
|
-- name: evaluate_pos_media(pos,media)
|
|
|
|
--
|
|
|
|
--! @brief check position media quality
|
|
|
|
--! @ingroup environment
|
|
|
|
--
|
|
|
|
--! @param pos position to check
|
|
|
|
--! @param entity mob to check
|
|
|
|
--!
|
|
|
|
--! @return 100 = in media 10 collision 0 invalid, nodename
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.evaluate_pos_media(pos,media)
|
|
|
|
local node_to_check = minetest.get_node(pos)
|
2013-08-17 12:51:59 +02:00
|
|
|
|
2013-08-17 11:47:02 +02:00
|
|
|
if node_to_check == nil then
|
|
|
|
mobf_bug_warning(LOGLEVEL_ERROR,"MOBF: BUG!!!! checking position with invalid node")
|
|
|
|
return 0,nil
|
|
|
|
end
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
if not environment.is_media_element(node_to_check.name,media) then
|
2013-08-17 11:47:02 +02:00
|
|
|
return 10,node_to_check
|
|
|
|
end
|
|
|
|
|
|
|
|
return 100,node_to_check
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: same_state(state1,state2)
|
|
|
|
--
|
|
|
|
--! @brief compare two states
|
|
|
|
--! @ingroup environment
|
|
|
|
--
|
|
|
|
--! @param state1
|
|
|
|
--! @param state2
|
|
|
|
--!
|
|
|
|
--! @return true/false
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.same_state(state1,state2)
|
|
|
|
|
|
|
|
if state1.valid == false or
|
|
|
|
state2.valid == false then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.media_quality ~= state2.media_quality then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.geometric_quality ~= state2.geometric_quality then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.surface_quality_min ~= state2.surface_quality_min then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.surface_quality_max ~= state2.surface_quality_max then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.level_quality ~= state2.level_quality then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: compare_state(state1,state2)
|
|
|
|
--
|
|
|
|
--! @brief compare state1 and state2
|
|
|
|
--! @ingroup environment
|
|
|
|
--
|
|
|
|
--! @param state1
|
|
|
|
--! @param state2
|
|
|
|
--!
|
|
|
|
--! @return -1, 0, 1
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.compare_state(state1,state2)
|
|
|
|
mobf_assert_backtrace(state1)
|
|
|
|
mobf_assert_backtrace(state2)
|
|
|
|
|
|
|
|
local right_worse = false
|
|
|
|
local right_better = false
|
|
|
|
|
|
|
|
if state1.valid == false and state2.valid == true then
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.valid == true and state2.valid == false then
|
|
|
|
return -1
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.media_quality < state2.media_quality or
|
|
|
|
state1.geometric_quality < state2.geometric_quality or
|
|
|
|
state1.surface_quality_min < state2.surface_quality_min or
|
|
|
|
state1.surface_quality_max < state2.surface_quality_max or
|
|
|
|
state1.level_quality < state2.level_quality
|
|
|
|
then
|
|
|
|
right_better = true
|
|
|
|
end
|
|
|
|
|
|
|
|
if state1.media_quality > state2.media_quality or
|
|
|
|
state1.geometric_quality > state2.geometric_quality or
|
|
|
|
state1.surface_quality_min > state2.surface_quality_min or
|
|
|
|
state1.surface_quality_max > state2.surface_quality_max or
|
|
|
|
state1.level_quality > state2.level_quality
|
|
|
|
then
|
|
|
|
left_better = true
|
|
|
|
end
|
|
|
|
if right_better and not left_better then
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if left_better and not right_better then
|
|
|
|
return -1
|
|
|
|
end
|
|
|
|
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
2013-08-17 12:51:59 +02:00
|
|
|
-- name: pos_quality(pos,entity)
|
2013-08-17 11:47:02 +02:00
|
|
|
--
|
|
|
|
--! @brief check position quality
|
|
|
|
--! @ingroup environment
|
|
|
|
--
|
|
|
|
--! @param pos position to check
|
|
|
|
--! @param entity mob to check
|
|
|
|
--! @return position quality
|
|
|
|
--! {
|
|
|
|
--! media_quality 100 = in media
|
|
|
|
--! 30 = collision
|
|
|
|
--! 20 = special in_water
|
|
|
|
--! 10 = special in_air
|
|
|
|
--! 0 = not evaluated
|
|
|
|
--! geometric_quality = 100 = full contact
|
|
|
|
--! 60 = partial contact
|
|
|
|
--! 30 = no contact
|
|
|
|
--! 0 = not evaluated
|
|
|
|
--! surface_quality_min = 100 = all ok
|
|
|
|
--! 60 = worst is possible
|
|
|
|
--! 30 = worst is wrong
|
|
|
|
--! 10 = special "above_water"
|
|
|
|
--! 0 = not evaluated
|
|
|
|
--! surface_quality_max = 100 = all ok
|
|
|
|
--! 60 = best is possible
|
|
|
|
--! 30 = best is wrong
|
|
|
|
--! 10 = special "above_water"
|
|
|
|
--! 0 = not evaluated
|
|
|
|
--! level_quality = 100 = ok
|
|
|
|
--! 60 = above_limit
|
|
|
|
--! 30 = below_limit
|
|
|
|
--! 0 = not evaluated
|
|
|
|
--! valid = true = data is valid
|
|
|
|
--! false = no valid data
|
|
|
|
-------------------------------------------------------------------------------
|
2013-08-17 12:51:59 +02:00
|
|
|
function environment.pos_quality(pos,entity)
|
2013-08-17 11:47:02 +02:00
|
|
|
|
|
|
|
local retval = {
|
2013-08-17 12:51:59 +02:00
|
|
|
media_quality = 100,
|
2013-08-17 11:47:02 +02:00
|
|
|
geometric_quality = 0,
|
|
|
|
surface_quality_min = 100,
|
|
|
|
surface_quality_max = 0,
|
|
|
|
level_quality = 100,
|
|
|
|
valid = true,
|
2013-08-17 12:51:59 +02:00
|
|
|
|
|
|
|
tostring = function(state)
|
|
|
|
local retval = "\nState: ".. dump(state.valid) .. "\n"
|
|
|
|
retval = retval .."\tmedia_quality: (" .. state.media_quality ..") "
|
|
|
|
if state.media_quality == 100 then retval = retval .. "in media" end
|
|
|
|
if state.media_quality == 30 then retval = retval .. "collision" end
|
|
|
|
if state.media_quality == 20 then retval = retval .. "in water" end
|
|
|
|
if state.media_quality == 10 then retval = retval .. "in air" end
|
|
|
|
if state.media_quality == 5 then retval = retval .. "solid" end
|
|
|
|
if state.media_quality == 0 then retval = retval .. "not evaluated" end
|
|
|
|
|
|
|
|
retval = retval .."\n\tgeometric_quality: (" .. state.geometric_quality .. ") "
|
|
|
|
if state.geometric_quality == 100 then retval = retval .. "full contact" end
|
|
|
|
if state.geometric_quality == 60 then retval = retval .. "partial contact" end
|
|
|
|
if state.geometric_quality == 30 then retval = retval .. "no contact" end
|
|
|
|
if state.geometric_quality == 0 then retval = retval .. "not evaluated" end
|
|
|
|
|
|
|
|
retval = retval .."\n\tsurface_quality_min: (" .. state.surface_quality_min ..") "
|
|
|
|
if state.surface_quality_min == 100 then retval = retval .. "ok" end
|
|
|
|
if state.surface_quality_min == 60 then retval = retval .. "possible" end
|
|
|
|
if state.surface_quality_min == 30 then retval = retval .. "wrong" end
|
|
|
|
if state.surface_quality_min == 10 then retval = retval .. "above water" end
|
|
|
|
if state.surface_quality_min == 0 then retval = retval .. "not evaluated" end
|
|
|
|
|
|
|
|
retval = retval .."\n\tsurface_quality_max: (" .. state.surface_quality_max .. ") "
|
|
|
|
if state.surface_quality_max == 100 then retval = retval .. "ok" end
|
|
|
|
if state.surface_quality_max == 60 then retval = retval .. "possible" end
|
|
|
|
if state.surface_quality_max == 30 then retval = retval .. "wrong" end
|
|
|
|
if state.surface_quality_max == 10 then retval = retval .. "above water" end
|
|
|
|
if state.surface_quality_max == 0 then retval = retval .. "not evaluated" end
|
|
|
|
|
|
|
|
retval = retval .."\n\tlevel_quality: (" .. state.level_quality .. ") "
|
|
|
|
if state.level_quality == 100 then retval = retval .. "ok" end
|
|
|
|
if state.level_quality == 60 then retval = retval .. "above limit" end
|
|
|
|
if state.level_quality == 30 then retval = retval .. "below limit" end
|
|
|
|
if state.level_quality == 0 then retval = retval .. "not evaluated" end
|
|
|
|
retval = retval .. "\n"
|
|
|
|
|
|
|
|
return retval
|
|
|
|
end
|
2013-08-17 11:47:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local cornerpositions = {}
|
|
|
|
local lastpos = nil -- performance improvement to skip checking same pos multiple times
|
|
|
|
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[4] -0.01,y=pos.y,z=pos.z + entity.collisionbox[6] -0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[4] -0.01,y=pos.y,z=pos.z + entity.collisionbox[3] +0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[1] +0.01,y=pos.y,z=pos.z + entity.collisionbox[6] -0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[1] +0.01,y=pos.y,z=pos.z + entity.collisionbox[3] +0.01})
|
|
|
|
|
|
|
|
local min_ground_distance,max_ground_distance = environment.get_min_max_ground_dist(entity)
|
|
|
|
|
|
|
|
--check if mob at pos will be in correct environment
|
|
|
|
for i=1,#cornerpositions,1 do
|
|
|
|
if not mobf_pos_is_same(lastpos,cornerpositions[i]) then
|
|
|
|
local med_quality,node_to_check =
|
|
|
|
environment.evaluate_pos_media(cornerpositions[i],
|
|
|
|
entity.environment.media)
|
|
|
|
--if current result is worse than old one
|
|
|
|
if med_quality < retval.media_quality then
|
|
|
|
if med_quality == 0 then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.valid = false
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if node_to_check.name == "default:water_source" or
|
|
|
|
node_to_check.name == "default:water_flowing" then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.media_quality = 20
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if node_to_check.name == "air" then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.media_quality = 10
|
2013-08-17 11:47:02 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
if med_quality < retval.media_quality then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.media_quality = 5
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
lastpos = cornerpositions[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
--check height level for flying mobs
|
|
|
|
if entity.data.movement.canfly == true then
|
|
|
|
lastpos = nil
|
|
|
|
for i=1,#cornerpositions,1 do
|
|
|
|
if not mobf_pos_is_same(lastpos,cornerpositions[i]) then
|
|
|
|
local miny,maxy = environment.get_absolute_min_max_pos(entity.environment,cornerpositions[i])
|
|
|
|
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tflying mob detected, min: "
|
|
|
|
.. miny .. " max: " .. maxy .. " current: " .. pos.y)
|
|
|
|
|
|
|
|
|
|
|
|
if cornerpositions[i].y < miny then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.level_quality = 30
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if cornerpositions[i].y > maxy then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.level_quality = 60
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
if retval.level_quality < 100 then
|
2013-08-17 11:47:02 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
lastpos = cornerpositions[i]
|
|
|
|
end
|
|
|
|
else
|
|
|
|
|
|
|
|
--check geometric and surface quality
|
|
|
|
lastpos = nil
|
|
|
|
local have_contact = false
|
|
|
|
local have_no_contact = false
|
|
|
|
for i=1,#cornerpositions,1 do
|
|
|
|
if not mobf_pos_is_same(lastpos,cornerpositions[i]) then
|
|
|
|
|
|
|
|
local ground_distance = mobf_ground_distance(cornerpositions[i], entity.environment.media)
|
|
|
|
|
|
|
|
|
|
|
|
--first check if on surface or not
|
|
|
|
if ground_distance <= max_ground_distance then
|
|
|
|
have_contact = true
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
local current_surface,belowname =
|
|
|
|
environment.checksurface(cornerpositions[i],entity.environment.surfaces)
|
2013-08-17 11:47:02 +02:00
|
|
|
|
|
|
|
if current_surface == "ok" then
|
2013-08-17 12:51:59 +02:00
|
|
|
if retval.surface_quality_max < 100 then
|
|
|
|
retval.surface_quality_max = 100
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if current_surface == "possible_surface" then
|
2013-08-17 12:51:59 +02:00
|
|
|
if retval.surface_quality_max < 60 then
|
|
|
|
retval.surface_quality_max = 60
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
if retval.surface_quality_min > 60 then
|
|
|
|
retval.surface_quality_min = 60
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if current_surface == "wrong_surface" then
|
2013-08-17 12:51:59 +02:00
|
|
|
if belowname == "default:water_source" or
|
|
|
|
belowname == "default:water_flowing" then
|
|
|
|
if retval.surface_quality_max < 10 then
|
|
|
|
retval.surface_quality_max = 10
|
|
|
|
end
|
|
|
|
|
|
|
|
if retval.surface_quality_min > 10 then
|
|
|
|
retval.surface_quality_min = 10
|
|
|
|
end
|
|
|
|
|
|
|
|
else
|
|
|
|
if retval.surface_quality_max < 30 then
|
|
|
|
retval.surface_quality_max = 30
|
|
|
|
end
|
|
|
|
|
|
|
|
if retval.surface_quality_min > 30 then
|
|
|
|
retval.surface_quality_min = 30
|
|
|
|
end
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
have_no_contact = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
lastpos = cornerpositions[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
if have_contact and not have_no_contact then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.geometric_quality = 100
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if have_contact and have_no_contact then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.geometric_quality = 60
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if not have_contact and have_no_contact then
|
2013-08-17 12:51:59 +02:00
|
|
|
retval.geometric_quality = 30
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-17 12:51:59 +02:00
|
|
|
return retval
|
2013-08-17 11:47:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: pos_is_ok(pos,entity) DEPRECATED
|
2013-01-10 20:44:38 +00:00
|
|
|
--
|
|
|
|
--! @brief check if a position is suitable for an mob
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2013-01-10 20:44:38 +00:00
|
|
|
--
|
|
|
|
--! @param pos position to check
|
|
|
|
--! @param entity mob to check
|
2013-01-20 13:29:25 +00:00
|
|
|
--! @param dont_do_jumpcheck
|
2013-01-10 20:44:38 +00:00
|
|
|
--! @return suitability of position for mob values:
|
|
|
|
--! -ok -@>position is ok
|
|
|
|
--! -collision -@>position is within a node
|
|
|
|
--! -collision_jumpable -@>position is within a node that can be jumped onto
|
|
|
|
--! -drop -@>position is a drop
|
|
|
|
--! -drop_above_water -@>position is to far above water
|
|
|
|
--! -above_water -@>position is right over water
|
|
|
|
--! -in_water -@>position is within a water node(source or flow)
|
|
|
|
--! -in_air -@>position is in air
|
|
|
|
--! -above_limit -@>position is above level limit
|
|
|
|
--! -below_limit -@>position is below level limit
|
|
|
|
--! -wrong_surface -@>position is above surface mob shouldn't be
|
|
|
|
--! -invalid -@>unable to check position
|
|
|
|
-------------------------------------------------------------------------------
|
2013-01-20 13:29:25 +00:00
|
|
|
function environment.pos_is_ok(pos,entity,dont_do_jumpcheck)
|
2013-01-10 20:44:38 +00:00
|
|
|
|
|
|
|
local min_ground_distance,max_ground_distance = environment.get_min_max_ground_dist(entity)
|
|
|
|
|
|
|
|
local cornerpositions = {}
|
|
|
|
|
|
|
|
table.insert(cornerpositions,pos)
|
|
|
|
--read positions at corners
|
2013-01-20 13:29:25 +00:00
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[4] -0.01,y=pos.y,z=pos.z + entity.collisionbox[6] -0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[4] -0.01,y=pos.y,z=pos.z + entity.collisionbox[3] +0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[1] +0.01,y=pos.y,z=pos.z + entity.collisionbox[6] -0.01})
|
|
|
|
table.insert(cornerpositions,{x=pos.x + entity.collisionbox[1] +0.01,y=pos.y,z=pos.z + entity.collisionbox[3] +0.01})
|
2013-01-10 20:44:38 +00:00
|
|
|
|
|
|
|
local lastpos = nil
|
|
|
|
|
|
|
|
local retval = "temp_ok"
|
|
|
|
|
|
|
|
--check if mob at pos will be in correct environment
|
|
|
|
for i=1,#cornerpositions,1 do
|
|
|
|
if not mobf_pos_is_same(lastpos,cornerpositions[i]) then
|
2013-05-26 13:35:33 +02:00
|
|
|
local node_to_check = minetest.get_node(cornerpositions[i])
|
2013-01-10 20:44:38 +00:00
|
|
|
|
|
|
|
if node_to_check == nil then
|
|
|
|
mobf_bug_warning(LOGLEVEL_ERROR,"MOBF: BUG!!!! checking position with invalid node")
|
|
|
|
retval = "invalid"
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
if not environment.is_media_element(node_to_check.name,entity.environment.media) == true then
|
2013-01-20 13:29:25 +00:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: " .. i .. ": " ..
|
|
|
|
printpos(cornerpositions[i]) .. " -- " .. printpos(pos) ..
|
|
|
|
" not within environment")
|
2013-01-10 20:44:38 +00:00
|
|
|
|
|
|
|
if mobf_pos_is_same(pos,cornerpositions[i]) then
|
|
|
|
if node_to_check.name == "default:water_source" or
|
|
|
|
node_to_check.name == "default:water_flowing" then
|
|
|
|
retval = "in_water"
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
if node_to_check.name == "air" then
|
|
|
|
retval = "in_air"
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
--TODO maybe replace by "invalid medium"
|
|
|
|
else
|
|
|
|
retval = "collision"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
lastpos = cornerpositions[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
--
|
|
|
|
if retval == "temp_ok" then
|
2013-02-05 21:16:43 +00:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: \tin environment")
|
2013-01-10 20:44:38 +00:00
|
|
|
local ground_distance = mobf_ground_distance(pos,entity.environment.media)
|
|
|
|
|
|
|
|
--following return codes are only usefull for non flying
|
|
|
|
if entity.data.movement.canfly == nil or
|
|
|
|
entity.data.movement.canfly == false then
|
|
|
|
|
|
|
|
if mobf_above_water(pos) then
|
|
|
|
|
|
|
|
if ground_distance > max_ground_distance then
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tdropping above water")
|
|
|
|
retval = "drop_above_water"
|
|
|
|
end
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tabove water")
|
|
|
|
retval = "above_water"
|
|
|
|
end
|
|
|
|
|
|
|
|
if ground_distance > max_ground_distance then
|
2013-01-19 13:50:54 +00:00
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tdropping "
|
|
|
|
.. ground_distance .. " / " .. max_ground_distance)
|
2013-01-10 20:44:38 +00:00
|
|
|
retval = "drop"
|
|
|
|
else
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tsurface dependent")
|
|
|
|
retval = environment.checksurface(pos,entity.environment.surfaces)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
local miny,maxy = environment.get_absolute_min_max_pos(entity.environment,pos)
|
2013-01-20 13:29:25 +00:00
|
|
|
dbg_mobf.environment_lvl2("MOBF: \tflying mob detected, min: "
|
|
|
|
.. miny .. " max: " .. maxy .. " current: " .. pos.y)
|
2013-01-10 20:44:38 +00:00
|
|
|
if pos.y < miny then
|
|
|
|
retval = "below_limit"
|
2013-01-20 13:29:25 +00:00
|
|
|
else if pos.y > maxy then
|
2013-01-10 20:44:38 +00:00
|
|
|
retval = "above_limit"
|
2013-01-20 13:29:25 +00:00
|
|
|
else
|
|
|
|
retval = environment.checksurface(pos,entity.environment.surfaces)
|
|
|
|
end end
|
2013-01-10 20:44:38 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-20 13:29:25 +00:00
|
|
|
if retval == "collision" and not dont_do_jumpcheck then
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: check if pos is jumpable")
|
|
|
|
local upper_pos_state = environment.pos_is_ok({x=pos.x,
|
|
|
|
y=pos.y+1,
|
|
|
|
z=pos.z},
|
|
|
|
entity,true)
|
|
|
|
if upper_pos_state == "ok" then
|
2013-01-10 20:44:38 +00:00
|
|
|
retval = "collision_jumpable"
|
2013-01-20 13:29:25 +00:00
|
|
|
else
|
|
|
|
dbg_mobf.environment_lvl2("MOBF: upper pos state was: " .. upper_pos_state)
|
2013-01-10 20:44:38 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return retval
|
2012-09-19 23:30:14 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: get_default_gravity(pos,environment,canfly)
|
|
|
|
--
|
|
|
|
--! @brief get default acceleration depending on mobs medium and pos
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param pos position where to check gravity
|
|
|
|
--! @param media mobs movement medium
|
|
|
|
--! @param canfly is mob capable of flying?
|
|
|
|
--! @return y-acceleration
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
function environment.get_default_gravity(pos,media,canfly)
|
|
|
|
|
2012-12-31 04:36:27 +00:00
|
|
|
if pos == nil then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2013-05-26 13:35:33 +02:00
|
|
|
local node = minetest.get_node(pos)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
--if an mob can't fly or isn't within it's medium default acceleration
|
|
|
|
-- for it's current medium is applied
|
|
|
|
if canfly == nil or
|
|
|
|
canfly == false or
|
|
|
|
environment.is_media_element(node.name,media) == false
|
|
|
|
then
|
|
|
|
if (node.name == "air") then
|
|
|
|
return -9.81
|
|
|
|
end
|
|
|
|
|
|
|
|
if node.name == "default:water_source" or
|
|
|
|
node.name == "default:water_flowing" then
|
|
|
|
return -2.5
|
|
|
|
end
|
|
|
|
|
|
|
|
if node.name == "default:lava" then
|
|
|
|
return 0.1
|
|
|
|
end
|
|
|
|
|
|
|
|
--mob is at invalid position thus returning default air acceleration
|
|
|
|
return -9.81
|
|
|
|
end
|
|
|
|
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: fix_base_pos(entity, middle_to_bottom)
|
|
|
|
--
|
|
|
|
--! @brief fix the mobs y position according to model or sprite height
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param entity mob to fix base position
|
|
|
|
--! @param center_to_bottom distance from center of mob to its bottom (absolute value)
|
|
|
|
--! @return new position set by function
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
function environment.fix_base_pos(entity, center_to_bottom)
|
|
|
|
|
|
|
|
if center_to_bottom > 0.5 then
|
|
|
|
|
|
|
|
local pos = entity.object:getpos()
|
|
|
|
|
2013-05-26 13:35:33 +02:00
|
|
|
local node_pos = minetest.get_node(pos)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
local pos_to_check = {x=pos.x,y=pos.y-center_to_bottom+0.1,z=pos.z}
|
2013-05-26 13:35:33 +02:00
|
|
|
local node_pos_check = minetest.get_node(pos_to_check)
|
2012-09-19 23:30:14 +02:00
|
|
|
|
|
|
|
if node_pos ~= nil and
|
|
|
|
node_pos_check ~= nil then
|
2013-01-04 23:49:58 +00:00
|
|
|
dbg_mobf.environment_lvl3("MOBF: fixing y position / base position required? "
|
|
|
|
.. node_pos.name .. " " .. node_pos_check.name)
|
2012-09-19 23:30:14 +02:00
|
|
|
if node_pos.name ~= node_pos_check.name then
|
|
|
|
distance_to_ground = mobf_surface_distance(pos)
|
|
|
|
|
|
|
|
pos.y = pos.y + (center_to_bottom - distance_to_ground +0.5)
|
2013-01-04 23:49:58 +00:00
|
|
|
dbg_mobf.environment_lvl2("MOBF: fixing y position of " .. entity.data.name
|
|
|
|
.. " got distance " .. center_to_bottom .. " moving to " ..printpos(pos))
|
2012-09-19 23:30:14 +02:00
|
|
|
entity.object:moveto(pos)
|
2013-02-05 21:16:43 +00:00
|
|
|
entity.dynamic_data.spawning.spawnpoint = pos
|
2012-09-19 23:30:14 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return entity.getbasepos(entity)
|
|
|
|
end
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: register(name, environment)
|
|
|
|
--
|
|
|
|
--! @brief register an environment to mob framework
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2012-09-19 23:30:14 +02:00
|
|
|
--
|
|
|
|
--! @param name id of environment
|
|
|
|
--! @param environment description of environment
|
|
|
|
--! @return true/false succesfully registred environment
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.register(name, environment)
|
|
|
|
|
|
|
|
if environment_list[name] ~= nil then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
environment_list[name] = environment
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-01-09 00:13:57 +00:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- name: pos_state_is_impossible(entity,pos)
|
|
|
|
--
|
|
|
|
--! @brief checks if a entity can be there (not if it would move there by its own)
|
2013-01-27 18:07:02 +00:00
|
|
|
--! @ingroup environment
|
2013-01-09 00:13:57 +00:00
|
|
|
--
|
|
|
|
--! @param entity entity to check
|
|
|
|
--! @param pos position to check
|
|
|
|
--! @return true entity may be there, entity can never be there
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
function environment.possible_pos(entity,pos)
|
|
|
|
local state = environment.pos_is_ok(pos,entity)
|
|
|
|
|
|
|
|
if state == "collision" or
|
|
|
|
state == "collision_jumpable" or
|
|
|
|
state == "invalid" then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-01-27 18:07:02 +00:00
|
|
|
--!@}
|
|
|
|
|
2013-01-06 23:25:30 +00:00
|
|
|
dofile (mobf_modpath .. "/environments/general_env_sets.lua")
|
2012-09-19 23:30:14 +02:00
|
|
|
dofile (mobf_modpath .. "/environments/flight_1.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/meadow.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/on_ground_1.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/on_ground_2.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/open_waters.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/shallow_waters.lua")
|
|
|
|
dofile (mobf_modpath .. "/environments/simple_air.lua")
|