diff options
-rw-r--r-- | MCServer/.gitignore | 8 | ||||
-rw-r--r-- | VC2008/MCServer.vcproj | 20 | ||||
-rw-r--r-- | source/BlockEntities/ChestEntity.cpp | 2 | ||||
-rw-r--r-- | source/BlockEntities/HopperEntity.cpp | 2 | ||||
-rw-r--r-- | source/BlockTracer.h | 104 | ||||
-rw-r--r-- | source/ChunkDef.h | 5 | ||||
-rw-r--r-- | source/ChunkMap.cpp | 41 | ||||
-rw-r--r-- | source/ChunkMap.h | 4 | ||||
-rw-r--r-- | source/Item.h | 5 | ||||
-rw-r--r-- | source/LineBlockTracer.cpp | 261 | ||||
-rw-r--r-- | source/LineBlockTracer.h | 84 | ||||
-rw-r--r-- | source/LuaState.cpp | 218 | ||||
-rw-r--r-- | source/LuaState.h | 90 | ||||
-rw-r--r-- | source/ManualBindings.cpp | 21 | ||||
-rw-r--r-- | source/Plugin_NewLua.cpp | 350 | ||||
-rw-r--r-- | source/Plugin_NewLua.h | 11 | ||||
-rw-r--r-- | source/World.cpp | 66 | ||||
-rw-r--r-- | source/World.h | 3 |
18 files changed, 1019 insertions, 276 deletions
diff --git a/MCServer/.gitignore b/MCServer/.gitignore index 62225e137..ca10d90e8 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -1,11 +1,8 @@ *.exe -ChunkWorx.ini -ChunkWorxSave.ini +*.ini MCServer -banned.ini logs players -whitelist.ini world* API.txt *.dat @@ -15,9 +12,6 @@ schematics *.pdb memdump.xml *.grab -ProtectionAreas.ini ProtectionAreas.sqlite helgrind.log -settings.ini -webadmin.ini motd.txt diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index dc0291cd6..591ee678a 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -307,6 +307,10 @@ > </File> <File + RelativePath="..\source\BlockTracer.h" + > + </File> + <File RelativePath="..\source\ByteBuffer.cpp" > </File> @@ -546,6 +550,14 @@ > </File> <File + RelativePath="..\source\LineBlockTracer.cpp" + > + </File> + <File + RelativePath="..\source\LineBlockTracer.h" + > + </File> + <File RelativePath="..\source\Log.cpp" > </File> @@ -1486,6 +1498,14 @@ > </File> <File + RelativePath="..\source\LuaState.cpp" + > + </File> + <File + RelativePath="..\source\LuaState.h" + > + </File> + <File RelativePath="..\source\LuaWindow.cpp" > </File> diff --git a/source/BlockEntities/ChestEntity.cpp b/source/BlockEntities/ChestEntity.cpp index 24d2aef11..d5cd076be 100644 --- a/source/BlockEntities/ChestEntity.cpp +++ b/source/BlockEntities/ChestEntity.cpp @@ -123,7 +123,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/BlockEntities/HopperEntity.cpp b/source/BlockEntities/HopperEntity.cpp index 23e4b8096..591db7b4d 100644 --- a/source/BlockEntities/HopperEntity.cpp +++ b/source/BlockEntities/HopperEntity.cpp @@ -125,7 +125,7 @@ void cHopperEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/BlockTracer.h b/source/BlockTracer.h new file mode 100644 index 000000000..6d67f1052 --- /dev/null +++ b/source/BlockTracer.h @@ -0,0 +1,104 @@ + +// BlockTracer.h + +// Declares the classes common for all blocktracers + + + + + +#pragma once + + + + + +// fwd: World.h +class cWorld; + + + + + +class cBlockTracer abstract +{ +public: + /** The callback class is used to notify the caller of individual events that are being traced. + */ + class cCallbacks abstract + { + 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) = 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) { return false; } + + /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= 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) { return false; } + + /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= 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) { return false; } + + /** Called when the path is sure not to hit any more blocks. + Note that for some shapes this might never happen (line with constant Y) + */ + virtual void OnNoMoreHits(void) {} + + /** Called when the block tracing walks into a chunk that is not allocated. + This usually means that the tracing is aborted. + */ + virtual void OnNoChunk(void) {} + } ; + + + /// Creates the BlockTracer parent with the specified callbacks + cBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + m_World(&a_World), + m_Callbacks(&a_Callbacks) + { + } + + + /// Sets new world, returns the old one. Note that both need to be valid + cWorld & SetWorld(cWorld & a_World) + { + cWorld & Old = *m_World; + m_World = &a_World; + return Old; + } + + + /// Sets new callbacks, returns the old ones. Note that both need to be valid + cCallbacks & SetCallbacks(cCallbacks & a_NewCallbacks) + { + cCallbacks & Old = *m_Callbacks; + m_Callbacks = &a_NewCallbacks; + return Old; + } + +protected: + /// The world upon which to operate + cWorld * m_World; + + /// The callback to use for reporting + cCallbacks * m_Callbacks; +} ; + + + + diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 7f9c0ca98..3e78b59b1 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -137,7 +137,7 @@ public: /// Converts absolute block coords into relative (chunk + block) coords: inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) { - BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); + BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ); a_X = a_X - a_ChunkX * Width; a_Z = a_Z - a_ChunkZ * Width; @@ -145,9 +145,8 @@ public: /// Converts absolute block coords to chunk coords: - inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) + inline static void BlockToChunk(int a_X, int a_Z, int & a_ChunkX, int & a_ChunkZ) { - (void)a_Y; a_ChunkX = a_X / Width; if ((a_X < 0) && (a_X % Width != 0)) { diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 0db4b898a..0d49ce9c4 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -345,7 +345,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c x = a_BlockX; y = a_BlockY; z = a_BlockZ; - cChunkDef::BlockToChunk(x, y, z, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if (Chunk == NULL) { @@ -364,7 +364,7 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_blockX, a_blockY, a_blockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -382,7 +382,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -592,7 +592,7 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, in cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -611,7 +611,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -645,7 +645,7 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -664,7 +664,7 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -682,7 +682,7 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -700,7 +700,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i // a_Player rclked block entity at the coords specified, handle it cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -713,11 +713,26 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i +bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return false; + } + return a_Callback.Item(Chunk); +} + + + + + void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -735,8 +750,8 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M { cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; - cChunkDef::BlockToChunk(a_MinBlockX, ZERO_CHUNK_Y, a_MinBlockZ, MinChunkX, MinChunkZ); - cChunkDef::BlockToChunk(a_MaxBlockX, ZERO_CHUNK_Y, a_MaxBlockZ, MaxChunkX, MaxChunkZ); + cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); + cChunkDef::BlockToChunk(a_MaxBlockX, a_MaxBlockZ, MaxChunkX, MaxChunkZ); for (int z = MinChunkZ; z <= MaxChunkZ; z++) { int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width); @@ -1903,7 +1918,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 899f290c5..183031808 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -35,6 +35,7 @@ typedef cItemCallback<cDispenserEntity> cDispenserCallback; typedef cItemCallback<cDropperEntity> cDropperCallback; typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback; typedef cItemCallback<cFurnaceEntity> cFurnaceCallback; +typedef cItemCallback<cChunk> cChunkCallback; @@ -79,6 +80,9 @@ public: /// a_Player rclked block entity at the coords specified, handle it void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); + /// Wakes up simulators for the specified block void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/source/Item.h b/source/Item.h index fc54da51d..fee861050 100644 --- a/source/Item.h +++ b/source/Item.h @@ -55,7 +55,10 @@ public: { if (!IsValidItem(m_ItemType)) { - LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + if (m_ItemType != E_BLOCK_AIR) + { + LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + } Empty(); } } diff --git a/source/LineBlockTracer.cpp b/source/LineBlockTracer.cpp new file mode 100644 index 000000000..03464314a --- /dev/null +++ b/source/LineBlockTracer.cpp @@ -0,0 +1,261 @@ + +// LineBlockTracer.cpp + +// Implements the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + +#include "Globals.h" +#include "LineBlockTracer.h" +#include "Vector3d.h" +#include "World.h" +#include "Chunk.h" + + + + + + +cLineBlockTracer::cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + super(a_World, a_Callbacks) +{ +} + + + + + +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); +} + + + + + +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) +{ + // 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; + + // Check the start coords, adjust into the world: + if (m_StartY < 0) + { + if (m_EndY < 0) + { + // Nothing to trace + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartBelowWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + else if (m_StartY >= cChunkDef::Height) + { + if (m_EndY >= cChunkDef::Height) + { + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartAboveWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + + m_CurrentX = (int)floor(m_StartX); + m_CurrentY = (int)floor(m_StartY); + m_CurrentZ = (int)floor(m_StartZ); + + m_DiffX = m_EndX - m_StartX; + m_DiffY = m_EndY - m_StartY; + m_DiffZ = m_EndZ - m_StartZ; + + // The actual trace is handled with ChunkMapCS locked by calling our Item() for the specified chunk + int BlockX = (int)floor(m_StartX); + int BlockZ = (int)floor(m_StartZ); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); + return m_World->DoWithChunk(ChunkX, ChunkZ, *this); +} + + + + + +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 = (double)cChunkDef::Height - 0.00001; + CalcXZIntersection(Height, m_StartX, m_StartZ); + m_StartY = Height; +} + + + + + +void cLineBlockTracer::FixStartBelowWorld(void) +{ + CalcXZIntersection(0, m_StartX, m_StartZ); + m_StartY = 0; +} + + + + + +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; +} + + + + + +bool cLineBlockTracer::MoveToNextBlock(void) +{ + // Find out which of the current block's walls gets hit by the path: + static const double EPS = 0.00001; + double Coeff = 1; + enum eDirection + { + dirNONE, + dirX, + dirY, + dirZ, + } Direction = dirNONE; + if (abs(m_DiffX) > EPS) + { + double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; + Coeff = (DestX - m_StartX) / m_DiffX; + if (Coeff <= 1) + { + Direction = dirX; + } + } + if (abs(m_DiffY) > EPS) + { + double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY; + double CoeffY = (DestY - m_StartY) / m_DiffY; + if (CoeffY < Coeff) + { + Coeff = CoeffY; + Direction = dirY; + } + } + if (abs(m_DiffZ) > EPS) + { + double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ; + double CoeffZ = (DestZ - m_StartZ) / m_DiffZ; + if (CoeffZ < Coeff) + { + Coeff = CoeffZ; + Direction = dirZ; + } + } + + // Based on the wall hit, adjust the current coords + switch (Direction) + { + case dirX: m_CurrentX += m_DirX; break; + case dirY: m_CurrentY += m_DirY; break; + case dirZ: m_CurrentZ += m_DirZ; break; + case dirNONE: return false; + } + return true; +} + + + + + +bool cLineBlockTracer::Item(cChunk * a_Chunk) +{ + ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld() + + // This is the actual line tracing loop. + bool Finished = false; + while (true) + { + // Report the current block through the callbacks: + if (a_Chunk == NULL) + { + m_Callbacks->OnNoChunk(); + return false; + } + if (a_Chunk->IsValid()) + { + 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)) + { + // The callback terminated the trace + return false; + } + } + else + { + if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ)) + { + // The callback terminated the trace + return false; + } + } + + // Move to next block + if (!MoveToNextBlock()) + { + // We've reached the end + m_Callbacks->OnNoMoreHits(); + return true; + } + + // Update the current chunk + if (a_Chunk != NULL) + { + a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); + } + + if ((m_CurrentY < 0) || (m_CurrentY >= 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)) + { + // The callback terminated the trace + return false; + } + m_Callbacks->OnNoMoreHits(); + return true; + } + } +} + + + + diff --git a/source/LineBlockTracer.h b/source/LineBlockTracer.h new file mode 100644 index 000000000..4616cb191 --- /dev/null +++ b/source/LineBlockTracer.h @@ -0,0 +1,84 @@ + +// LineBlockTracer.h + +// Declares the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + + + + + +#pragma once + +#include "BlockTracer.h" + + + + + +// fwd: Chunk.h +class cChunk; + +// fwd: cChunkMap.h +typedef cItemCallback<cChunk> cChunkCallback; + + + + + + +class cLineBlockTracer : + public cBlockTracer, + public cChunkCallback +{ + typedef cBlockTracer super; + +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); + + // 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); + + /// 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); + +protected: + // The start point of the trace + double m_StartX, m_StartY, m_StartZ; + + // The end point of the trace + double m_EndX, m_EndY, m_EndZ; + + // The difference in coords, End - Start + double m_DiffX, m_DiffY, m_DiffZ; + + // The increment at which the block coords are going from Start to End; either +1 or -1 + int m_DirX, m_DirY, m_DirZ; + + // The current block + int m_CurrentX, m_CurrentY, m_CurrentZ; + + + /// Adjusts the start point above the world to just at the world's top + void FixStartAboveWorld(void); + + /// Adjusts the start point below the world to just at the world's bottom + void FixStartBelowWorld(void); + + /// Calculates the XZ coords of an intersection with the specified Yconst plane; assumes that such an intersection exists + void CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ); + + /// Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) + bool MoveToNextBlock(void); + + // cChunkCallback overrides: + virtual bool Item(cChunk * a_Chunk) override; +} ; + + + + + diff --git a/source/LuaState.cpp b/source/LuaState.cpp new file mode 100644 index 000000000..da86a4b20 --- /dev/null +++ b/source/LuaState.cpp @@ -0,0 +1,218 @@ + +// LuaState.cpp + +// Implements the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + +#include "Globals.h" +#include "LuaState.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +// fwd: SQLite/lsqlite3.c +extern "C" +{ + LUALIB_API int luaopen_lsqlite3(lua_State * L); +} + +// fwd: LuaExpat/lxplib.c: +extern "C" +{ + int luaopen_lxp(lua_State * L); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaState: + +cLuaState::cLuaState(const AString & a_SubsystemName) : + m_LuaState(NULL), + m_SubsystemName(a_SubsystemName) +{ +} + + + + + +cLuaState::~cLuaState() +{ + if (IsValid()) + { + Close(); + } +} + + + + + +void cLuaState::Create(void) +{ + if (m_LuaState != NULL) + { + LOGWARNING("%s: Trying to create an already-existing LuaState, ignoring.", __FUNCTION__); + return; + } + m_LuaState = lua_open(); + luaL_openlibs(m_LuaState); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind(m_LuaState); + luaopen_lsqlite3(m_LuaState); + luaopen_lxp(m_LuaState); +} + + + + + +void cLuaState::Close(void) +{ + if (m_LuaState == NULL) + { + LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); + return; + } + lua_close(m_LuaState); + m_LuaState = NULL; +} + + + + + +bool cLuaState::LoadFile(const AString & a_FileName) +{ + ASSERT(IsValid()); + + // Load the file: + int s = luaL_loadfile(m_LuaState, a_FileName.c_str()); + if (ReportErrors(s)) + { + LOGWARNING("Can't load %s because of an error in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + // Execute the globals: + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + return true; +} + + + + + +bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) +{ + if (!IsValid()) + { + // This happens if cPlugin::Initialize() fails with an error + return false; + } + + lua_getglobal(m_LuaState, a_FunctionName); + if (!lua_isfunction(m_LuaState, -1)) + { + if (a_ShouldLogFailure) + { + LOGWARNING("Error in %s: Could not find function %s()", m_SubsystemName.c_str(), a_FunctionName); + } + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +bool cLuaState::PushFunctionFromRegistry(int a_FnRef) +{ + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() + if (!lua_isfunction(m_LuaState, -1)) + { + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +void cLuaState::PushStringVector(const AStringVector & a_Vector) +{ + lua_createtable(m_LuaState, a_Vector.size(), 0); + int newTable = lua_gettop(m_LuaState); + int index = 1; + for (AStringVector::const_iterator itr = a_Vector.begin(), end = a_Vector.end(); itr != end; ++itr, ++index) + { + tolua_pushstring(m_LuaState, itr->c_str()); + lua_rawseti(m_LuaState, newTable, index); + } +} + + + + + +bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +{ + ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + return false; + } + return true; +} + + + + + +bool cLuaState::ReportErrors(int a_Status) +{ + return ReportErrors(m_LuaState, a_Status); +} + + + + + +bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) +{ + if (a_Status == 0) + { + // No error to report + return false; + } + + LOGWARNING("LUA: %d - %s", a_Status, lua_tostring(a_LuaState, -1)); + lua_pop(a_LuaState, 1); + return true; +} + + + + diff --git a/source/LuaState.h b/source/LuaState.h new file mode 100644 index 000000000..10ff53911 --- /dev/null +++ b/source/LuaState.h @@ -0,0 +1,90 @@ + +// LuaState.h + +// Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + + + + + +#pragma once + + + + + +// fwd: lua.h +struct lua_State; + + + + + +class cLuaState +{ +public: + /** Creates a new instance. The LuaState is not initialized. + a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, + or "LuaScript" for the cLuaScript template + */ + cLuaState(const AString & a_SubsystemName); + + ~cLuaState(); + + operator lua_State * (void) { return m_LuaState; } + + /// Creates the m_LuaState, if not closed already + void Create(void); + + /// Closes the m_LuaState, if not closed already + void Close(void); + + /// Returns true if the m_LuaState is valid + bool IsValid(void) const { return (m_LuaState != NULL); } + + /** Loads the specified file + Returns false and logs a warning to the console if not successful (but the LuaState is kept open). + m_SubsystemName is displayed in the warning log message. + */ + bool LoadFile(const AString & a_FileName); + + /** Pushes the function of the specified name onto the stack. + Returns true if successful. + If a_ShouldLogFail is true, logs a warning on failure (incl. m_SubsystemName) + */ + bool PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure = true); + + /** Pushes a function that has been saved into the global registry, identified by a_FnRef. + Returns true if successful. Logs a warning on failure + */ + bool PushFunctionFromRegistry(int a_FnRef); + + /// Pushes a string vector, as a table, onto the stack + void PushStringVector(const AStringVector & a_Vector); + + /** + Calls the function that has been pushed onto the stack by PushFunction. + Returns true if successful, logs a warning on failure. + a_FunctionName is used only for the warning log message, the function + to be called must be pushed by PushFunction() beforehand. + */ + bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + bool ReportErrors(int status); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + static bool ReportErrors(lua_State * a_LuaState, int status); + +protected: + lua_State * m_LuaState; + + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" + whatever is given to the constructor + */ + AString m_SubsystemName; +} ; + + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 9e9b5f5a8..141335602 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -19,13 +19,14 @@ #include "BlockEntities/FurnaceEntity.h" #include "md5/md5.h" #include "LuaWindow.h" +#include "LuaState.h" // fwd: LuaCommandBinder.cpp -bool report_errors(lua_State* lua, int status); +// bool cLuaState::ReportErrors(lua_State* lua, int status); @@ -233,7 +234,7 @@ static int tolua_DoWith(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -323,7 +324,7 @@ static int tolua_DoWithID(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -418,7 +419,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -511,7 +512,7 @@ static int tolua_ForEachInChunk(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -602,7 +603,7 @@ static int tolua_ForEach(lua_State * tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -813,7 +814,7 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 3, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -887,7 +888,7 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 2, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -1307,8 +1308,8 @@ static int tolua_cPlugin_Call(lua_State* tolua_S) return 0; } - int s = lua_pcall(targetState, top-2, LUA_MULTRET, 0); - if( report_errors( targetState, s ) ) + int s = lua_pcall(targetState, top - 2, LUA_MULTRET, 0); + if (cLuaState::ReportErrors(targetState, s)) { LOGWARN("Error while calling function '%s' in plugin '%s'", funcName.c_str(), self->GetName().c_str() ); return 0; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 8b0f047cd..51d16c839 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -7,45 +7,10 @@ extern "C" { -#include "lualib.h" + #include "lualib.h" } #include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - - - - - -// fwd: SQLite/lsqlite3.c -extern "C" -{ - LUALIB_API int luaopen_lsqlite3(lua_State * L); -} - -// fwd: LuaExpat/lxplib.c: -extern "C" -{ - int luaopen_lxp(lua_State * L); -} - - - - - -bool report_errors(lua_State * lua, int status) -{ - if (status == 0) - { - // No error to report - return false; - } - - LOGERROR("LUA: %s", lua_tostring(lua, -1)); - lua_pop(lua, 1); - return true; -} @@ -54,10 +19,9 @@ bool report_errors(lua_State * lua, int status) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPlugin_NewLua: -cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) - : m_LuaState( 0 ) - , cWebPlugin() - , cPlugin(a_PluginDirectory) +cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) : + cPlugin(a_PluginDirectory), + m_LuaState(Printf("plugin %s", GetName().c_str())) { } @@ -68,12 +32,7 @@ cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) cPlugin_NewLua::~cPlugin_NewLua() { cCSLock Lock(m_CriticalSection); - - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } + m_LuaState.Close(); } @@ -83,14 +42,9 @@ cPlugin_NewLua::~cPlugin_NewLua() bool cPlugin_NewLua::Initialize(void) { cCSLock Lock(m_CriticalSection); - if (m_LuaState == NULL) + if (!m_LuaState.IsValid()) { - m_LuaState = lua_open(); - luaL_openlibs(m_LuaState); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind(m_LuaState); - luaopen_lsqlite3(m_LuaState); - luaopen_lxp(m_LuaState); + m_LuaState.Create(); // Inject the identification global variables into the state: lua_pushlightuserdata(m_LuaState, this); @@ -110,47 +64,32 @@ bool cPlugin_NewLua::Initialize(void) continue; } AString Path = PluginPath + *itr; - int s = luaL_loadfile(m_LuaState, Path.c_str() ); - if( report_errors( m_LuaState, s ) ) + if (!m_LuaState.LoadFile(Path)) { - LOGERROR("Can't load plugin %s because of an error in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Error in plugin %s in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } } // for itr - Files[] // Call intialize function - if (!PushFunction("Initialize")) + if (!m_LuaState.PushFunction("Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); - if (!CallFunction(1, 1, "Initialize")) + if (!m_LuaState.CallFunction(1, 1, "Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } - if( !lua_isboolean( m_LuaState, -1 ) ) + if (!lua_isboolean(m_LuaState, -1)) { - LOGWARN("Error in plugin %s Initialize() must return a boolean value!", GetLocalDirectory().c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + LOGWARNING("Error in plugin %s: Initialize() must return a boolean value!", GetName().c_str()); + m_LuaState.Close(); return false; } @@ -165,12 +104,12 @@ bool cPlugin_NewLua::Initialize(void) void cPlugin_NewLua::OnDisable() { cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnDisable", false)) // false = don't log error if not found + if (!m_LuaState.PushFunction("OnDisable", false)) // false = don't log error if not found { return; } - CallFunction(0, 0, "OnDisable"); + m_LuaState.CallFunction(0, 0, "OnDisable"); } @@ -181,14 +120,14 @@ void cPlugin_NewLua::Tick(float a_Dt) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TICK); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return; } tolua_pushnumber( m_LuaState, a_Dt ); - CallFunction(1, 0, FnName); + m_LuaState.CallFunction(1, 0, FnName); } @@ -200,7 +139,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_BLOCK_TO_PICKUPS); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -214,7 +153,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int tolua_pushnumber (m_LuaState, a_BlockMeta); tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -233,7 +172,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHAT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -241,7 +180,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Message.c_str()); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -264,7 +203,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_AVAILABLE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -273,7 +212,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -292,7 +231,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -302,7 +241,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -321,7 +260,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -331,7 +270,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_pLuaChunk, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -350,7 +289,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -359,7 +298,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -378,7 +317,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -387,7 +326,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -406,7 +345,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_COLLECTING_PICKUP); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -414,7 +353,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -433,7 +372,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CRAFTING_NO_RECIPE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -442,7 +381,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -461,7 +400,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_DISCONNECT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -469,7 +408,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Reason.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -488,7 +427,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_EXECUTE_COMMAND); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -508,7 +447,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & ++index; } - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -527,7 +466,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_HANDSHAKE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -535,7 +474,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); tolua_pushstring (m_LuaState, a_Username.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -554,7 +493,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_KILLING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -562,7 +501,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) tolua_pushusertype(m_LuaState, &a_Victim, "cEntity"); tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -581,7 +520,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_LOGIN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -590,7 +529,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co tolua_pushnumber (m_LuaState, a_ProtocolVersion); tolua_pushcppstring(m_LuaState, a_Username); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -609,7 +548,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BREAKING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -622,7 +561,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -641,7 +580,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BROKEN_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -654,7 +593,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -673,14 +612,14 @@ bool cPlugin_NewLua::OnPlayerEating(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_EATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -699,14 +638,14 @@ bool cPlugin_NewLua::OnPlayerJoined(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_JOINED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -725,7 +664,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_LEFT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -737,7 +676,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockFace); tolua_pushnumber (m_LuaState, a_Status); - if (!CallFunction(6, 1, FnName)) + if (!m_LuaState.CallFunction(6, 1, FnName)) { return false; } @@ -756,14 +695,14 @@ bool cPlugin_NewLua::OnPlayerMoved(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_MOVING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -782,7 +721,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -798,7 +737,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -817,7 +756,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -833,7 +772,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -852,7 +791,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -866,7 +805,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -885,7 +824,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICKING_ENTITY); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -893,7 +832,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, &a_Entity, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -912,14 +851,14 @@ bool cPlugin_NewLua::OnPlayerShooting(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SHOOTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -938,14 +877,14 @@ bool cPlugin_NewLua::OnPlayerSpawned(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SPAWNED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -964,14 +903,14 @@ bool cPlugin_NewLua::OnPlayerTossingItem(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_TOSSING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -990,7 +929,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1006,7 +945,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1025,7 +964,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1039,7 +978,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1058,7 +997,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1074,7 +1013,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1093,7 +1032,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1107,7 +1046,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1126,7 +1065,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_POST_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1135,7 +1074,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1154,7 +1093,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PRE_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1163,7 +1102,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1182,7 +1121,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TAKE_DAMAGE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1190,7 +1129,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity"); tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -1214,7 +1153,7 @@ bool cPlugin_NewLua::OnUpdatedSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATED_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1229,7 +1168,7 @@ bool cPlugin_NewLua::OnUpdatedSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 1, FnName)) + if (!m_LuaState.CallFunction(9, 1, FnName)) { return false; } @@ -1253,7 +1192,7 @@ bool cPlugin_NewLua::OnUpdatingSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATING_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1268,7 +1207,7 @@ bool cPlugin_NewLua::OnUpdatingSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 5, "OnUpdatingSign")) + if (!m_LuaState.CallFunction(9, 5, "OnUpdatingSign")) { return false; } @@ -1303,14 +1242,14 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_World, "cWorld"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -1329,7 +1268,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1337,7 +1276,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather tolua_pushusertype(m_LuaState, &a_World, "cWorld"); tolua_pushnumber (m_LuaState, a_NewWeather); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -1368,29 +1307,22 @@ bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Pl cCSLock Lock(m_CriticalSection); // Push the function to be called: - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() - - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector<std::string>::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) + if (!m_LuaState.PushFunctionFromRegistry(cmd->second)) { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; + LOGWARNING("Command handler function for \"%s\" is invalid", cmd->first.c_str()); + return false; } + // Push the split: + m_LuaState.PushStringVector(a_Split); + // Push player: tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); // Call function: - int s = lua_pcall(m_LuaState, 2, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1436,10 +1368,9 @@ bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cComman } // Call function: - int s = lua_pcall(m_LuaState, 1, 2, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(1, 2, __FUNCTION__)) { - LOGERROR("Lua error. Stack size: %i", lua_gettop(m_LuaState)); + LOGWARNING("Lua error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1604,9 +1535,9 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) return ""; sWebPluginTab* Tab = 0; - for( TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr ) + for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr) { - if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr + if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr { Tab = *itr; break; @@ -1615,13 +1546,13 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) if( Tab ) { - //LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, Tab->UserData); // same as lua_getref() - //LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); - //LOGINFO("Calling bound function! :D"); + // LOGINFO("Calling bound function! :D"); int s = lua_pcall( m_LuaState, 1, 1, 0); if ( s != 0 ) @@ -1642,7 +1573,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) RetVal += tolua_tostring(m_LuaState, -1, 0); lua_pop(m_LuaState, 1); // Pop return value - //LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); } return RetVal; @@ -1652,7 +1583,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) -bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference ) +bool cPlugin_NewLua::AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference) { cCSLock Lock(m_CriticalSection); if (a_LuaState != m_LuaState) @@ -1666,7 +1597,7 @@ bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, Tab->UserData = a_FunctionReference; - GetTabs().push_back( Tab ); + GetTabs().push_back(Tab); return true; } @@ -1715,10 +1646,9 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); // Call function: - int s = lua_pcall(m_LuaState, 3, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(3, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1741,56 +1671,12 @@ void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, tolua_pushnumber (m_LuaState, a_SlotNum); // Call function: - int s = lua_pcall(m_LuaState, 2, 0, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 0, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); } } - -// Helper functions -bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */) -{ - if (m_LuaState == NULL) - { - // This happens if Initialize() fails with an error - return false; - } - - lua_getglobal(m_LuaState, a_FunctionName); - if (!lua_isfunction(m_LuaState, -1)) - { - if (a_bLogError) - { - LOGWARN("Error in plugin %s: Could not find function %s()", GetName().c_str(), a_FunctionName); - } - lua_pop(m_LuaState, 1); - return false; - } - return true; -} - - - - - -bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName) -{ - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); - - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); - if (report_errors(m_LuaState, s)) - { - LOGWARN("Error in plugin %s calling function %s()", GetName().c_str(), a_FunctionName); - return false; - } - return true; -} - - - - diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index a79affd5d..d31a62601 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -3,6 +3,7 @@ #include "Plugin.h" #include "WebPlugin.h" +#include "LuaState.h" // Names for the global variables through which the plugin is identified in its LuaState #define LUA_PLUGIN_NAME_VAR_NAME "_MCServerInternal_PluginName" @@ -11,9 +12,6 @@ -// fwd: Lua -typedef struct lua_State lua_State; - // fwd: UI/Window.h class cWindow; @@ -99,7 +97,7 @@ public: /// Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap. void BindConsoleCommand(const AString & a_Command, int a_FnRef); - lua_State * GetLuaState(void) { return m_LuaState; } + cLuaState & GetLuaState(void) { return m_LuaState; } cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; } @@ -114,7 +112,7 @@ public: protected: cCriticalSection m_CriticalSection; - lua_State * m_LuaState; + cLuaState m_LuaState; /// Maps command name into Lua function reference typedef std::map<AString, int> CommandMap; @@ -122,9 +120,6 @@ protected: CommandMap m_Commands; CommandMap m_ConsoleCommands; - bool PushFunction(const char * a_FunctionName, bool a_bLogError = true); - bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else - /// Returns the name of Lua function that should handle the specified hook const char * GetHookFnName(cPluginManager::PluginHook a_Hook); } ; // tolua_export diff --git a/source/World.cpp b/source/World.cpp index 880f6e5b2..1ff5a5970 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -59,6 +59,9 @@ #include "tolua++.h" +// DEBUG: Test out the cLineBlockTracer class by tracing a few lines: +#include "LineBlockTracer.h" + #ifndef _WIN32 #include <stdlib.h> #endif @@ -442,6 +445,60 @@ void cWorld::InitializeSpawn(void) // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // +1.6f eye height + + + #ifdef TEST_LINEBLOCKTRACER + // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: + class cTracerCallbacks : + public cBlockTracer::cCallbacks + { + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override + { + LOGD("Block {%d, %d, %d}: %d:%d (%s)", + a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, + ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() + ); + return false; + } + + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override + { + LOGD("Block {%d, %d, %d}: no data available", + a_BlockX, a_BlockY, a_BlockZ + ); + return false; + } + + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Out of world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Into world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual void OnNoMoreHits(void) override + { + LOGD("No more hits"); + } + } Callbacks; + LOGD("Spawn is at {%f, %f, %f}", m_SpawnX, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along +X:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY, m_SpawnZ, m_SpawnX + 10, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along -Z:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, m_SpawnY, m_SpawnZ + 10, m_SpawnX, m_SpawnY, m_SpawnZ - 10); + LOGD("Tracing a line along -Y, out of world:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, 260, m_SpawnZ, m_SpawnX, -5, m_SpawnZ); + LOGD("Tracing a line along XY:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY - 10, m_SpawnZ, m_SpawnX + 10, m_SpawnY + 10, m_SpawnZ); + LOGD("Tracing a line in generic direction:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 15, m_SpawnY - 5, m_SpawnZ + 7.5, m_SpawnX + 13, m_SpawnY - 10, m_SpawnZ + 8.5); + LOGD("Tracing tests done"); + #endif // TEST_LINEBLOCKTRACER } @@ -832,6 +889,15 @@ bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_ +bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, a_Callback); +} + + + + + void cWorld::GrowTree(int a_X, int a_Y, int a_Z) { if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) diff --git a/source/World.h b/source/World.h index 5720ae634..712064af6 100644 --- a/source/World.h +++ b/source/World.h @@ -404,6 +404,9 @@ public: /// a_Player is using block entity at [x, y, z], handle that: void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } + + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export |