02-23-2011, 11:20 PM
Water IS generated, but I guess it's pretty rare... the generation algorithm definitely needs some modifying.
The water plugin simply makes water flow. The messages are not errors but warnings, because it does use deprecated functions like.. each tick
Here's the water plugin edited by me, to remove some logging and fixed deprecated warnings. This is NOT written by me, but by the awesome guy that goes by with the name ker on the Ae forum http://ae-c.net/viewtopic.php?f=14&t=261
The water plugin simply makes water flow. The messages are not errors but warnings, because it does use deprecated functions like.. each tick
Here's the water plugin edited by me, to remove some logging and fixed deprecated warnings. This is NOT written by me, but by the awesome guy that goes by with the name ker on the Ae forum http://ae-c.net/viewtopic.php?f=14&t=261
Code:
local WaterPlugin = {}
WaterPlugin.__index = WaterPlugin
function WaterPlugin:new()
local t = {}
setmetatable(t, WaterPlugin)
local w = Lua__cPlugin:new()
tolua.setpeer(w, t)
w:tolua__set_instance(w)
return w
end
function WaterPlugin:OnDisable()
--Log( Plugin:GetName() .. " v." .. Plugin:GetVersion() .. " is shutting down..." )
end
function WaterPlugin:Initialize()
self:SetName( "Water" )
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.WaterBlocks = {};
self.WaterBlocks = {};
--Log( "Initialized " .. self:GetName() .. " v." .. self:GetVersion() )
self.NumTicks = 0;
return true
end
function IsFreeForWater(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 WaterPlugin: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 )
--Log("water: " .. X .. "," .. Y .. "," .. Z .. " -- adding due to Place...");
self:AddSurroundings(X, Y, Z);
return false
end
function WaterPlugin: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 WaterPlugin:AddBlock(X, Y, Z)
local World = cRoot:Get():GetWorld();
local t = World:GetBlock(X, Y, Z);
if(t == E_BLOCK_WATER or t == E_BLOCK_STATIONARY_WATER) then
local found = false;
for key,val in pairs(self.WaterBlocks) do
if(val[1] == X and val[2] == Y and val[3] == Z) then
found = true;
--Log("addblock found");
break;
end
end
if(not found) then
--Log("addblock adding");
table.insert(self.WaterBlocks, {X, Y, Z});
end
end
end
function WaterPlugin: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("water: " .. X .. "," .. Y .. "," .. Z .. " -- adding due to dig... status is: " .. PacketData.m_Status);
self:AddSurroundings(X, Y, Z);
end
return false
end
function WaterPlugin:Tick( DeltaTime )
if( self.NumTicks < 5 ) then -- Only spread every 10 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.WaterBlocks;
self.WaterBlocks = {};
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_WATER) 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_WATER) then
isFed = true;
f = 0;
end
elseif(f == 0) then
isFed = true;
else
f2 = GetMaximumWaterAround(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(IsFreeForWater(down)) then
--Log(" down");
World:SetBlock(X, Y-1, Z, E_BLOCK_WATER, 8);
self:AddBlock(X, Y-1, Z);
else
--Log(" around");
if(f2+1 < f) then
World:SetBlock(X, Y, Z, E_BLOCK_WATER, 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_WATER) then
if(v[2] == Y) then
World:SetBlock(v[1], v[2], v[3], E_BLOCK_WATER, f+1);
else
World:SetBlock(v[1], v[2], v[3], E_BLOCK_WATER, 8);
end
self:AddBlock(v[1], v[2], v[3]);
else -- is water
local f3 = World:GetBlockMeta(v[1], v[2], v[3]);
if(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
--Log("changed before tick, not processing none-water");
end
end
end
function GetMaximumWaterAround(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_WATER) then
mx = 0;
break;
elseif(t == E_BLOCK_WATER) 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 = cWorld:GetWorld()
local t = World:GetBlock(X, Y-1, Z);
local points = {};
if(IsFreeForWater(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 waterFound = 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(IsFreeForWater(t) and IsFreeForWater(t2)) then
table.insert(points, val);
val[2] = Y;
table.insert(points, val);
elseif(t2 == E_BLOCK_WATER and (IsFreeForWater(t) or t == E_BLOCK_WATER)) then
waterFound = true;
end
end
if(#points == 0 and not waterFound) 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(IsFreeForWater(t) or t == E_BLOCK_WATER) then
table.insert(points, val);
end
end
end
return points;
end
Plugin = WaterPlugin:new()
cRoot:Get():GetPluginManager():AddPlugin( Plugin )