summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormBornand <63592189+mBornand@users.noreply.github.com>2020-05-08 11:04:07 +0200
committerGitHub <noreply@github.com>2020-05-08 11:04:07 +0200
commit1565d9b3ce8e74cdf8d2c95181f98531794f2c36 (patch)
tree09f6d9158cd2c583789d5c23bc174be115178972
parentFix SetBlockMeta call in observer handler (#4728) (diff)
downloadcuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar.gz
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar.bz2
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar.lz
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar.xz
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.tar.zst
cuberite-1565d9b3ce8e74cdf8d2c95181f98531794f2c36.zip
-rw-r--r--Server/Plugins/APIDump/Classes/Geometry.lua87
-rw-r--r--Server/Plugins/Debuggers/Debuggers.lua98
-rw-r--r--Server/Plugins/Debuggers/Info.lua7
-rw-r--r--src/Bindings/ManualBindings.cpp218
-rw-r--r--src/BlockTracer.h24
-rw-r--r--src/Entities/ProjectileEntity.cpp9
-rw-r--r--src/Items/ItemBoat.h4
-rw-r--r--src/Items/ItemBottle.h4
-rw-r--r--src/Items/ItemBucket.h14
-rw-r--r--src/Items/ItemLilypad.h8
-rw-r--r--src/LineBlockTracer.cpp141
-rw-r--r--src/LineBlockTracer.h20
12 files changed, 419 insertions, 215 deletions
diff --git a/Server/Plugins/APIDump/Classes/Geometry.lua b/Server/Plugins/APIDump/Classes/Geometry.lua
index 475cab2f2..9d289632c 100644
--- a/Server/Plugins/APIDump/Classes/Geometry.lua
+++ b/Server/Plugins/APIDump/Classes/Geometry.lua
@@ -1011,25 +1011,44 @@ the most popular tracing reasons - line of sight and solid hits.
}, -- LineOfSightTrace
Trace =
{
- IsStatic = true,
- Params =
{
- { Name = "World", Type = "cWorld" },
- { Name = "Callbacks", Type = "table" },
- { Name = "StartX", Type = "number" },
- { Name = "StartY", Type = "number" },
- { Name = "StartZ", Type = "number" },
- { Name = "EndX", Type = "number" },
- { Name = "EndY", Type = "number" },
- { Name = "EndZ", Type = "number" },
+ IsStatic = true,
+ Params =
+ {
+ { Name = "World", Type = "cWorld" },
+ { Name = "Callbacks", Type = "table" },
+ { Name = "StartX", Type = "number" },
+ { Name = "StartY", Type = "number" },
+ { Name = "StartZ", Type = "number" },
+ { Name = "EndX", Type = "number" },
+ { Name = "EndY", Type = "number" },
+ { Name = "EndZ", Type = "number" },
+ },
+ Returns =
+ {
+ {
+ Type = "boolean",
+ },
+ },
+ Notes = "(OBSOLETE, use the Vector3-based overload instead) Performs the trace on the specified line. Returns true if the entire trace was processed (no callback returned true)",
},
- Returns =
{
+ IsStatic = true,
+ Params =
{
- Type = "boolean",
+ { Name = "World", Type = "cWorld" },
+ { Name = "Callbacks", Type = "table" },
+ { Name = "Start", Type = "Vector3d" },
+ { Name = "End", Type = "Vector3d" },
},
+ Returns =
+ {
+ {
+ Type = "boolean",
+ },
+ },
+ Notes = "Performs the trace on the specified line. Returns true if the entire trace was processed (no callback returned true)",
},
- Notes = "Performs the trace on the specified line. Returns true if the entire trace was processed (no callback returned true)",
},
},
Constants =
@@ -1064,21 +1083,24 @@ The Callbacks in the Trace() function is a table that contains named functions.
individual functions from that table for the events that occur on the line - hitting a block, going out of
valid world data etc. The following table lists all the available callbacks. If the callback function is
not defined, Cuberite skips it. Each function can return a bool value, if it returns true, the tracing is
-aborted and Trace() returns false.</p>
+aborted and Trace() returns false.<br>
+Note: The folowing can only be used when using the Vector3-based Trace() function. When using
+the number-based overload, the callbacks receive number-based coordinates (see Deprecated
+Callbacks below).</p>
<p>
<table><tr><th>Name</th><th>Parameters</th><th>Notes</th></tr>
-<tr><td>OnNextBlock</td><td>BlockX, BlockY, BlockZ, BlockType, BlockMeta, EntryFace</td>
+<tr><td>OnNextBlock</td><td>BlockPos, BlockType, BlockMeta, EntryFace</td>
<td>Called when the ray hits a new valid block. The block type and meta is given. EntryFace is one of the
BLOCK_FACE_ constants indicating which "side" of the block got hit by the ray.</td></tr>
-<tr><td>OnNextBlockNoData</td><td>BlockX, BlockY, BlockZ, EntryFace</td>
+<tr><td>OnNextBlockNoData</td><td>BlockPos, EntryFace</td>
<td>Called when the ray hits a new block, but the block is in an unloaded chunk - no valid data is
available. Only the coords and the entry face are given.</td></tr>
-<tr><td>OnOutOfWorld</td><td>X, Y, Z</td>
+<tr><td>OnOutOfWorld</td><td>BlockPos</td>
<td>Called when the ray goes outside of the world (Y-wise); the coords specify the exact exit point. Note
that for other paths than lines (considered for future implementations) the path may leave the world and
go back in again later, in such a case this callback is followed by OnIntoWorld() and further
OnNextBlock() calls.</td></tr>
-<tr><td>OnIntoWorld</td><td>X, Y, Z</td>
+<tr><td>OnIntoWorld</td><td>BlockPos</td>
<td>Called when the ray enters the world (Y-wise); the coords specify the exact entry point.</td></tr>
<tr><td>OnNoMoreHits</td><td>&nbsp;</td>
<td>Called when the path is sure not to hit any more blocks. This is the final callback, no more
@@ -1091,6 +1113,29 @@ aborted and Trace() returns false.</p>
]],
},
{
+ Header = "Deprecated Callbacks",
+ Contents = [[
+When using the deprecated number-based Trace function, Cuberite will instead assume the following signatures for the callbacks:</p>
+<p>
+<table><tr><th>Name</th><th>Parameters</th><th>Notes</th></tr>
+<tr><td>OnNextBlock</td><td>BlockX, BlockY, BlockZ, BlockType, BlockMeta, EntryFace</td>
+ <td>Called when the ray hits a new valid block. The block type and meta is given. EntryFace is one of the
+ BLOCK_FACE_ constants indicating which "side" of the block got hit by the ray.</td></tr>
+<tr><td>OnNextBlockNoData</td><td>BlockX, BlockY, BlockZ, EntryFace</td>
+ <td>Called when the ray hits a new block, but the block is in an unloaded chunk - no valid data is
+ available. Only the coords and the entry face are given.</td></tr>
+<tr><td>OnOutOfWorld</td><td>X, Y, Z</td>
+ <td>Called when the ray goes outside of the world (Y-wise); the coords specify the exact exit point. Note
+ that for other paths than lines (considered for future implementations) the path may leave the world and
+ go back in again later, in such a case this callback is followed by OnIntoWorld() and further
+ OnNextBlock() calls.</td></tr>
+<tr><td>OnIntoWorld</td><td>X, Y, Z</td>
+ <td>Called when the ray enters the world (Y-wise); the coords specify the exact entry point.</td></tr>
+</table>
+
+ ]],
+ },
+ {
Header = "Example",
Contents = [[
<p>The following example is taken from the Debuggers plugin. It is a command handler function for the
@@ -1101,12 +1146,12 @@ function HandleSpideyCmd(a_Split, a_Player)
local World = a_Player:GetWorld();
local Callbacks = {
- OnNextBlock = function(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta)
+ OnNextBlock = function(a_BlockPos, a_BlockType, a_BlockMeta)
if (a_BlockType ~= E_BLOCK_AIR) then
-- abort the trace
return true;
end
- World:SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_COBWEB, 0);
+ World:SetBlock(a_BlockPos, E_BLOCK_COBWEB, 0);
end
};
@@ -1118,7 +1163,7 @@ function HandleSpideyCmd(a_Split, a_Player)
local Start = EyePos + LookVector + LookVector;
local End = EyePos + LookVector * 50;
- cLineBlockTracer.Trace(World, Callbacks, Start.x, Start.y, Start.z, End.x, End.y, End.z);
+ cLineBlockTracer.Trace(World, Callbacks, Start, End);
return true;
end
diff --git a/Server/Plugins/Debuggers/Debuggers.lua b/Server/Plugins/Debuggers/Debuggers.lua
index 5f04d12ee..585b2e1cc 100644
--- a/Server/Plugins/Debuggers/Debuggers.lua
+++ b/Server/Plugins/Debuggers/Debuggers.lua
@@ -1178,12 +1178,12 @@ function HandleSpideyCmd(a_Split, a_Player)
local World = a_Player:GetWorld();
local Callbacks = {
- OnNextBlock = function(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta)
+ OnNextBlock = function(a_BlockPos, a_BlockType, a_BlockMeta)
if (a_BlockType ~= E_BLOCK_AIR) then
-- abort the trace
return true;
end
- World:SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_COBWEB, 0);
+ World:SetBlock(a_BlockPos, E_BLOCK_COBWEB, 0);
end
};
@@ -1195,7 +1195,7 @@ function HandleSpideyCmd(a_Split, a_Player)
local Start = EyePos + LookVector + LookVector;
local End = EyePos + LookVector * 50;
- cLineBlockTracer.Trace(World, Callbacks, Start.x, Start.y, Start.z, End.x, End.y, End.z);
+ cLineBlockTracer.Trace(World, Callbacks, Start, End);
return true;
end
@@ -2424,6 +2424,89 @@ function HandleConsoleTestTracer(a_Split, a_EntireCmd)
-- Define the callbacks to use for tracing:
local Callbacks =
{
+ OnNextBlock = function(a_BlockPos, a_BlockType, a_BlockMeta, a_EntryFace)
+ LOG(string.format("{%d, %d, %d}: %s", a_Block.x, a_Block.y, a_Block.z, ItemToString(cItem(a_BlockType, 1, a_BlockMeta))))
+ end,
+ OnNextBlockNoData = function(a_BlockPos, a_EntryFace)
+ LOG(string.format("{%d, %d, %d} (no data)", a_Block.x, a_Block.y, a_Block.z))
+ end,
+ OnNoChunk = function()
+ LOG("Chunk not loaded")
+ end,
+ OnNoMoreHits = function()
+ LOG("Trace finished")
+ end,
+ OnOutOfWorld = function()
+ LOG("Out of world")
+ end,
+ OnIntoWorld = function()
+ LOG("Into world")
+ end,
+ }
+
+ -- Approximate the chunks needed for the trace by iterating over all chunks and measuring their center's distance from the traced line
+ local Chunks = {}
+ local sx = math.floor(Coords[1] / 16)
+ local sz = math.floor(Coords[3] / 16)
+ local ex = math.floor(Coords[4] / 16)
+ local ez = math.floor(Coords[6] / 16)
+ local sgnx = (sx < ex) and 1 or -1
+ local sgnz = (sz < ez) and 1 or -1
+ for z = sz, ez, sgnz do
+ local ChunkCenterZ = z * 16 + 8
+ for x = sx, ex, sgnx do
+ local ChunkCenterX = x * 16 + 8
+ local sqdist = SqDistPtFromLine(ChunkCenterX, ChunkCenterZ, Coords[1], Coords[3], Coords[4], Coords[6])
+ if (sqdist <= 128) then
+ table.insert(Chunks, {x, z})
+ end
+ end
+ end
+
+ -- Load the chunks and do the trace once loaded:
+ local startPos = Vector3i(Coords[1], Coords[2], Coords[3])
+ local endPos = Vector3i(Coords[4], Coords[5], Coords[6])
+ World:ChunkStay(Chunks,
+ nil,
+ function()
+ cLineBlockTracer:Trace(World, Callbacks, startPos, endPos)
+ end
+ )
+ return true
+end
+
+
+
+
+
+function HandleConsoleTestTracerDeprecated(a_Split, a_EntireCmd)
+ -- Check required params:
+ if not(a_Split[7]) then
+ return true, "Usage: " .. a_Split[1] .. " <x1> <y1> <z1> <x2> <y2> <z2> [<WorldName>]"
+ end
+ local Coords = {}
+ for i = 1, 6 do
+ local v = tonumber(a_Split[i + 1])
+ if not(v) then
+ return true, "Parameter " .. (i + 1) .. " (" .. tostring(a_Split[i + 1]) .. ") not a number "
+ end
+ Coords[i] = v
+ end
+
+ -- Get the world in which to test:
+ local World
+ if (a_Split[8]) then
+ World = cRoot:GetWorld(a_Split[2])
+ else
+ World = cRoot:Get():GetDefaultWorld()
+ end
+ if not(World) then
+ return true, "No such world"
+ end
+
+ -- Define the callbacks to use for tracing:
+ local Callbacks =
+ {
OnNextBlock = function(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_EntryFace)
LOG(string.format("{%d, %d, %d}: %s", a_BlockX, a_BlockY, a_BlockZ, ItemToString(cItem(a_BlockType, 1, a_BlockMeta))))
end,
@@ -2716,9 +2799,9 @@ function HandleBlkCmd(a_Split, a_Player)
local World = a_Player:GetWorld();
local Callbacks = {
- OnNextBlock = function(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta)
+ OnNextBlock = function(a_BlockPos, a_BlockType, a_BlockMeta)
if (a_BlockType ~= E_BLOCK_AIR) then
- a_Player:SendMessage("Block at " .. a_BlockX .. ", " .. a_BlockY .. ", " .. a_BlockZ .. " is " .. a_BlockType .. ":" .. a_BlockMeta)
+ a_Player:SendMessage("Block at " .. a_BlockPos.x .. ", " .. a_BlockPos.y .. ", " .. a_BlockPos.z .. " is " .. a_BlockType .. ":" .. a_BlockMeta)
return true;
end
end
@@ -2730,7 +2813,7 @@ function HandleBlkCmd(a_Split, a_Player)
local End = EyePos + LookVector * 50;
- cLineBlockTracer.Trace(World, Callbacks, EyePos.x, EyePos.y, EyePos.z, End.x, End.y, End.z);
+ cLineBlockTracer.Trace(World, Callbacks, EyePos, End);
return true;
end
@@ -2760,6 +2843,3 @@ function HandleTeamsCmd(a_Split, a_Player)
end
-
-
-
diff --git a/Server/Plugins/Debuggers/Info.lua b/Server/Plugins/Debuggers/Info.lua
index 6fbd90e58..6e81296aa 100644
--- a/Server/Plugins/Debuggers/Info.lua
+++ b/Server/Plugins/Debuggers/Info.lua
@@ -392,6 +392,12 @@ g_PluginInfo =
HelpString = "Tests the cLineBlockTracer",
},
+ ["testtracerdeprecated"] =
+ {
+ Handler = HandleConsoleTestTracerDeprecated,
+ HelpString = "Tests the cLineBlockTracer's deprecated API",
+ },
+
["testurlclient"] =
{
Handler = HandleConsoleTestUrlClient,
@@ -414,4 +420,3 @@ g_PluginInfo =
-
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index 9909b233a..0713ec49b 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -2823,64 +2823,67 @@ public:
{
}
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
bool res = false;
- if (!m_Callbacks->CallTableFn(
+ if (m_Callbacks->CallTableFn(
"OnNextBlock",
- a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_EntryFace,
- cLuaState::Return, res
- ))
+ a_BlockPos,
+ a_BlockType,
+ a_BlockMeta,
+ a_EntryFace,
+ cLuaState::Return, res)
+ )
{
- // No such function in the table, skip the callback
- return false;
+ return res;
}
- return res;
+ // No such function in the table, skip the callback
+ return false;
}
- virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace) override
+ virtual bool OnNextBlockNoData(Vector3i a_BlockPos, char a_EntryFace) override
{
bool res = false;
- if (!m_Callbacks->CallTableFn(
+ if (m_Callbacks->CallTableFn(
"OnNextBlockNoData",
- a_BlockX, a_BlockY, a_BlockZ, a_EntryFace,
- cLuaState::Return, res
- ))
+ a_BlockPos,
+ a_EntryFace,
+ cLuaState::Return, res)
+ )
{
- // No such function in the table, skip the callback
- return false;
+ return res;
}
- return res;
+ // No such function in the table, skip the callback
+ return false;
}
- virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override
+ virtual bool OnOutOfWorld(Vector3d a_BlockPos) override
{
bool res = false;
- if (!m_Callbacks->CallTableFn(
+ if (m_Callbacks->CallTableFn(
"OnOutOfWorld",
- a_BlockX, a_BlockY, a_BlockZ,
- cLuaState::Return, res
- ))
+ a_BlockPos,
+ cLuaState::Return, res)
+ )
{
- // No such function in the table, skip the callback
- return false;
+ return res;
}
- return res;
+ // No such function in the table, skip the callback
+ return false;
}
- virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override
+ virtual bool OnIntoWorld(Vector3d a_BlockPos) override
{
bool res = false;
- if (!m_Callbacks->CallTableFn(
- "OnIntoWorld",
- a_BlockX, a_BlockY, a_BlockZ,
- cLuaState::Return, res
- ))
+ if (m_Callbacks->CallTableFn("OnIntoWorld",
+ a_BlockPos,
+ cLuaState::Return, res)
+ )
{
- // No such function in the table, skip the callback
- return false;
+ return res;
}
- return res;
+ // No such function in the table, skip the callback
+ return false;
}
virtual void OnNoMoreHits(void) override
@@ -2895,7 +2898,88 @@ public:
protected:
cLuaState::cTableRefPtr m_Callbacks;
-} ;
+};
+
+
+
+
+
+/** Provides interface between a Lua table of callbacks and the cBlockTracer::cCallbacks
+This is the deprecated version of cLuaBlockTracerCallback, used when the plugin calls
+the Trace function with number-based coords. */
+class cLuaBlockTracerCallbacksOld :
+ public cLuaBlockTracerCallbacks
+{
+public:
+ cLuaBlockTracerCallbacksOld(cLuaState::cTableRefPtr && a_Callbacks):
+ cLuaBlockTracerCallbacks(std::move(a_Callbacks))
+ {
+ }
+
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ {
+ bool res = false;
+ if (m_Callbacks->CallTableFn(
+ "OnNextBlock",
+ a_BlockPos.x, a_BlockPos.y, a_BlockPos.z,
+ a_BlockType,
+ a_BlockMeta,
+ a_EntryFace,
+ cLuaState::Return, res)
+ )
+ {
+ return res;
+ }
+ // No such function in the table, skip the callback
+ return false;
+ }
+
+ virtual bool OnNextBlockNoData(Vector3i a_BlockPos, char a_EntryFace) override
+ {
+ bool res = false;
+ if (m_Callbacks->CallTableFn(
+ "OnNextBlockNoData",
+ a_BlockPos.x, a_BlockPos.y, a_BlockPos.z,
+ a_EntryFace,
+ cLuaState::Return, res)
+ )
+ {
+ return res;
+ }
+ // No such function in the table, skip the callback
+ return false;
+ }
+
+ virtual bool OnOutOfWorld(Vector3d a_BlockPos) override
+ {
+ bool res = false;
+ if (m_Callbacks->CallTableFn(
+ "OnOutOfWorld",
+ a_BlockPos.x, a_BlockPos.y, a_BlockPos.z,
+ cLuaState::Return, res)
+ )
+ {
+ return res;
+ }
+ // No such function in the table, skip the callback
+ return false;
+ }
+
+ virtual bool OnIntoWorld(Vector3d a_BlockPos) override
+ {
+ bool res = false;
+ if (m_Callbacks->CallTableFn(
+ "OnIntoWorld",
+ a_BlockPos.x, a_BlockPos.y, a_BlockPos.z,
+ cLuaState::Return, res)
+ )
+ {
+ return res;
+ }
+ // No such function in the table, skip the callback
+ return false;
+ }
+};
@@ -3100,8 +3184,10 @@ static int tolua_cLineBlockTracer_LineOfSightTrace(lua_State * tolua_S)
static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S)
{
/* Supported function signatures:
- cLineBlockTracer:Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) // Canonical
- cLineBlockTracer.Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ)
+ cLineBlockTracer:Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) // Canonical // DEPRECATED
+ cLineBlockTracer.Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) // DEPRECATED
+ cLineBlockTracer:Trace(World, Callbacks, Start, End) // Canonical
+ cLineBlockTracer.Trace(World, Callbacks, Start, End)
*/
// If the first param is the cLineBlockTracer class, shift param index by one:
@@ -3116,9 +3202,7 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S)
cLuaState L(tolua_S);
if (
!L.CheckParamUserType(idx, "cWorld") ||
- !L.CheckParamTable (idx + 1) ||
- !L.CheckParamNumber (idx + 2, idx + 7) ||
- !L.CheckParamEnd (idx + 8)
+ !L.CheckParamTable (idx + 1)
)
{
return 0;
@@ -3126,22 +3210,54 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S)
// Get the params:
cWorld * world;
- double startX, startY, startZ;
- double endX, endY, endZ;
+ Vector3d start;
+ Vector3d end;
cLuaState::cTableRefPtr callbacks;
- if (!L.GetStackValues(idx, world, callbacks, startX, startY, startZ, endX, endY, endZ))
+ if (
+ L.IsParamNumber (idx + 2) &&
+ L.IsParamNumber (idx + 3) &&
+ L.IsParamNumber (idx + 4) &&
+ L.IsParamNumber (idx + 5) &&
+ L.IsParamNumber (idx + 6) &&
+ L.IsParamNumber (idx + 7) &&
+ L.CheckParamEnd (idx + 8)
+ )
{
- LOGWARNING("cLineBlockTracer:Trace(): Cannot read parameters (starting at idx %d), aborting the trace.", idx);
+ if (!L.GetStackValues(idx, world, callbacks, start.x, start.y, start.z, end.x, end.y, end.z))
+ {
+ LOGWARNING("cLineBlockTracer:Trace(): Cannot read parameters (starting at idx %d), aborting the trace.", idx);
+ L.LogStackTrace();
+ L.LogStackValues("Values on the stack");
+ return 0;
+ }
+ LOGWARNING("cLineBlockTracer:Trace(): Using plain numbers is deprecated, use Vector3 coords instead.");
L.LogStackTrace();
- L.LogStackValues("Values on the stack");
- return 0;
+ // Trace:
+ cLuaBlockTracerCallbacksOld tracerCallbacks(std::move(callbacks));
+ bool res = cLineBlockTracer::Trace(*world, tracerCallbacks, start, end);
+ tolua_pushboolean(L, res ? 1 : 0);
+ return 1;
}
-
- // Trace:
- cLuaBlockTracerCallbacks tracerCallbacks(std::move(callbacks));
- bool res = cLineBlockTracer::Trace(*world, tracerCallbacks, startX, startY, startZ, endX, endY, endZ);
- tolua_pushboolean(L, res ? 1 : 0);
- return 1;
+ else if (
+ L.IsParamVector3(idx + 2) &&
+ L.IsParamVector3(idx + 3) &&
+ L.CheckParamEnd (idx + 4)
+ )
+ {
+ if (!L.GetStackValues(idx, world, callbacks, start, end))
+ {
+ LOGWARNING("cLineBlockTracer:Trace(): Cannot read parameters (starting at idx %d), aborting the trace.", idx);
+ L.LogStackTrace();
+ L.LogStackValues("Values on the stack");
+ return 0;
+ }
+ // Trace:
+ cLuaBlockTracerCallbacks tracerCallbacks(std::move(callbacks));
+ bool res = cLineBlockTracer::Trace(*world, tracerCallbacks, start, end);
+ tolua_pushboolean(L, res ? 1 : 0);
+ return 1;
+ }
+ return L.ApiParamError("Invalid overload of cLineBlockTracer:Trace()");
}
diff --git a/src/BlockTracer.h b/src/BlockTracer.h
index 2cb97c569..46b588771 100644
--- a/src/BlockTracer.h
+++ b/src/BlockTracer.h
@@ -40,45 +40,39 @@ public:
/** Called on each block encountered along the path, including the first block (path start)
When this callback returns true, the tracing is aborted.
*/
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) = 0;
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) = 0;
/** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded
When this callback returns true, the tracing is aborted.
*/
- virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace)
+ virtual bool OnNextBlockNoData(Vector3i a_BlockPos, char a_EntryFace)
{
- UNUSED(a_BlockX);
- UNUSED(a_BlockY);
- UNUSED(a_BlockZ);
+ UNUSED(a_BlockPos);
UNUSED(a_EntryFace);
return false;
}
- /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height)
+ /** Called when the path goes out of world, either below (a_BlockPos.y < 0) or above (a_BlockPos.y >= cChunkDef::Height)
The coords specify the exact point at which the path exited the world.
If this callback returns true, the tracing is aborted.
Note that some paths can go out of the world and come back again (parabola),
in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls
*/
- virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ)
+ virtual bool OnOutOfWorld(Vector3d a_BlockPos)
{
- UNUSED(a_BlockX);
- UNUSED(a_BlockY);
- UNUSED(a_BlockZ);
+ UNUSED(a_BlockPos);
return false;
}
- /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height)
+ /** Called when the path goes into the world, from either below (a_BlockPos.y < 0) or above (a_BlockPos.y >= cChunkDef::Height)
The coords specify the exact point at which the path entered the world.
If this callback returns true, the tracing is aborted.
Note that some paths can go out of the world and come back again (parabola),
in such a case this callback is followed by further OnNextBlock() calls
*/
- virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ)
+ virtual bool OnIntoWorld(Vector3d a_BlockPos)
{
- UNUSED(a_BlockX);
- UNUSED(a_BlockY);
- UNUSED(a_BlockZ);
+ UNUSED(a_BlockPos);
return false;
}
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index fa0654ca5..a8ba83b5d 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -50,7 +50,7 @@ protected:
double m_SlowdownCoeff;
// cCallbacks overrides:
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
/*
// DEBUG:
@@ -65,7 +65,7 @@ protected:
if (cBlockInfo::IsSolid(a_BlockType))
{
// The projectile hit a solid block, calculate the exact hit coords:
- cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); // Bounding box of the block hit
+ cBoundingBox bb(a_BlockPos, a_BlockPos + Vector3i(1, 1, 1)); // Bounding box of the block hit
const Vector3d LineStart = m_Projectile->GetPosition(); // Start point for the imaginary line that goes through the block hit
const Vector3d LineEnd = LineStart + m_Projectile->GetSpeed(); // End point for the imaginary line that goes through the block hit
double LineCoeff = 0; // Used to calculate where along the line an intersection with the bounding box occurs
@@ -75,7 +75,7 @@ protected:
{
Vector3d Intersection = LineStart + m_Projectile->GetSpeed() * LineCoeff; // Point where projectile goes into the hit block
- if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, Intersection))
+ if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, Face, Intersection))
{
return false;
}
@@ -455,6 +455,3 @@ void cProjectileEntity::CollectedBy(cPlayer & a_Dest)
UNUSED(a_Dest);
}
-
-
-
diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h
index b6af554c5..d6e9ed7c3 100644
--- a/src/Items/ItemBoat.h
+++ b/src/Items/ItemBoat.h
@@ -52,11 +52,11 @@ public:
{
}
- virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
+ virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
{
if (a_CBBlockType != E_BLOCK_AIR)
{
- m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
+ m_Pos = a_CBBlockPos;
m_HasFound = true;
return true;
}
diff --git a/src/Items/ItemBottle.h b/src/Items/ItemBottle.h
index 2f4d8f93f..84950de29 100644
--- a/src/Items/ItemBottle.h
+++ b/src/Items/ItemBottle.h
@@ -43,7 +43,7 @@ public:
{
}
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
if (IsBlockWater(a_BlockType))
{
@@ -52,7 +52,7 @@ public:
return false;
}
m_HasHitFluid = true;
- m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
+ m_Pos = a_BlockPosition;
return true;
}
return false;
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index d2a9b1884..7e1e2c07f 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -197,7 +197,7 @@ public:
{
}
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType))
{
@@ -206,7 +206,7 @@ public:
return false;
}
m_HasHitFluid = true;
- m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
+ m_Pos = a_BlockPosition;
return true;
}
return false;
@@ -217,7 +217,7 @@ public:
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
- Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
+ Tracer.Trace(Start, End);
if (!Callbacks.m_HasHitFluid)
{
@@ -244,7 +244,7 @@ public:
NIBBLETYPE m_ReplacedBlockMeta;
eBlockFace m_EntryFace;
- virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
+ virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
{
if ((a_CBBlockType != E_BLOCK_AIR) && !IsBlockLiquid(a_CBBlockType))
{
@@ -253,9 +253,9 @@ public:
m_EntryFace = static_cast<eBlockFace>(a_CBEntryFace);
if (!cFluidSimulator::CanWashAway(a_CBBlockType))
{
- AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, a_CBEntryFace); // Was an unwashawayable block, can't overwrite it!
+ a_CBBlockPos = AddFaceDirection(a_CBBlockPos, a_CBEntryFace); // Was an unwashawayable block, can't overwrite it!
}
- m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ); // (Block could be washed away, replace it)
+ m_Pos = a_CBBlockPos; // (Block could be washed away, replace it)
return true; // Abort tracing
}
return false;
@@ -269,7 +269,7 @@ public:
// cLineBlockTracer::Trace() returns true when whole line was traversed. By returning true from the callback when we hit something,
// we ensure that this never happens if liquid could be placed
// Use this to judge whether the position is valid
- if (!Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z))
+ if (!Tracer.Trace(Start, End))
{
a_BlockPos = Callbacks.m_Pos;
a_BlockType = Callbacks.m_ReplacedBlockType;
diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h
index 1190e817b..747175811 100644
--- a/src/Items/ItemLilypad.h
+++ b/src/Items/ItemLilypad.h
@@ -66,7 +66,7 @@ public:
{
}
- virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
+ virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
{
if (IsBlockWater(a_CBBlockType))
{
@@ -74,7 +74,7 @@ public:
{
return false;
}
- AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, BLOCK_FACE_YP); // Always place pad at top of water block
+ a_CBBlockPos = AddFaceDirection(a_CBBlockPos, BLOCK_FACE_YP); // Always place pad at top of water block
if (
!IsBlockWater(a_CBBlockType) &&
cBlockInfo::FullyOccupiesVoxel(a_CBBlockType)
@@ -84,7 +84,7 @@ public:
return true;
}
m_HasHitFluid = true;
- m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
+ m_Pos = a_CBBlockPos;
return true;
}
return false;
@@ -96,7 +96,7 @@ public:
} Callbacks;
auto Start = a_Player->GetEyePosition() + a_Player->GetLookVector();
auto End = a_Player->GetEyePosition() + a_Player->GetLookVector() * 5;
- cLineBlockTracer::Trace(*a_Player->GetWorld(), Callbacks, Start.x, Start.y, Start.z, End.x, End.y, End.z);
+ cLineBlockTracer::Trace(*a_Player->GetWorld(), Callbacks, Start, End);
if (Callbacks.m_HasHitFluid)
{
diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp
index 0b3dcf1f3..6160f8485 100644
--- a/src/LineBlockTracer.cpp
+++ b/src/LineBlockTracer.cpp
@@ -16,21 +16,11 @@
cLineBlockTracer::cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) :
Super(a_World, a_Callbacks),
- m_StartX(0.0),
- m_StartY(0.0),
- m_StartZ(0.0),
- m_EndX(0.0),
- m_EndY(0.0),
- m_EndZ(0.0),
- m_DiffX(0.0),
- m_DiffY(0.0),
- m_DiffZ(0.0),
- m_DirX(0),
- m_DirY(0),
- m_DirZ(0),
- m_CurrentX(0),
- m_CurrentY(0),
- m_CurrentZ(0),
+ m_Start(),
+ m_End(),
+ m_Diff(),
+ m_Dir(),
+ m_Current(),
m_CurrentFace(BLOCK_FACE_NONE)
{
}
@@ -39,10 +29,10 @@ cLineBlockTracer::cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) :
-bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End)
+bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks & a_Callbacks, const Vector3d a_Start, const Vector3d a_End)
{
cLineBlockTracer Tracer(a_World, a_Callbacks);
- return Tracer.Trace(a_Start.x, a_Start.y, a_Start.z, a_End.x, a_End.y, a_End.z);
+ return Tracer.Trace(a_Start, a_End);
}
@@ -64,7 +54,7 @@ bool cLineBlockTracer::LineOfSightTrace(cWorld & a_World, const Vector3d & a_Sta
m_IsLavaOpaque(a_IsLavaOpaque)
{}
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
switch (a_BlockType)
{
@@ -108,7 +98,7 @@ bool cLineBlockTracer::FirstSolidHitTrace(
{
}
- virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
+ virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
if (!cBlockInfo::IsSolid(a_BlockType))
{
@@ -116,9 +106,9 @@ bool cLineBlockTracer::FirstSolidHitTrace(
}
// We hit a solid block, calculate the exact hit coords and abort trace:
- m_HitBlockCoords.Set(a_BlockX, a_BlockY, a_BlockZ);
+ m_HitBlockCoords = a_BlockPos;
m_HitBlockFace = a_EntryFace;
- cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); // Bounding box of the block hit
+ cBoundingBox bb(a_BlockPos, a_BlockPos + Vector3i(1, 1, 1)); // Bounding box of the block hit
double LineCoeff = 0; // Used to calculate where along the line an intersection with the bounding box occurs
eBlockFace Face; // Face hit
if (!bb.CalcLineIntersection(m_Start, m_End, LineCoeff, Face))
@@ -144,64 +134,46 @@ bool cLineBlockTracer::FirstSolidHitTrace(
-bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks &a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ)
-{
- cLineBlockTracer Tracer(a_World, a_Callbacks);
- return Tracer.Trace(a_StartX, a_StartY, a_StartZ, a_EndX, a_EndY, a_EndZ);
-}
-
-
-
-
-
-bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ)
+bool cLineBlockTracer::Trace(const Vector3d a_Start, const Vector3d a_End)
{
// Initialize the member veriables:
- m_StartX = a_StartX;
- m_StartY = a_StartY;
- m_StartZ = a_StartZ;
- m_EndX = a_EndX;
- m_EndY = a_EndY;
- m_EndZ = a_EndZ;
- m_DirX = (m_StartX < m_EndX) ? 1 : -1;
- m_DirY = (m_StartY < m_EndY) ? 1 : -1;
- m_DirZ = (m_StartZ < m_EndZ) ? 1 : -1;
+ m_Start = a_Start;
+ m_End = a_End;
+ m_Dir.x = (m_Start.x < m_End.x) ? 1 : -1;
+ m_Dir.y = (m_Start.y < m_End.y) ? 1 : -1;
+ m_Dir.z = (m_Start.z < m_End.z) ? 1 : -1;
m_CurrentFace = BLOCK_FACE_NONE;
// Check the start coords, adjust into the world:
- if (m_StartY < 0)
+ if (m_Start.y < 0)
{
- if (m_EndY < 0)
+ if (m_End.y < 0)
{
// Nothing to trace
m_Callbacks->OnNoMoreHits();
return true;
}
FixStartBelowWorld();
- m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ);
+ m_Callbacks->OnIntoWorld(m_Start);
}
- else if (m_StartY >= cChunkDef::Height)
+ else if (m_Start.y >= cChunkDef::Height)
{
- if (m_EndY >= cChunkDef::Height)
+ if (m_End.y >= cChunkDef::Height)
{
m_Callbacks->OnNoMoreHits();
return true;
}
FixStartAboveWorld();
- m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ);
+ m_Callbacks->OnIntoWorld(m_Start);
}
- m_CurrentX = FloorC(m_StartX);
- m_CurrentY = FloorC(m_StartY);
- m_CurrentZ = FloorC(m_StartZ);
+ m_Current = m_Start.Floor();
- m_DiffX = m_EndX - m_StartX;
- m_DiffY = m_EndY - m_StartY;
- m_DiffZ = m_EndZ - m_StartZ;
+ m_Diff = m_End - m_Start;
// The actual trace is handled with ChunkMapCS locked by calling our ChunkCallback for the specified chunk
- int BlockX = FloorC(m_StartX);
- int BlockZ = FloorC(m_StartZ);
+ int BlockX = FloorC(m_Start.x);
+ int BlockZ = FloorC(m_Start.z);
int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
return m_World->DoWithChunk(ChunkX, ChunkZ, [this](cChunk & a_Chunk) { return ChunkCallback(&a_Chunk); });
@@ -216,8 +188,8 @@ void cLineBlockTracer::FixStartAboveWorld(void)
// We must set the start Y to less than cChunkDef::Height so that it is considered inside the world later on
// Therefore we use an EPS-offset from the height, as small as reasonably possible.
const double Height = static_cast<double>(cChunkDef::Height) - 0.00001;
- CalcXZIntersection(Height, m_StartX, m_StartZ);
- m_StartY = Height;
+ CalcXZIntersection(Height, m_Start.x, m_Start.z);
+ m_Start.y = Height;
}
@@ -226,8 +198,8 @@ void cLineBlockTracer::FixStartAboveWorld(void)
void cLineBlockTracer::FixStartBelowWorld(void)
{
- CalcXZIntersection(0, m_StartX, m_StartZ);
- m_StartY = 0;
+ CalcXZIntersection(0, m_Start.x, m_Start.z);
+ m_Start.y = 0;
}
@@ -236,9 +208,9 @@ void cLineBlockTracer::FixStartBelowWorld(void)
void cLineBlockTracer::CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ)
{
- double Ratio = (m_StartY - a_Y) / (m_StartY - m_EndY);
- a_IntersectX = m_StartX + (m_EndX - m_StartX) * Ratio;
- a_IntersectZ = m_StartZ + (m_EndZ - m_StartZ) * Ratio;
+ double Ratio = (m_Start.y - a_Y) / (m_Start.y - m_End.y);
+ a_IntersectX = m_Start.x + (m_End.x - m_Start.x) * Ratio;
+ a_IntersectZ = m_Start.z + (m_End.z - m_Start.z) * Ratio;
}
@@ -259,10 +231,10 @@ bool cLineBlockTracer::MoveToNextBlock(void)
// Calculate the next YZ wall hit:
double Coeff = 1;
- if (std::abs(m_DiffX) > EPS)
+ if (std::abs(m_Diff.x) > EPS)
{
- double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX;
- double CoeffX = (DestX - m_StartX) / m_DiffX;
+ double DestX = (m_Dir.x > 0) ? (m_Current.x + 1) : m_Current.x;
+ double CoeffX = (DestX - m_Start.x) / m_Diff.x;
if (CoeffX <= 1) // We need to include equality for the last block in the trace
{
Coeff = CoeffX;
@@ -271,10 +243,10 @@ bool cLineBlockTracer::MoveToNextBlock(void)
}
// If the next XZ wall hit is closer, use it instead:
- if (std::abs(m_DiffY) > EPS)
+ if (std::abs(m_Diff.y) > EPS)
{
- double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY;
- double CoeffY = (DestY - m_StartY) / m_DiffY;
+ double DestY = (m_Dir.y > 0) ? (m_Current.y + 1) : m_Current.y;
+ double CoeffY = (DestY - m_Start.y) / m_Diff.y;
if (CoeffY <= Coeff) // We need to include equality for the last block in the trace
{
Coeff = CoeffY;
@@ -283,10 +255,10 @@ bool cLineBlockTracer::MoveToNextBlock(void)
}
// If the next XY wall hit is closer, use it instead:
- if (std::abs(m_DiffZ) > EPS)
+ if (std::abs(m_Diff.z) > EPS)
{
- double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ;
- double CoeffZ = (DestZ - m_StartZ) / m_DiffZ;
+ double DestZ = (m_Dir.z > 0) ? (m_Current.z + 1) : m_Current.z;
+ double CoeffZ = (DestZ - m_Start.z) / m_Diff.z;
if (CoeffZ <= Coeff) // We need to include equality for the last block in the trace
{
Direction = dirZ;
@@ -296,9 +268,9 @@ bool cLineBlockTracer::MoveToNextBlock(void)
// Based on the wall hit, adjust the current coords
switch (Direction)
{
- case dirX: m_CurrentX += m_DirX; m_CurrentFace = (m_DirX > 0) ? BLOCK_FACE_XM : BLOCK_FACE_XP; break;
- case dirY: m_CurrentY += m_DirY; m_CurrentFace = (m_DirY > 0) ? BLOCK_FACE_YM : BLOCK_FACE_YP; break;
- case dirZ: m_CurrentZ += m_DirZ; m_CurrentFace = (m_DirZ > 0) ? BLOCK_FACE_ZM : BLOCK_FACE_ZP; break;
+ case dirX: m_Current.x += m_Dir.x; m_CurrentFace = (m_Dir.x > 0) ? BLOCK_FACE_XM : BLOCK_FACE_XP; break;
+ case dirY: m_Current.y += m_Dir.y; m_CurrentFace = (m_Dir.y > 0) ? BLOCK_FACE_YM : BLOCK_FACE_YP; break;
+ case dirZ: m_Current.z += m_Dir.z; m_CurrentFace = (m_Dir.z > 0) ? BLOCK_FACE_ZM : BLOCK_FACE_ZP; break;
case dirNONE: return false;
}
return true;
@@ -310,7 +282,7 @@ bool cLineBlockTracer::MoveToNextBlock(void)
bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
{
- ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld()
+ ASSERT((m_Current.y >= 0) && (m_Current.y < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld()
// This is the actual line tracing loop.
for (;;)
@@ -330,12 +302,12 @@ bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
return true;
}
- if ((m_CurrentY < 0) || (m_CurrentY >= cChunkDef::Height))
+ if ((m_Current.y < 0) || (m_Current.y >= cChunkDef::Height))
{
// We've gone out of the world, that's the end of this trace
double IntersectX, IntersectZ;
- CalcXZIntersection(m_CurrentY, IntersectX, IntersectZ);
- if (m_Callbacks->OnOutOfWorld(IntersectX, m_CurrentY, IntersectZ))
+ CalcXZIntersection(m_Current.y, IntersectX, IntersectZ);
+ if (m_Callbacks->OnOutOfWorld({IntersectX, double(m_Current.y), IntersectZ}))
{
// The callback terminated the trace
return false;
@@ -345,7 +317,7 @@ bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
}
// Update the current chunk
- a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ);
+ a_Chunk = a_Chunk->GetNeighborChunk(m_Current.x, m_Current.z);
if (a_Chunk == nullptr)
{
m_Callbacks->OnNoChunk();
@@ -356,16 +328,16 @@ bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- int RelX = m_CurrentX - a_Chunk->GetPosX() * cChunkDef::Width;
- int RelZ = m_CurrentZ - a_Chunk->GetPosZ() * cChunkDef::Width;
- a_Chunk->GetBlockTypeMeta(RelX, m_CurrentY, RelZ, BlockType, BlockMeta);
- if (m_Callbacks->OnNextBlock(m_CurrentX, m_CurrentY, m_CurrentZ, BlockType, BlockMeta, m_CurrentFace))
+ int RelX = m_Current.x - a_Chunk->GetPosX() * cChunkDef::Width;
+ int RelZ = m_Current.z - a_Chunk->GetPosZ() * cChunkDef::Width;
+ a_Chunk->GetBlockTypeMeta(RelX, m_Current.y, RelZ, BlockType, BlockMeta);
+ if (m_Callbacks->OnNextBlock(m_Current, BlockType, BlockMeta, m_CurrentFace))
{
// The callback terminated the trace
return false;
}
}
- else if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ, m_CurrentFace))
+ else if (m_Callbacks->OnNextBlockNoData(m_Current, m_CurrentFace))
{
// The callback terminated the trace
return false;
@@ -375,4 +347,3 @@ bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
-
diff --git a/src/LineBlockTracer.h b/src/LineBlockTracer.h
index 0dca6dfcb..b1dacee20 100644
--- a/src/LineBlockTracer.h
+++ b/src/LineBlockTracer.h
@@ -45,15 +45,13 @@ public:
cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks);
/** Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) */
- bool Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ);
+ bool Trace(Vector3d a_Start, Vector3d a_End);
- // Utility functions for simple one-line usage:
- /** Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) */
- static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ);
+ // Utility functions for simple one-line usage:
/** Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) */
- static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End);
+ static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, const Vector3d a_Start, const Vector3d a_End);
/** Returns true if the two positions are within line of sight (not obscured by blocks).
a_Sight specifies which blocks are considered transparent for the trace, is an OR-combination of eLineOfSight constants. */
@@ -75,19 +73,19 @@ public:
protected:
/** The start point of the trace */
- double m_StartX, m_StartY, m_StartZ;
+ Vector3d m_Start;
/** The end point of the trace */
- double m_EndX, m_EndY, m_EndZ;
+ Vector3d m_End;
/** The difference in coords, End - Start */
- double m_DiffX, m_DiffY, m_DiffZ;
+ Vector3d m_Diff;
/** The increment at which the block coords are going from Start to End; either +1 or -1 */
- int m_DirX, m_DirY, m_DirZ;
+ Vector3i m_Dir;
/** The current block */
- int m_CurrentX, m_CurrentY, m_CurrentZ;
+ Vector3i m_Current;
/** The face through which the current block has been entered */
eBlockFace m_CurrentFace;
@@ -110,5 +108,3 @@ protected:
-
-