diff options
author | mBornand <63592189+mBornand@users.noreply.github.com> | 2020-05-08 11:04:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-08 11:04:07 +0200 |
commit | 1565d9b3ce8e74cdf8d2c95181f98531794f2c36 (patch) | |
tree | 09f6d9158cd2c583789d5c23bc174be115178972 /src | |
parent | Fix SetBlockMeta call in observer handler (#4728) (diff) | |
download | cuberite-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 |
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 218 | ||||
-rw-r--r-- | src/BlockTracer.h | 24 | ||||
-rw-r--r-- | src/Entities/ProjectileEntity.cpp | 9 | ||||
-rw-r--r-- | src/Items/ItemBoat.h | 4 | ||||
-rw-r--r-- | src/Items/ItemBottle.h | 4 | ||||
-rw-r--r-- | src/Items/ItemBucket.h | 14 | ||||
-rw-r--r-- | src/Items/ItemLilypad.h | 8 | ||||
-rw-r--r-- | src/LineBlockTracer.cpp | 141 | ||||
-rw-r--r-- | src/LineBlockTracer.h | 20 |
9 files changed, 258 insertions, 184 deletions
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: - - |