We now point non-player entities away from portal, Looks really good with

mobs like rats and sheep.
This commit is contained in:
Robert Munafo 2015-10-13 18:32:01 -04:00
parent 335db88466
commit a61a583f54
2 changed files with 107 additions and 37 deletions

View File

@ -76,6 +76,7 @@ old portalgun_portals table)
20151011 When a player is teleported and the exit portal points x+, 20151011 When a player is teleported and the exit portal points x+,
x-, z+ or z-, we now set their look direction appropriately so they x-, z+ or z-, we now set their look direction appropriately so they
have their back to the portal they just emerged from. have their back to the portal they just emerged from.
20151012 Set yaw of non-player entities as they emerge from a portal
TODO - BUG FIXES TODO - BUG FIXES

View File

@ -35,6 +35,68 @@ local function node_ok(pos)
return minetest.registered_nodes[fallback] return minetest.registered_nodes[fallback]
end end
-- try to figure out the object's physical height. There are
-- several cases that need to be handled. Not all objects
-- have a collisionbox
local function object_height(ob)
if ob:is_player() then
-- We assume players have a height of 1.8 metres
print "object_height: is player, returning 1.8"
return 1.8
end
local ent = ob:get_luaentity()
if ent then
local cb = ent.collisionbox;
if cb then
-- We got lucky, an object whose entity actually defines a
-- collisionbox! The height is in cb[5]
print("object_height: cb ("..cb[1]..", "..cb[2]..", "..cb[3]
..", "..cb[4]..", "..cb[5]..", "..cb[6]..")")
return cb[5]
elseif ent.name=="__builtin:item" then
local iname = ItemStack(ent.itemstring):get_name()
print("object_height: dropped obj '"..ent.itemstring
.."', iname '"..iname.."'")
cb = minetest.registered_entities[ent.name].collisionbox
if cb == nil then
cb = minetest.registered_items[iname].collisionbox
end
if cb then
-- This seems to never happen
print(" found cb ("..cb[1]..", "..cb[2]..", "..cb[3]
..", "..cb[4]..", "..cb[5]..", "..cb[6]..")")
return cb[5]
else
-- Try to get the visual attribute, but it is never available
local vs = minetest.registered_entities[ent.name].visual
print(" no cb, visual '"..minetest.serialize(vs).."'")
-- TODO: Can we test what version of the Minetest engine
-- we're in? The size of __builtin:item objects changed,
-- look in game/item_entity.lua for a call to register_entity
-- it used to be about 0.33 and is presently 0.6
return 0.6
end
else
print("object_height: entity '"..ent.name.."'")
cb = minetest.registered_entities[ent.name].collisionbox
if cb then
-- This seems to never happen
print(" found cb ("..cb[1]..", "..cb[2]..", "..cb[3]
..", "..cb[4]..", "..cb[5]..", "..cb[6]..")")
return cb[5]
else
print(" no cb, assume small")
end
end
else
-- we couldn't get a laentity
end
-- if we get here we couldn't figure it out at all.
return 0.1
end
minetest.register_on_leaveplayer( minetest.register_on_leaveplayer(
-- when a player leaves the game, make their portals expire -- when a player leaves the game, make their portals expire
function(user) function(user)
@ -95,6 +157,12 @@ local function portalgun_step_proc(portal, id)
-- to catch players, whose "position" is a point near the feet) -- to catch players, whose "position" is a point near the feet)
for ii, ob in pairs(minetest.get_objects_inside_radius(pos1, 1.5)) do for ii, ob in pairs(minetest.get_objects_inside_radius(pos1, 1.5)) do
local ent = ob:get_luaentity() local ent = ob:get_luaentity()
-- TODO: use object height to get a more refined sense of the
-- object's true distance from the portal, and ignore if object
-- is not within a closer radius
-- local height = object_height(ob)
if ent and ent.name == "portalgun:portal" then if ent and ent.name == "portalgun:portal" then
-- this object is the portal itself; ignore -- this object is the portal itself; ignore
else else
@ -116,12 +184,6 @@ local function portalgun_step_proc(portal, id)
-- compute the magnitude of the velocity -- compute the magnitude of the velocity
local vmag = math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z) local vmag = math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
-- if v.x<0 then v.x=v.x*-1 end
-- if v.y<0 then v.y=v.y*-1 end
-- if v.z<0 then v.z=v.z*-1 end
-- local vmag=0 -- get the biggest velocity
-- if v.x>v.z then vmag=v.x else vmag=v.z end
-- if vmag<v.y then vmag=v.y end
-- compute exit velocity. Objects always exit in a -- compute exit velocity. Objects always exit in a
-- direction perpendicular to the exit portal, with -- direction perpendicular to the exit portal, with
@ -131,16 +193,20 @@ local function portalgun_step_proc(portal, id)
v.z = 0 v.z = 0
if d2 == "x+" then if d2 == "x+" then
v.x = vmag v.x = vmag
ob:setyaw(math.pi/-2)
elseif d2 == "x-" then elseif d2 == "x-" then
v.x = vmag*-1 v.x = vmag*-1
ob:setyaw(math.pi/2)
elseif d2 == "y+" then elseif d2 == "y+" then
v.y = vmag v.y = vmag
elseif d2 == "y-" then elseif d2 == "y-" then
v.y = vmag*-1 v.y = vmag*-1
elseif d2 == "z+" then elseif d2 == "z+" then
v.z = vmag v.z = vmag
ob:setyaw(0)
elseif d2 == "z-" then elseif d2 == "z-" then
v.z = vmag*-1 v.z = vmag*-1
ob:setyaw(math.pi)
end end
ob:setvelocity({x = v.x, y = v.y, z = v.z}) ob:setvelocity({x = v.x, y = v.y, z = v.z})
@ -150,6 +216,8 @@ local function portalgun_step_proc(portal, id)
-- in whatever direction the exit portal is facing. It has -- in whatever direction the exit portal is facing. It has
-- to be 2 nodes away so we don't immediately get -- to be 2 nodes away so we don't immediately get
-- teleported again. -- teleported again.
-- TODO: Once we manage to decrease the capture radius of 1.5,
-- we may also diminish this distance.
if d2 == "x+" then x = 2 if d2 == "x+" then x = 2
elseif d2 == "x-" then x = -2 elseif d2 == "x-" then x = -2
elseif d2 == "y+" then y = 2 elseif d2 == "y+" then y = 2
@ -412,6 +480,7 @@ local function portal_useproc(itemstack, user, pointed_thing, RMB, remove)
id_p0rtal[id].portal1 = obj id_p0rtal[id].portal1 = obj
end end
if obj then if obj then
-- fill in its staticdata
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
if ent then if ent then
ent.owner = uname ent.owner = uname
@ -430,7 +499,7 @@ local function portal_useproc(itemstack, user, pointed_thing, RMB, remove)
op_prtl[op] = {} op_prtl[op] = {}
end end
op_prtl[op].pnum = pnum op_prtl[op].pnum = pnum
op_prtl[op].portal = portal op_prtl[op].portal = obj
op_prtl[op].owner = uname op_prtl[op].owner = uname
op_prtl[op].pos = cpos op_prtl[op].pos = cpos
op_prtl[op].dir = portal_dir op_prtl[op].dir = portal_dir