ball: bounce mode 2 for extra reliable bounce even with lag.. dirt_with grass and glass will now bounce in y-direction, default:wood in x direction and default:junglewood in z direction
This commit is contained in:
parent
7141a657e0
commit
450ce19f4c
43
ball.lua
43
ball.lua
@ -93,7 +93,8 @@ minetest.register_entity("basic_machines:ball",{
|
|||||||
local origin = self.origin;
|
local origin = self.origin;
|
||||||
|
|
||||||
local r = 30;-- maximal distance when balls disappear
|
local r = 30;-- maximal distance when balls disappear
|
||||||
if math.abs(pos.x-origin.x)>r or math.abs(pos.y-origin.y)>r or math.abs(pos.z-origin.z)>r then -- remove if it goes too far
|
local dist = math.max(math.abs(pos.x-origin.x), math.abs(pos.y-origin.y), math.abs(pos.z-origin.z));
|
||||||
|
if dist>r then -- remove if it goes too far
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -102,6 +103,7 @@ minetest.register_entity("basic_machines:ball",{
|
|||||||
local walkable = false;
|
local walkable = false;
|
||||||
if nodename ~= "air" then
|
if nodename ~= "air" then
|
||||||
walkable = minetest.registered_nodes[nodename].walkable;
|
walkable = minetest.registered_nodes[nodename].walkable;
|
||||||
|
if nodename == "basic_machines:ball_spawner" and dist>1 then walkable = true end -- ball can activate spawner, just not originating one
|
||||||
end
|
end
|
||||||
|
|
||||||
if walkable then -- we hit a node
|
if walkable then -- we hit a node
|
||||||
@ -125,11 +127,25 @@ minetest.register_entity("basic_machines:ball",{
|
|||||||
local bounce = self.bounce;
|
local bounce = self.bounce;
|
||||||
if self.bounce == 0 then self.object:remove() return end
|
if self.bounce == 0 then self.object:remove() return end
|
||||||
|
|
||||||
|
local n = {x=0,y=1,z=0}; -- this will be bouncen ormal
|
||||||
local v = self.object:getvelocity();
|
local v = self.object:getvelocity();
|
||||||
|
|
||||||
local opos = {x=round(pos.x),y=round(pos.y), z=round(pos.z)}; -- obstacle
|
local opos = {x=round(pos.x),y=round(pos.y), z=round(pos.z)}; -- obstacle
|
||||||
local bpos ={ x=(pos.x-opos.x),y=(pos.y-opos.y),z=(pos.z-opos.z)}; -- boundary position on cube, approximate
|
local bpos ={ x=(pos.x-opos.x),y=(pos.y-opos.y),z=(pos.z-opos.z)}; -- boundary position on cube, approximate
|
||||||
|
|
||||||
|
if bounce == 2 then -- uses special blocks for exact bouncing: dirt, glass: bounces up/down
|
||||||
|
if node.name == "default:dirt_with_grass" then
|
||||||
|
if bpos.y<0 then n.y = -1 else n.y = 1 end
|
||||||
|
elseif node.name == "default:glass" then
|
||||||
|
if bpos.y<0 then n.y = -1 else n.y = 1 end
|
||||||
|
elseif node.name == "default:wood" then
|
||||||
|
if bpos.z<0 then n.z = -1 else n.z = 1 end
|
||||||
|
n.y = 0;
|
||||||
|
elseif node.name == "default:junglewood" then
|
||||||
|
if bpos.x<0 then n.x = -1 else n.x = 1 end
|
||||||
|
n.y = 0;
|
||||||
|
end
|
||||||
|
else -- normal bounce..
|
||||||
|
|
||||||
-- try to determine exact point of entry
|
-- try to determine exact point of entry
|
||||||
local vm = math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z); if vm == 0 then vm = 1 end
|
local vm = math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z); if vm == 0 then vm = 1 end
|
||||||
local vn = {x=-v.x/vm,y=-v.y/vm, z= -v.z/vm};
|
local vn = {x=-v.x/vm,y=-v.y/vm, z= -v.z/vm};
|
||||||
@ -157,7 +173,6 @@ minetest.register_entity("basic_machines:ball",{
|
|||||||
local dpos = { x=(bpos.x-opos.x),y=(bpos.y-opos.y),z=(bpos.z-opos.z)};
|
local dpos = { x=(bpos.x-opos.x),y=(bpos.y-opos.y),z=(bpos.z-opos.z)};
|
||||||
local dposa = { x=math.abs(dpos.x),y=math.abs(dpos.y),z=math.abs(dpos.z)};
|
local dposa = { x=math.abs(dpos.x),y=math.abs(dpos.y),z=math.abs(dpos.z)};
|
||||||
local maxo = math.max(dposa.x,dposa.y,dposa.z);
|
local maxo = math.max(dposa.x,dposa.y,dposa.z);
|
||||||
local n = {x=0,y=0,z=0};
|
|
||||||
|
|
||||||
if dposa.x == maxo then
|
if dposa.x == maxo then
|
||||||
if dpos.x>0 then n.x = 1 else n.x = -1 end
|
if dpos.x>0 then n.x = 1 else n.x = -1 end
|
||||||
@ -181,6 +196,7 @@ minetest.register_entity("basic_machines:ball",{
|
|||||||
if dpos.x>0 then n.x = 1 else n.x = -1 end ; n.y = 0;
|
if dpos.x>0 then n.x = 1 else n.x = -1 end ; n.y = 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local elasticity = self.elasticity;
|
local elasticity = self.elasticity;
|
||||||
|
|
||||||
@ -236,6 +252,27 @@ minetest.register_node("basic_machines:ball_spawner", {
|
|||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
action_on = function (pos, node,ttl)
|
action_on = function (pos, node,ttl)
|
||||||
if ttl<0 then return end
|
if ttl<0 then return end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(pos);
|
||||||
|
local t0 = meta:get_int("t");
|
||||||
|
local t1 = minetest.get_gametime();
|
||||||
|
local T = meta:get_int("T"); -- temperature
|
||||||
|
|
||||||
|
if t0>t1-1 then -- activated before natural time
|
||||||
|
T=T+1;
|
||||||
|
else
|
||||||
|
if T>0 then T=T-1 end
|
||||||
|
end
|
||||||
|
meta:set_int("T",T);
|
||||||
|
meta:set_int("t",t1); -- update last activation time
|
||||||
|
|
||||||
|
if T > 2 then -- overheat
|
||||||
|
minetest.sound_play("default_cool_lava",{pos = pos, max_hear_distance = 16, gain = 0.25})
|
||||||
|
meta:set_string("infotext","overheat: temperature ".. T)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, "basic_machines:ball");
|
local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, "basic_machines:ball");
|
||||||
local luaent = obj:get_luaentity();
|
local luaent = obj:get_luaentity();
|
||||||
local meta = minetest.get_meta(pos);
|
local meta = minetest.get_meta(pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user