From 1565d9b3ce8e74cdf8d2c95181f98531794f2c36 Mon Sep 17 00:00:00 2001 From: mBornand <63592189+mBornand@users.noreply.github.com> Date: Fri, 8 May 2020 11:04:07 +0200 Subject: Use Vector3 for cLineBlockTracer and cBlockTracer (#4715) * cLineBlockTracer uses Vector --- Server/Plugins/APIDump/Classes/Geometry.lua | 87 ++++++++++++++++++------- Server/Plugins/Debuggers/Debuggers.lua | 98 ++++++++++++++++++++++++++--- Server/Plugins/Debuggers/Info.lua | 7 ++- 3 files changed, 161 insertions(+), 31 deletions(-) (limited to 'Server') 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.

+aborted and Trace() returns false.
+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).

- + - + - + - +
NameParametersNotes
OnNextBlockBlockX, BlockY, BlockZ, BlockType, BlockMeta, EntryFace
OnNextBlockBlockPos, BlockType, BlockMeta, EntryFace 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.
OnNextBlockNoDataBlockX, BlockY, BlockZ, EntryFace
OnNextBlockNoDataBlockPos, EntryFace 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.
OnOutOfWorldX, Y, Z
OnOutOfWorldBlockPos 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.
OnIntoWorldX, Y, Z
OnIntoWorldBlockPos Called when the ray enters the world (Y-wise); the coords specify the exact entry point.
OnNoMoreHits  Called when the path is sure not to hit any more blocks. This is the final callback, no more @@ -1090,6 +1112,29 @@ aborted and Trace() returns false.

]], }, + { + Header = "Deprecated Callbacks", + Contents = [[ +When using the deprecated number-based Trace function, Cuberite will instead assume the following signatures for the callbacks:

+

+ + + + + + + + + +
NameParametersNotes
OnNextBlockBlockX, BlockY, BlockZ, BlockType, BlockMeta, EntryFaceCalled 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.
OnNextBlockNoDataBlockX, BlockY, BlockZ, EntryFaceCalled 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.
OnOutOfWorldX, Y, ZCalled 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.
OnIntoWorldX, Y, ZCalled when the ray enters the world (Y-wise); the coords specify the exact entry point.
+ + ]], + }, { Header = "Example", Contents = [[ @@ -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 @@ -2421,6 +2421,89 @@ function HandleConsoleTestTracer(a_Split, a_EntireCmd) return true, "No such world" end + -- 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] .. " []" + 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 = { @@ -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 = - -- cgit v1.2.3