local LavaPlugin = {}
LavaPlugin.__index = LavaPlugin
function LavaPlugin:new()
local t = {}
setmetatable(t, LavaPlugin)
local w = Lua__cPlugin:new()
tolua.setpeer(w, t)
w:tolua__set_instance(w)
return w
end
function LavaPlugin:OnDisable()
Log( Plugin:GetName() .. " v." .. Plugin:GetVersion() .. " is shutting down..." )
end
function LavaPlugin:Initialize()
self:SetName( "Lava" )
self:SetVersion( 1 )
PluginManager = cRoot:Get():GetPluginManager()
PluginManager:AddHook( self, cPluginManager.E_PLUGIN_TICK )
PluginManager:AddHook( self, cPluginManager.E_PLUGIN_BLOCK_DIG )
PluginManager:AddHook( self, cPluginManager.E_PLUGIN_BLOCK_PLACE )
self.LavaBlocks = {};
self.LavaBlocks = {};
Log( "Initialized " .. self:GetName() .. " v." .. self:GetVersion() )
self.NumTicks = 0;
return true
end
function IsFreeForLava(block)
return block == E_BLOCK_AIR
or block == E_BLOCK_TORCH
or block == E_BLOCK_MINECART_TRACKS
or block == E_BLOCK_REDSTONE_TORCH_ON
or block == E_BLOCK_REDSTONE_TORCH_OFF;
end
function IsBurnable(block)
return block == E_BLOCK_LOG
or block == E_BLOCK_LEAVES;
end
function LavaPlugin:OnBlockPlace( PacketData, Player )
local X = PacketData.m_PosX
local Y = PacketData.m_PosY
local Z = PacketData.m_PosZ
X, Y, Z = AddDirection( X, Y, Z, PacketData.m_Direction )
local t = PacketData.m_ItemType; -- the type of item used to call the place command
Log("lava: " .. X .. "," .. Y .. "," .. Z .. " -- adding due to Place... " .. t);
local World = cRoot:Get():GetWorld();
if(t == 327) then -- lava bucket
World:SetBlock(X, Y, Z, E_BLOCK_LAVA, 0);
elseif(t == 10) then
World:SetBlock(X, Y, Z, E_BLOCK_LAVA, 0);
end
self:AddSurroundings(X, Y, Z);
self:AddBlock(X, Y, Z);
return false
end
function LavaPlugin:AddSurroundings(X, Y, Z)
local level_points = {
{X-1, Y, Z},
{X+1, Y, Z},
{X, Y, Z-1},
{X, Y, Z+1},
{X, Y+1, Z},
{X, Y-1, Z},
};
for key,val in pairs(level_points) do
self:AddBlock(val[1], val[2], val[3]);
end
end
function LavaPlugin:AddBlock(X, Y, Z)
local World = cRoot:Get():GetWorld();
local t = World:GetBlock(X, Y, Z);
if(t == E_BLOCK_LAVA or t == E_BLOCK_STATIONARY_LAVA) then
local found = false;
for key,val in pairs(self.LavaBlocks) do
if(val[1] == X and val[2] == Y and val[3] == Z) then
found = true;
Log("addblock found");
break;
end
end
end
if(not found) then
Log("addblock adding");
table.insert(self.LavaBlocks, {X, Y, Z});
end
end
function LavaPlugin:OnBlockDig( PacketData, Player )
local X = PacketData.m_PosX
local Y = PacketData.m_PosY
local Z = PacketData.m_PosZ
if(PacketData.m_Status == 3) then -- block broken
Log("lava: " .. X .. "," .. Y .. "," .. Z .. " -- adding due to dig... status is: " .. PacketData.m_Status);
self:AddSurroundings(X, Y, Z);
end
return false
end
function LavaPlugin:Tick( DeltaTime )
if( self.NumTicks < 50 ) then -- Only spread every 50 ticks, to make sure it doesnt happen too fast
self.NumTicks = self.NumTicks + 1
return
end
local debug = true;
self.NumTicks = 0
local World = cRoot:Get():GetWorld()
local OldBlocks = self.LavaBlocks;
self.LavaBlocks = {};
for key,val in pairs(OldBlocks) do
local X = val[1]
local Y = val[2]
local Z = val[3]
local t = World:GetBlock(X, Y, Z);
Log("processing: " .. X .. "," .. Y .. "," .. Z .. " -- " .. t);
if(t == E_BLOCK_LAVA) then
local isFed = false;
local f = World:GetBlockMeta(X, Y, Z);
local f2 = f;
if(f == 8) then
local t2 = World:GetBlock(X, Y+1, Z);
if(t2 == E_BLOCK_LAVA) then
isFed = true;
local t3 = World:GetBlock(X, Y-1, Z);
local f3 = World:GetBlockMeta(X, Y-1, Z);
if(t3 == E_BLOCK_LAVA and f3 == 8) then
-- I'm falling, don't spread sideways
else
f = 0;
end
end
elseif(f == 0) then
isFed = true;
else
f2 = GetMaximumLavaAround(X, Y, Z);
if(f2 < f) then
isFed = true;
end
end
if(isFed) then
Log(" isFed");
local down = World:GetBlock(X, Y-1, Z);
if(IsFreeForLava(down)) then
Log(" down");
World:SetBlock(X, Y-1, Z, E_BLOCK_LAVA, 8);
self:AddBlock(X, Y-1, Z);
else
Log(" around");
if(f == 8) then
-- I'm falling
elseif(f2+1 < f) then
World:SetBlock(X, Y, Z, E_BLOCK_LAVA, f2+1);
self:AddBlock(X, Y, Z);
elseif(f < 7) then
Log(" enough power");
local points = GetLowestPoints(X, Y, Z);
for k,v in pairs(points) do
local t2 = World:GetBlock(v[1], v[2], v[3]);
if(t2 ~= E_BLOCK_LAVA) then
if(v[2] == Y) then
World:SetBlock(v[1], v[2], v[3], E_BLOCK_LAVA, f+1);
else
World:SetBlock(v[1], v[2], v[3], E_BLOCK_LAVA, 8);
end
self:AddBlock(v[1], v[2], v[3]);
else -- is lava
local f3 = World:GetBlockMeta(v[1], v[2], v[3]);
if(f3 ~= 8 and f3 > f+1) then
self:AddBlock(v[1], v[2], v[3]);
end
end
end
end
end
else
Log(" not isFed");
World:SetBlock(X, Y, Z, E_BLOCK_AIR, 0);
self:AddSurroundings(X, Y, Z);
end
else
if(IsBurnable(down)) then
Log("Burnable");
else
Log("changed before tick, not processing none-lava");
end
end
end
end
function GetMaximumLavaAround(X, Y, Z)
local mx = 8;
local level_points = {
{X-1, Y, Z},
{X+1, Y, Z},
{X, Y, Z-1},
{X, Y, Z+1},
};
local World = cRoot:Get():GetWorld();
for key,val in pairs(level_points) do
local t = World:GetBlock(val[1], val[2], val[3]);
if(t == E_BLOCK_STATIONARY_LAVA) then
mx = 0;
break;
elseif(t == E_BLOCK_LAVA) then
local f = World:GetBlockMeta(val[1], val[2], val[3]);
if(f < mx) then
mx = f;
elseif(f == 8) then
mx = 0;
end
if(mx == 0) then
break;
end
end
end
return mx;
end
function GetLowestPoints(X, Y, Z)
local World = cRoot:Get():GetWorld()
local t = World:GetBlock(X, Y-1, Z);
local points = {};
if(IsFreeForLava(t)) then
table.insert(points, {X, Y-1, Z});
return points;
end
local lower_points = {
{X-1, Y-1, Z},
{X+1, Y-1, Z},
{X, Y-1, Z-1},
{X, Y-1, Z+1},
};
local lavaFound = false;
for key,val in pairs(lower_points) do
local t = World:GetBlock(val[1], val[2], val[3]);
local t2 = World:GetBlock(val[1], Y, val[3]);
if(IsFreeForLava(t) and IsFreeForLava(t2)) then
table.insert(points, val);
val[2] = Y;
table.insert(points, val);
elseif(t2 == E_BLOCK_LAVA and (IsFreeForLava(t) or t == E_BLOCK_LAVA)) then
lavaFound = true;
end
end
if(#points == 0 and not lavaFound) then
local level_points = {
{X-1, Y, Z},
{X+1, Y, Z},
{X, Y, Z-1},
{X, Y, Z+1},
};
for key,val in pairs(level_points) do
local t = World:GetBlock(val[1], val[2], val[3]);
if(IsFreeForLava(t) or t == E_BLOCK_LAVA) then
table.insert(points, val);
end
end
end
return points;
end
Plugin = LavaPlugin:new()
cRoot:Get():GetPluginManager():AddPlugin( Plugin )