From 083228a10dffcaa77b1d0035c29013c6802befd4 Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Sun, 8 Jul 2012 21:01:08 +0000 Subject: Squirrel Plugins I worked a little bit on the squirrel Bindings They work now on linux and windows :) (OSX is untested, but should work also) but they are very limited at the moment. (Only made OnChat working) I also fixed some small bugs. git-svn-id: http://mc-server.googlecode.com/svn/trunk@648 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/AllToLua.pkg | 2 +- source/Bindings.cpp | 4 +- source/Bindings.h | 2 +- source/BlockArea.cpp | 626 -------------------------- source/BlockArea.h | 147 ------ source/SquirrelBindings.cpp | 140 ------ source/SquirrelBindings.h | 15 - source/_OLD_SquirrelBindings.cpp | 140 ++++++ source/_OLD_SquirrelBindings.h | 15 + source/cBlockArea.cpp | 626 ++++++++++++++++++++++++++ source/cBlockArea.h | 147 ++++++ source/cChunk.cpp | 2 +- source/cPluginManager.cpp | 36 +- source/cPlugin_Squirrel.cpp | 352 +++++++++++++++ source/cPlugin_Squirrel.h | 42 ++ source/cVine.h | 1 - source/main.cpp | 7 +- source/squirrelbindings/SquirrelBindings.cpp | 52 +++ source/squirrelbindings/SquirrelBindings.h | 13 + source/squirrelbindings/SquirrelFunctions.cpp | 65 +++ source/squirrelbindings/SquirrelFunctions.h | 6 + source/squirrelbindings/SquirrelObject.h | 24 + source/squirrelbindings/cSquirrelBaseClass.h | 29 ++ 23 files changed, 1531 insertions(+), 962 deletions(-) delete mode 100644 source/BlockArea.cpp delete mode 100644 source/BlockArea.h delete mode 100644 source/SquirrelBindings.cpp delete mode 100644 source/SquirrelBindings.h create mode 100644 source/_OLD_SquirrelBindings.cpp create mode 100644 source/_OLD_SquirrelBindings.h create mode 100644 source/cBlockArea.cpp create mode 100644 source/cBlockArea.h create mode 100644 source/cPlugin_Squirrel.cpp create mode 100644 source/cPlugin_Squirrel.h create mode 100644 source/squirrelbindings/SquirrelBindings.cpp create mode 100644 source/squirrelbindings/SquirrelBindings.h create mode 100644 source/squirrelbindings/SquirrelFunctions.cpp create mode 100644 source/squirrelbindings/SquirrelFunctions.h create mode 100644 source/squirrelbindings/SquirrelObject.h create mode 100644 source/squirrelbindings/cSquirrelBaseClass.h (limited to 'source') diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index b6ee64579..4e4cfb4b5 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -45,7 +45,7 @@ $cfile "cCuboid.h" $cfile "cMCLogger.h" $cfile "cTracer.h" $cfile "cGroup.h" -$cfile "BlockArea.h" +$cfile "cBlockArea.h" $cfile "packets/cPacket_Login.h" $cfile "packets/cPacket_BlockDig.h" $cfile "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 485f37dc0..772013b25 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:12. */ #ifndef __cplusplus @@ -54,7 +54,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "cMCLogger.h" #include "cTracer.h" #include "cGroup.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "packets/cPacket_Login.h" #include "packets/cPacket_BlockDig.h" #include "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.h b/source/Bindings.h index a47b5e463..097fe7e64 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:13. */ /* Exported function */ diff --git a/source/BlockArea.cpp b/source/BlockArea.cpp deleted file mode 100644 index 7750b94fb..000000000 --- a/source/BlockArea.cpp +++ /dev/null @@ -1,626 +0,0 @@ - -// BlockArea.cpp - -// Implements the cBlockArea object representing an area of block data that can be queried from cWorld and then accessed again without further queries -// The object also supports writing the blockdata back into cWorld, even into other coords - -#include "Globals.h" -#include "BlockArea.h" -#include "cWorld.h" - - - - - -cBlockArea::cBlockArea(void) : - m_SizeX(0), - m_SizeY(0), - m_SizeZ(0), - m_BlockTypes(NULL), - m_BlockMetas(NULL), - m_BlockLight(NULL), - m_BlockSkyLight(NULL) -{ -} - - - - - -cBlockArea::~cBlockArea() -{ - Clear(); -} - - - - - -void cBlockArea::Clear(void) -{ - delete[] m_BlockTypes; m_BlockTypes = NULL; - delete[] m_BlockMetas; m_BlockMetas = NULL; - delete[] m_BlockLight; m_BlockLight = NULL; - delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; - m_SizeX = 0; - m_SizeY = 0; - m_SizeZ = 0; -} - - - - -bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes) -{ - // Normalize the coords: - if (a_MinBlockX > a_MaxBlockX) - { - std::swap(a_MinBlockX, a_MaxBlockX); - } - if (a_MinBlockY > a_MaxBlockY) - { - std::swap(a_MinBlockY, a_MaxBlockY); - } - if (a_MinBlockZ > a_MaxBlockZ) - { - std::swap(a_MinBlockZ, a_MaxBlockZ); - } - - // Check coords validity: - if (a_MinBlockY < 0) - { - LOGWARNING("cBlockArea:Read(): MinBlockY less than zero, adjusting to zero"); - a_MinBlockY = 0; - } - else if (a_MinBlockY >= cChunkDef::Height) - { - LOGWARNING("cBlockArea::Read(): MinBlockY more than chunk height, adjusting to chunk height"); - a_MinBlockY = cChunkDef::Height - 1; - } - if (a_MaxBlockY < 0) - { - LOGWARNING("cBlockArea:Read(): MaxBlockY less than zero, adjusting to zero"); - a_MaxBlockY = 0; - } - else if (a_MinBlockY >= cChunkDef::Height) - { - LOGWARNING("cBlockArea::Read(): MaxBlockY more than chunk height, adjusting to chunk height"); - a_MaxBlockY = cChunkDef::Height - 1; - } - - // Allocate the needed memory: - Clear(); - if (!SetSize(a_MaxBlockX - a_MinBlockX, a_MaxBlockY - a_MinBlockY, a_MaxBlockZ - a_MinBlockZ, a_DataTypes)) - { - return false; - } - m_OriginX = a_MinBlockX; - m_OriginY = a_MinBlockY; - m_OriginZ = a_MinBlockZ; - cChunkReader Reader(*this); - - // Convert block coords to chunks coords: - int MinChunkX, MaxChunkX; - int MinChunkZ, MaxChunkZ; - cChunkDef::AbsoluteToRelative(a_MinBlockX, a_MinBlockY, a_MinBlockZ, MinChunkX, MinChunkZ); - cChunkDef::AbsoluteToRelative(a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ, MaxChunkX, MaxChunkZ); - - // Query block data: - if (!a_World->ForEachChunkInRect(MinChunkX, MaxChunkX, MinChunkZ, MaxChunkZ, Reader)) - { - Clear(); - return false; - } - return true; -} - - - - - -bool cBlockArea::Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) -{ - // TODO - ASSERT(!"Not implemented yet"); - return false; -} - - - - - - -void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType) -{ - if (m_BlockTypes == NULL) - { - LOGWARNING("cBlockArea: BlockTypes have not been read!"); - return; - } - m_BlockTypes[MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_BlockType; -} - - - - - -void cBlockArea::SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) -{ - SetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType); -} - - - - - -void cBlockArea::SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta) -{ - SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockMeta, m_BlockMetas); -} - - - - - -void cBlockArea::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta) -{ - SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta, m_BlockMetas); -} - - - - - -void cBlockArea::SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight) -{ - SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockLight, m_BlockLight); -} - - - - - -void cBlockArea::SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight) -{ - SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockLight, m_BlockLight); -} - - - - - -void cBlockArea::SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight) -{ - SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockSkyLight, m_BlockSkyLight); -} - - - - - -void cBlockArea::SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight) -{ - SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockSkyLight, m_BlockSkyLight); -} - - - - - -BLOCKTYPE cBlockArea::GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) -{ - if (m_BlockTypes == NULL) - { - LOGWARNING("cBlockArea: BlockTypes have not been read!"); - return E_BLOCK_AIR; - } - return m_BlockTypes[MakeIndex(a_RelX, a_RelY, a_RelZ)]; -} - - - - - -BLOCKTYPE cBlockArea::GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - return GetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ); -} - - - - - -NIBBLETYPE cBlockArea::GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) -{ - return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockMetas); -} - - - - - -NIBBLETYPE cBlockArea::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockMetas); -} - - - - - -NIBBLETYPE cBlockArea::GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) -{ - return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockLight); -} - - - - - -NIBBLETYPE cBlockArea::GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockLight); -} - - - - - -NIBBLETYPE cBlockArea::GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) -{ - return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockSkyLight); -} - - - - - -NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockSkyLight); -} - - - - - -int cBlockArea::GetDataTypes(void) const -{ - int res = 0; - if (m_BlockTypes != NULL) - { - res |= baTypes; - } - if (m_BlockMetas != NULL) - { - res |= baMetas; - } - if (m_BlockLight != NULL) - { - res |= baLight; - } - if (m_BlockSkyLight != NULL) - { - res |= baSkyLight; - } - return res; -} - - - - - -bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) -{ - ASSERT(m_BlockTypes == NULL); // Has been cleared - - if (a_DataTypes & baTypes) - { - m_BlockTypes = new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockTypes == NULL) - { - return false; - } - } - if (a_DataTypes & baMetas) - { - m_BlockMetas = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockMetas == NULL) - { - delete[] m_BlockTypes; - return false; - } - } - if (a_DataTypes & baLight) - { - m_BlockLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockLight == NULL) - { - delete[] m_BlockMetas; - delete[] m_BlockTypes; - return false; - } - } - if (a_DataTypes & baSkyLight) - { - m_BlockSkyLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; - if (m_BlockSkyLight == NULL) - { - delete[] m_BlockLight; - delete[] m_BlockMetas; - delete[] m_BlockTypes; - return false; - } - } - m_SizeX = a_SizeX; - m_SizeY = a_SizeY; - m_SizeZ = a_SizeZ; - return true; -} - - - - - -int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) -{ - return a_RelX + a_RelZ * m_SizeZ + a_RelY * m_SizeX * m_SizeZ; -} - - - - - -void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) -{ - if (a_Array == NULL) - { - LOGWARNING("cBlockArea: datatype has not been read!"); - return; - } - a_Array[MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_Value; -} - - - - - -void cBlockArea::SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) -{ - SetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Value, a_Array); -} - - - - - -NIBBLETYPE cBlockArea::GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array) -{ - if (a_Array == NULL) - { - LOGWARNING("cBlockArea: datatype has not been read!"); - return 16; - } - return a_Array[MakeIndex(a_RelX, a_RelY, a_RelZ)]; -} - - - - - -NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array) -{ - return GetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Array); -} - - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBlockArea::cChunkReader: - -cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : - m_Area(a_Area), - m_OriginX(a_Area.m_OriginX), - m_OriginY(a_Area.m_OriginY), - m_OriginZ(a_Area.m_OriginZ) -{ -} - - - - - -void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc) -{ - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; - - // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) - // OffX, OffZ are the offsets of the current chunk data from the area origin - // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders - int SizeX = cChunkDef::Width; - int SizeZ = cChunkDef::Width; - int OffX, OffZ; - int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; - if (OffX < 0) - { - BaseX = -OffX; - SizeX += OffX; // SizeX is decreased, OffX is negative - OffX = 0; - } - else - { - BaseX = 0; - } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; - if (OffZ < 0) - { - BaseZ = -OffZ; - SizeZ += OffZ; // SizeZ is decreased, OffZ is negative - OffZ = 0; - } - else - { - BaseZ = 0; - } - // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) - { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); - } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) - { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); - } - - for (int y = 0; y < SizeY; y++) - { - int ChunkY = MinY + y; - int AreaY = y; - for (int z = 0; z < SizeZ; z++) - { - int ChunkZ = BaseZ + z; - int AreaZ = OffZ + z; - for (int x = 0; x < SizeX; x++) - { - int ChunkX = BaseX + x; - int AreaX = OffX + x; - a_AreaDst[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = cChunkDef::GetNibble(a_ChunkSrc, ChunkX, ChunkY, ChunkZ); - } // for x - } // for z - } // for y -} - - - - - -bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) -{ - m_CurrentChunkX = a_ChunkX; - m_CurrentChunkZ = a_ChunkZ; - return true; -} - - - - - -void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) -{ - if (m_Area.m_BlockTypes == NULL) - { - // Don't want BlockTypes - return; - } - - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; - - // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) - // OffX, OffZ are the offsets of the current chunk data from the area origin - // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders - int SizeX = cChunkDef::Width; - int SizeZ = cChunkDef::Width; - int OffX, OffZ; - int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; - if (OffX < 0) - { - BaseX = -OffX; - SizeX += OffX; // SizeX is decreased, OffX is negative - OffX = 0; - } - else - { - BaseX = 0; - } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; - if (OffZ < 0) - { - BaseZ = -OffZ; - SizeZ += OffZ; // SizeZ is decreased, OffZ is negative - OffZ = 0; - } - else - { - BaseZ = 0; - } - // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) - { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); - } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) - { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); - } - - for (int y = 0; y < SizeY; y++) - { - int ChunkY = MinY + y; - int AreaY = y; - for (int z = 0; z < SizeZ; z++) - { - int ChunkZ = BaseZ + z; - int AreaZ = OffZ + z; - for (int x = 0; x < SizeX; x++) - { - int ChunkX = BaseX + x; - int AreaX = OffX + x; - m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = cChunkDef::GetBlock(a_BlockTypes, ChunkX, ChunkY, ChunkZ); - } // for x - } // for z - } // for y -} - - - - - -void cBlockArea::cChunkReader::BlockMeta(const NIBBLETYPE * a_BlockMetas) -{ - if (m_Area.m_BlockMetas == NULL) - { - // Don't want metas - return; - } - CopyNibbles(m_Area.m_BlockMetas, a_BlockMetas); -} - - - - - -void cBlockArea::cChunkReader::BlockLight(const NIBBLETYPE * a_BlockLight) -{ - if (m_Area.m_BlockLight == NULL) - { - // Don't want light - return; - } - CopyNibbles(m_Area.m_BlockLight, a_BlockLight); -} - - - - - -void cBlockArea::cChunkReader::BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) -{ - if (m_Area.m_BlockSkyLight == NULL) - { - // Don't want skylight - return; - } - CopyNibbles(m_Area.m_BlockSkyLight, a_BlockSkyLight); -} - - - - - diff --git a/source/BlockArea.h b/source/BlockArea.h deleted file mode 100644 index 5abdab3bb..000000000 --- a/source/BlockArea.h +++ /dev/null @@ -1,147 +0,0 @@ - -// BlockArea.h - -// Interfaces to the cBlockArea object representing an area of block data that can be queried from cWorld and then accessed again without further queries -// The object also supports writing the blockdata back into cWorld, even into other coords - - - - - -#pragma once - - - - - -// fwd: "cWorld.h" -class cWorld; - - - - - -// tolua_begin -class cBlockArea -{ - // tolua_end - DISALLOW_COPY_AND_ASSIGN(cBlockArea); - // tolua_begin - -public: - - /// What data is to be queried (bit-mask) - enum - { - baTypes = 1, - baMetas = 2, - baLight = 4, - baSkyLight = 8, - } ; - - cBlockArea(void); - ~cBlockArea(); - - /// Clears the data stored to reclaim memory - void Clear(void); - - /// Reads an area of blocks specified. Returns true if successful. All coords are inclusive. - bool Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes = baTypes | baMetas); - - /// Writes the area back into cWorld at the coords specified. Returns true if successful. - bool Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes = baTypes | baMetas); - - // TODO: Write() is not too good an interface: if it fails, there's no way to repeat only for the parts that didn't write - // A better way may be to return a list of cBlockAreas for each part that didn't succeed writing, so that the caller may try again - - // Setters: - void SetRelBlockType (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); - void SetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); - void SetRelBlockMeta (int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta); - void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta); - void SetRelBlockLight (int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight); - void SetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight); - void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight); - void SetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight); - - // Getters: - BLOCKTYPE GetRelBlockType (int a_RelX, int a_RelY, int a_RelZ); - BLOCKTYPE GetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ); - NIBBLETYPE GetRelBlockMeta (int a_RelX, int a_RelY, int a_RelZ); - NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); - NIBBLETYPE GetRelBlockLight (int a_RelX, int a_RelY, int a_RelZ); - NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ); - NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ); - NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); - - /// Returns the datatypes that are stored in the object (bitmask of baXXX values) - int GetDataTypes(void) const; - - // tolua_end - - // Clients can use these for faster access to all blocktypes. Be careful though! - /// Returns the internal pointer to the block types - BLOCKTYPE * GetBlockTypes(void) { return m_BlockTypes; } - int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; } - - // tolua_begin - -protected: - - // tolua_end - - class cChunkReader : - public cChunkDataCallback - { - public: - cChunkReader(cBlockArea & a_Area); - - protected: - cBlockArea & m_Area; - int m_OriginX; - int m_OriginY; - int m_OriginZ; - int m_CurrentChunkX; - int m_CurrentChunkZ; - - void CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc); - - // cChunkDataCallback overrides: - virtual bool Coords (int a_ChunkX, int a_ChunkZ) override; - virtual void BlockTypes (const BLOCKTYPE * a_BlockTypes) override; - virtual void BlockMeta (const NIBBLETYPE * a_BlockMetas) override; - virtual void BlockLight (const NIBBLETYPE * a_BlockLight) override; - virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override; - } ; - - // tolua_begin - - int m_OriginX; - int m_OriginY; - int m_OriginZ; - int m_SizeX; - int m_SizeY; - int m_SizeZ; - - BLOCKTYPE * m_BlockTypes; - NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access - NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access - NIBBLETYPE * m_BlockSkyLight; // Each light value is stored as a separate byte for faster access - - bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes); - - int MakeIndex(int a_RelX, int a_RelY, int a_RelZ); - - // Basic Setters: - void SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); - void SetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); - - // Basic Getters: - NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array); - NIBBLETYPE GetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array); -} ; -// tolua_end - - - - diff --git a/source/SquirrelBindings.cpp b/source/SquirrelBindings.cpp deleted file mode 100644 index d8f513370..000000000 --- a/source/SquirrelBindings.cpp +++ /dev/null @@ -1,140 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SquirrelBindings.h" -#if USE_SQUIRREL -#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus -#pragma warning(disable:4127) - -#include -#include -#include <../squirrel/sqstate.h> -#include <../squirrel/sqvm.h> - -#include "cPlugin.h" -#include "cPluginManager.h" -#include "cRoot.h" -#include "cPlayer.h" - - - - - -bool SquirrelBindings::IsBound = false; - -bool IsTopClosure( HSQUIRRELVM v ) -{ - return ( v->_stack[0]._type == OT_CLOSURE ); -} - -class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel -{ -public: - template - static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) - { - LOG("ConstructAndDestruct()"); - - StackHandler sa(v); - HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE - SquirrelObject instance(ho); - SqPlus::PopulateAncestry(v, instance, a_Instance); - a_Instance->vm = v; - a_Instance->obj = instance; - - sq_setinstanceup(v, 1, a_Instance); - sq_setreleasehook(v, 1, a_ReleaseHook); - return TRUE; - } - - HSQUIRRELVM vm; - SquirrelObject obj; -}; - -class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class -{ -public: - cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } - - bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance - { - SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); - if( !InitFunc.func.IsNull() ) - return InitFunc(); - LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented - return false; - } - - static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } - - virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) - { - if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) - { //Called from C++ - return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); - } - else // Called from Squirrel - { - return cPlugin::OnChat(a_Chat, a_Player); - } - } -}; - -static void printFunc(HSQUIRRELVM v,const SQChar * s,...) -{ - (void)v; - va_list vl; - va_start(vl,s); - cMCLogger::GetInstance()->Log( s, vl ); - va_end(vl); -} - -DECLARE_INSTANCE_TYPE( cRoot ); -DECLARE_INSTANCE_TYPE( cPluginManager ); -DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); -DECLARE_INSTANCE_TYPE( cPlugin ); -DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); - -DECLARE_INSTANCE_TYPE( cEntity ); -DECLARE_INSTANCE_TYPE( cPawn ); -DECLARE_INSTANCE_TYPE( cPlayer ); - -void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) -{ - IsBound = true; - - sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); - - - SqPlus::SQClassDefNoConstructor("cEntity"); - SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); - SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one - func(&cPlayer::GetName, "GetName"); - - SqPlus::SQClassDefNoConstructor("cPlugin"). - func(&cPlugin::SetName, "SetName"). - func(&cPlugin::GetName, "GetName"). - func(&cPlugin::GetVersion, "GetVersion"). - func(&cPlugin::OnChat, "OnChat"); - - - SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). - staticFunc(&cPlugin__Squirrel::constructor, "constructor"); - - - SqPlus::SQClassDefNoConstructor("cRoot"). - staticFunc(&cRoot::Get, "Get"). - func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); - - - SqPlus::SQClassDefNoConstructor("cPluginManager"). - overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). - func(&cPluginManager::GetPlugin, "GetPlugin"). - func(&cPluginManager::AddHook, "AddHook"). - enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); - - - -} - -#endif diff --git a/source/SquirrelBindings.h b/source/SquirrelBindings.h deleted file mode 100644 index 06a3df716..000000000 --- a/source/SquirrelBindings.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#define USE_SQUIRREL 0 - -#if USE_SQUIRREL - -struct SQVM; -class SquirrelBindings -{ -public: - static void Bind( SQVM* a_SquirrelVM ); - static bool IsBound; -}; - -#endif diff --git a/source/_OLD_SquirrelBindings.cpp b/source/_OLD_SquirrelBindings.cpp new file mode 100644 index 000000000..532b19950 --- /dev/null +++ b/source/_OLD_SquirrelBindings.cpp @@ -0,0 +1,140 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "SquirrelBindings.h" +#if USE_SQUIRREL +//#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus +//#pragma warning(disable:4127) + +#include +#include +#include <../squirrel/sqstate.h> +#include <../squirrel/sqvm.h> + +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cRoot.h" +#include "cPlayer.h" + + + + + +bool SquirrelBindings::IsBound = false; + +bool IsTopClosure( HSQUIRRELVM v ) +{ + return ( v->_stack[0]._type == OT_CLOSURE ); +} + +class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel +{ +public: + template + static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) + { + LOG("ConstructAndDestruct()"); + + StackHandler sa(v); + HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE + SquirrelObject instance(ho); + SqPlus::PopulateAncestry(v, instance, a_Instance); + a_Instance->vm = v; + a_Instance->obj = instance; + + sq_setinstanceup(v, 1, a_Instance); + sq_setreleasehook(v, 1, a_ReleaseHook); + return TRUE; + } + + HSQUIRRELVM vm; + SquirrelObject obj; +}; + +class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class +{ +public: + cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } + + bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance + { + SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); + if( !InitFunc.func.IsNull() ) + return InitFunc(); + LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented + return false; + } + + static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } + + virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) + { + if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) + { //Called from C++ + return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); + } + else // Called from Squirrel + { + return cPlugin::OnChat(a_Chat, a_Player); + } + } +}; + +static void printFunc(HSQUIRRELVM v,const SQChar * s,...) +{ + (void)v; + va_list vl; + va_start(vl,s); + cMCLogger::GetInstance()->Log( s, vl ); + va_end(vl); +} + +DECLARE_INSTANCE_TYPE( cRoot ); +DECLARE_INSTANCE_TYPE( cPluginManager ); +DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); +DECLARE_INSTANCE_TYPE( cPlugin ); +DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); + +DECLARE_INSTANCE_TYPE( cEntity ); +DECLARE_INSTANCE_TYPE( cPawn ); +DECLARE_INSTANCE_TYPE( cPlayer ); + +void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) +{ + IsBound = true; + + sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); + + + SqPlus::SQClassDefNoConstructor("cEntity"); + SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); + SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one + func(&cPlayer::GetName, "GetName"); + + SqPlus::SQClassDefNoConstructor("cPlugin"). + func(&cPlugin::SetName, "SetName"). + func(&cPlugin::GetName, "GetName"). + func(&cPlugin::GetVersion, "GetVersion"). + func(&cPlugin::OnChat, "OnChat"); + + + SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). + staticFunc(&cPlugin__Squirrel::constructor, "constructor"); + + + SqPlus::SQClassDefNoConstructor("cRoot"). + staticFunc(&cRoot::Get, "Get"). + func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); + + + SqPlus::SQClassDefNoConstructor("cPluginManager"). + overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). + func(&cPluginManager::GetPlugin, "GetPlugin"). + func(&cPluginManager::AddHook, "AddHook"). + enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); + + + +} + +#endif diff --git a/source/_OLD_SquirrelBindings.h b/source/_OLD_SquirrelBindings.h new file mode 100644 index 000000000..26f125746 --- /dev/null +++ b/source/_OLD_SquirrelBindings.h @@ -0,0 +1,15 @@ +#pragma once + +#define USE_SQUIRREL 1 + +#if USE_SQUIRREL + +struct SQVM; +class SquirrelBindings +{ +public: + static void Bind( SQVM* a_SquirrelVM ); + static bool IsBound; +}; + +#endif diff --git a/source/cBlockArea.cpp b/source/cBlockArea.cpp new file mode 100644 index 000000000..810503f04 --- /dev/null +++ b/source/cBlockArea.cpp @@ -0,0 +1,626 @@ + +// BlockArea.cpp + +// Implements the cBlockArea object representing an area of block data that can be queried from cWorld and then accessed again without further queries +// The object also supports writing the blockdata back into cWorld, even into other coords + +#include "Globals.h" +#include "cBlockArea.h" +#include "cWorld.h" + + + + + +cBlockArea::cBlockArea(void) : + m_SizeX(0), + m_SizeY(0), + m_SizeZ(0), + m_BlockTypes(NULL), + m_BlockMetas(NULL), + m_BlockLight(NULL), + m_BlockSkyLight(NULL) +{ +} + + + + + +cBlockArea::~cBlockArea() +{ + Clear(); +} + + + + + +void cBlockArea::Clear(void) +{ + delete[] m_BlockTypes; m_BlockTypes = NULL; + delete[] m_BlockMetas; m_BlockMetas = NULL; + delete[] m_BlockLight; m_BlockLight = NULL; + delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; + m_SizeX = 0; + m_SizeY = 0; + m_SizeZ = 0; +} + + + + +bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes) +{ + // Normalize the coords: + if (a_MinBlockX > a_MaxBlockX) + { + std::swap(a_MinBlockX, a_MaxBlockX); + } + if (a_MinBlockY > a_MaxBlockY) + { + std::swap(a_MinBlockY, a_MaxBlockY); + } + if (a_MinBlockZ > a_MaxBlockZ) + { + std::swap(a_MinBlockZ, a_MaxBlockZ); + } + + // Check coords validity: + if (a_MinBlockY < 0) + { + LOGWARNING("cBlockArea:Read(): MinBlockY less than zero, adjusting to zero"); + a_MinBlockY = 0; + } + else if (a_MinBlockY >= cChunkDef::Height) + { + LOGWARNING("cBlockArea::Read(): MinBlockY more than chunk height, adjusting to chunk height"); + a_MinBlockY = cChunkDef::Height - 1; + } + if (a_MaxBlockY < 0) + { + LOGWARNING("cBlockArea:Read(): MaxBlockY less than zero, adjusting to zero"); + a_MaxBlockY = 0; + } + else if (a_MinBlockY >= cChunkDef::Height) + { + LOGWARNING("cBlockArea::Read(): MaxBlockY more than chunk height, adjusting to chunk height"); + a_MaxBlockY = cChunkDef::Height - 1; + } + + // Allocate the needed memory: + Clear(); + if (!SetSize(a_MaxBlockX - a_MinBlockX, a_MaxBlockY - a_MinBlockY, a_MaxBlockZ - a_MinBlockZ, a_DataTypes)) + { + return false; + } + m_OriginX = a_MinBlockX; + m_OriginY = a_MinBlockY; + m_OriginZ = a_MinBlockZ; + cChunkReader Reader(*this); + + // Convert block coords to chunks coords: + int MinChunkX, MaxChunkX; + int MinChunkZ, MaxChunkZ; + cChunkDef::AbsoluteToRelative(a_MinBlockX, a_MinBlockY, a_MinBlockZ, MinChunkX, MinChunkZ); + cChunkDef::AbsoluteToRelative(a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ, MaxChunkX, MaxChunkZ); + + // Query block data: + if (!a_World->ForEachChunkInRect(MinChunkX, MaxChunkX, MinChunkZ, MaxChunkZ, Reader)) + { + Clear(); + return false; + } + return true; +} + + + + + +bool cBlockArea::Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) +{ + // TODO + ASSERT(!"Not implemented yet"); + return false; +} + + + + + + +void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType) +{ + if (m_BlockTypes == NULL) + { + LOGWARNING("cBlockArea: BlockTypes have not been read!"); + return; + } + m_BlockTypes[MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_BlockType; +} + + + + + +void cBlockArea::SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) +{ + SetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType); +} + + + + + +void cBlockArea::SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta) +{ + SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockMeta, m_BlockMetas); +} + + + + + +void cBlockArea::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta) +{ + SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta, m_BlockMetas); +} + + + + + +void cBlockArea::SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight) +{ + SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockLight, m_BlockLight); +} + + + + + +void cBlockArea::SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight) +{ + SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockLight, m_BlockLight); +} + + + + + +void cBlockArea::SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight) +{ + SetRelNibble(a_RelX, a_RelY, a_RelZ, a_BlockSkyLight, m_BlockSkyLight); +} + + + + + +void cBlockArea::SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight) +{ + SetNibble(a_BlockX, a_BlockY, a_BlockZ, a_BlockSkyLight, m_BlockSkyLight); +} + + + + + +BLOCKTYPE cBlockArea::GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) +{ + if (m_BlockTypes == NULL) + { + LOGWARNING("cBlockArea: BlockTypes have not been read!"); + return E_BLOCK_AIR; + } + return m_BlockTypes[MakeIndex(a_RelX, a_RelY, a_RelZ)]; +} + + + + + +BLOCKTYPE cBlockArea::GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return GetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ); +} + + + + + +NIBBLETYPE cBlockArea::GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) +{ + return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockMetas); +} + + + + + +NIBBLETYPE cBlockArea::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockMetas); +} + + + + + +NIBBLETYPE cBlockArea::GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) +{ + return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockLight); +} + + + + + +NIBBLETYPE cBlockArea::GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockLight); +} + + + + + +NIBBLETYPE cBlockArea::GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) +{ + return GetRelNibble(a_RelX, a_RelY, a_RelZ, m_BlockSkyLight); +} + + + + + +NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return GetNibble(a_BlockX, a_BlockY, a_BlockZ, m_BlockSkyLight); +} + + + + + +int cBlockArea::GetDataTypes(void) const +{ + int res = 0; + if (m_BlockTypes != NULL) + { + res |= baTypes; + } + if (m_BlockMetas != NULL) + { + res |= baMetas; + } + if (m_BlockLight != NULL) + { + res |= baLight; + } + if (m_BlockSkyLight != NULL) + { + res |= baSkyLight; + } + return res; +} + + + + + +bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) +{ + ASSERT(m_BlockTypes == NULL); // Has been cleared + + if (a_DataTypes & baTypes) + { + m_BlockTypes = new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]; + if (m_BlockTypes == NULL) + { + return false; + } + } + if (a_DataTypes & baMetas) + { + m_BlockMetas = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; + if (m_BlockMetas == NULL) + { + delete[] m_BlockTypes; + return false; + } + } + if (a_DataTypes & baLight) + { + m_BlockLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; + if (m_BlockLight == NULL) + { + delete[] m_BlockMetas; + delete[] m_BlockTypes; + return false; + } + } + if (a_DataTypes & baSkyLight) + { + m_BlockSkyLight = new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]; + if (m_BlockSkyLight == NULL) + { + delete[] m_BlockLight; + delete[] m_BlockMetas; + delete[] m_BlockTypes; + return false; + } + } + m_SizeX = a_SizeX; + m_SizeY = a_SizeY; + m_SizeZ = a_SizeZ; + return true; +} + + + + + +int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) +{ + return a_RelX + a_RelZ * m_SizeZ + a_RelY * m_SizeX * m_SizeZ; +} + + + + + +void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) +{ + if (a_Array == NULL) + { + LOGWARNING("cBlockArea: datatype has not been read!"); + return; + } + a_Array[MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_Value; +} + + + + + +void cBlockArea::SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) +{ + SetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Value, a_Array); +} + + + + + +NIBBLETYPE cBlockArea::GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array) +{ + if (a_Array == NULL) + { + LOGWARNING("cBlockArea: datatype has not been read!"); + return 16; + } + return a_Array[MakeIndex(a_RelX, a_RelY, a_RelZ)]; +} + + + + + +NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array) +{ + return GetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Array); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBlockArea::cChunkReader: + +cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : + m_Area(a_Area), + m_OriginX(a_Area.m_OriginX), + m_OriginY(a_Area.m_OriginY), + m_OriginZ(a_Area.m_OriginZ) +{ +} + + + + + +void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc) +{ + int SizeY = m_Area.m_SizeY; + int MinY = m_OriginY; + + // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) + // OffX, OffZ are the offsets of the current chunk data from the area origin + // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders + int SizeX = cChunkDef::Width; + int SizeZ = cChunkDef::Width; + int OffX, OffZ; + int BaseX, BaseZ; + OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + if (OffX < 0) + { + BaseX = -OffX; + SizeX += OffX; // SizeX is decreased, OffX is negative + OffX = 0; + } + else + { + BaseX = 0; + } + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + if (OffZ < 0) + { + BaseZ = -OffZ; + SizeZ += OffZ; // SizeZ is decreased, OffZ is negative + OffZ = 0; + } + else + { + BaseZ = 0; + } + // If the chunk extends beyond the area in the X or Z axis, cut off the Size: + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + { + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + } + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + { + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + } + + for (int y = 0; y < SizeY; y++) + { + int ChunkY = MinY + y; + int AreaY = y; + for (int z = 0; z < SizeZ; z++) + { + int ChunkZ = BaseZ + z; + int AreaZ = OffZ + z; + for (int x = 0; x < SizeX; x++) + { + int ChunkX = BaseX + x; + int AreaX = OffX + x; + a_AreaDst[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = cChunkDef::GetNibble(a_ChunkSrc, ChunkX, ChunkY, ChunkZ); + } // for x + } // for z + } // for y +} + + + + + +bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) +{ + m_CurrentChunkX = a_ChunkX; + m_CurrentChunkZ = a_ChunkZ; + return true; +} + + + + + +void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) +{ + if (m_Area.m_BlockTypes == NULL) + { + // Don't want BlockTypes + return; + } + + int SizeY = m_Area.m_SizeY; + int MinY = m_OriginY; + + // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) + // OffX, OffZ are the offsets of the current chunk data from the area origin + // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders + int SizeX = cChunkDef::Width; + int SizeZ = cChunkDef::Width; + int OffX, OffZ; + int BaseX, BaseZ; + OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + if (OffX < 0) + { + BaseX = -OffX; + SizeX += OffX; // SizeX is decreased, OffX is negative + OffX = 0; + } + else + { + BaseX = 0; + } + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + if (OffZ < 0) + { + BaseZ = -OffZ; + SizeZ += OffZ; // SizeZ is decreased, OffZ is negative + OffZ = 0; + } + else + { + BaseZ = 0; + } + // If the chunk extends beyond the area in the X or Z axis, cut off the Size: + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + { + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + } + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + { + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + } + + for (int y = 0; y < SizeY; y++) + { + int ChunkY = MinY + y; + int AreaY = y; + for (int z = 0; z < SizeZ; z++) + { + int ChunkZ = BaseZ + z; + int AreaZ = OffZ + z; + for (int x = 0; x < SizeX; x++) + { + int ChunkX = BaseX + x; + int AreaX = OffX + x; + m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = cChunkDef::GetBlock(a_BlockTypes, ChunkX, ChunkY, ChunkZ); + } // for x + } // for z + } // for y +} + + + + + +void cBlockArea::cChunkReader::BlockMeta(const NIBBLETYPE * a_BlockMetas) +{ + if (m_Area.m_BlockMetas == NULL) + { + // Don't want metas + return; + } + CopyNibbles(m_Area.m_BlockMetas, a_BlockMetas); +} + + + + + +void cBlockArea::cChunkReader::BlockLight(const NIBBLETYPE * a_BlockLight) +{ + if (m_Area.m_BlockLight == NULL) + { + // Don't want light + return; + } + CopyNibbles(m_Area.m_BlockLight, a_BlockLight); +} + + + + + +void cBlockArea::cChunkReader::BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) +{ + if (m_Area.m_BlockSkyLight == NULL) + { + // Don't want skylight + return; + } + CopyNibbles(m_Area.m_BlockSkyLight, a_BlockSkyLight); +} + + + + + diff --git a/source/cBlockArea.h b/source/cBlockArea.h new file mode 100644 index 000000000..5abdab3bb --- /dev/null +++ b/source/cBlockArea.h @@ -0,0 +1,147 @@ + +// BlockArea.h + +// Interfaces to the cBlockArea object representing an area of block data that can be queried from cWorld and then accessed again without further queries +// The object also supports writing the blockdata back into cWorld, even into other coords + + + + + +#pragma once + + + + + +// fwd: "cWorld.h" +class cWorld; + + + + + +// tolua_begin +class cBlockArea +{ + // tolua_end + DISALLOW_COPY_AND_ASSIGN(cBlockArea); + // tolua_begin + +public: + + /// What data is to be queried (bit-mask) + enum + { + baTypes = 1, + baMetas = 2, + baLight = 4, + baSkyLight = 8, + } ; + + cBlockArea(void); + ~cBlockArea(); + + /// Clears the data stored to reclaim memory + void Clear(void); + + /// Reads an area of blocks specified. Returns true if successful. All coords are inclusive. + bool Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes = baTypes | baMetas); + + /// Writes the area back into cWorld at the coords specified. Returns true if successful. + bool Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes = baTypes | baMetas); + + // TODO: Write() is not too good an interface: if it fails, there's no way to repeat only for the parts that didn't write + // A better way may be to return a list of cBlockAreas for each part that didn't succeed writing, so that the caller may try again + + // Setters: + void SetRelBlockType (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); + void SetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); + void SetRelBlockMeta (int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta); + void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta); + void SetRelBlockLight (int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight); + void SetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight); + void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight); + void SetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight); + + // Getters: + BLOCKTYPE GetRelBlockType (int a_RelX, int a_RelY, int a_RelZ); + BLOCKTYPE GetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ); + NIBBLETYPE GetRelBlockMeta (int a_RelX, int a_RelY, int a_RelZ); + NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); + NIBBLETYPE GetRelBlockLight (int a_RelX, int a_RelY, int a_RelZ); + NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ); + NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ); + NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Returns the datatypes that are stored in the object (bitmask of baXXX values) + int GetDataTypes(void) const; + + // tolua_end + + // Clients can use these for faster access to all blocktypes. Be careful though! + /// Returns the internal pointer to the block types + BLOCKTYPE * GetBlockTypes(void) { return m_BlockTypes; } + int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; } + + // tolua_begin + +protected: + + // tolua_end + + class cChunkReader : + public cChunkDataCallback + { + public: + cChunkReader(cBlockArea & a_Area); + + protected: + cBlockArea & m_Area; + int m_OriginX; + int m_OriginY; + int m_OriginZ; + int m_CurrentChunkX; + int m_CurrentChunkZ; + + void CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc); + + // cChunkDataCallback overrides: + virtual bool Coords (int a_ChunkX, int a_ChunkZ) override; + virtual void BlockTypes (const BLOCKTYPE * a_BlockTypes) override; + virtual void BlockMeta (const NIBBLETYPE * a_BlockMetas) override; + virtual void BlockLight (const NIBBLETYPE * a_BlockLight) override; + virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override; + } ; + + // tolua_begin + + int m_OriginX; + int m_OriginY; + int m_OriginZ; + int m_SizeX; + int m_SizeY; + int m_SizeZ; + + BLOCKTYPE * m_BlockTypes; + NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access + NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access + NIBBLETYPE * m_BlockSkyLight; // Each light value is stored as a separate byte for faster access + + bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes); + + int MakeIndex(int a_RelX, int a_RelY, int a_RelZ); + + // Basic Setters: + void SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); + void SetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); + + // Basic Getters: + NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array); + NIBBLETYPE GetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array); +} ; +// tolua_end + + + + diff --git a/source/cChunk.cpp b/source/cChunk.cpp index cd94e3413..489af5cc9 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -27,7 +27,7 @@ #include "cBlockToPickup.h" #include "MersenneTwister.h" #include "cPlayer.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "cPluginManager.h" #include "packets/cPacket_DestroyEntity.h" diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index f152911e8..4cf21c850 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -5,6 +5,7 @@ #include "cPlugin.h" #include "cPlugin_Lua.h" #include "cPlugin_NewLua.h" +#include "cPlugin_Squirrel.h" #include "cWebAdmin.h" #include "cItem.h" #include "cRoot.h" @@ -12,10 +13,12 @@ #include "../iniFile/iniFile.h" #include "tolua++.h" -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" +#include "squirrelbindings/SquirrelFunctions.h" + #if USE_SQUIRREL #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include + #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) #endif @@ -70,11 +73,8 @@ void cPluginManager::ReloadPluginsNow() UnloadPluginsNow(); #if USE_SQUIRREL - if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script - { - SquirrelVM::Init(); - SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); - } + CloseSquirrelVM(); + OpenSquirrelVM(); #endif // USE_SQUIRREL cIniFile IniFile("settings.ini"); @@ -129,26 +129,11 @@ void cPluginManager::ReloadPluginsNow() if( !PluginFile.empty() ) { LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); - try - { - SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); - try - { - SquirrelVM::RunScript( SquirrelScript ); - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); - } - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); - } + + this->AddPlugin(new cPlugin_Squirrel(PluginFile.c_str())); } } #endif // USE_SQUIRREL - } } @@ -195,7 +180,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) if (a_Hook == HOOK_CHAT) { if (a_NumArgs != 2) - { + { return false; } va_list argptr; @@ -221,6 +206,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) return true; } } + return false; } diff --git a/source/cPlugin_Squirrel.cpp b/source/cPlugin_Squirrel.cpp new file mode 100644 index 000000000..aa7f7f023 --- /dev/null +++ b/source/cPlugin_Squirrel.cpp @@ -0,0 +1,352 @@ +#include "Globals.h" +#include "cPlugin_Squirrel.h" +#include "squirrelbindings/SquirrelFunctions.h" +#include "squirrelbindings/SquirrelBindings.h" +#include "squirrelbindings/cSquirrelBaseClass.h" + + +cPlugin_Squirrel::cPlugin_Squirrel( const char* a_PluginName ) +{ + SetLanguage( cPlugin::E_SQUIRREL ); + m_PluginName = a_PluginName; +} + +cPlugin_Squirrel::~cPlugin_Squirrel() +{ + delete m_PluginName; + delete m_Plugin; +} + +bool cPlugin_Squirrel::Initialize() +{ + cCSLock Lock(m_CriticalSection); + + std::string PluginPath = std::string("Plugins/") + m_PluginName + ".nut"; + + Sqrat::Script script; + script.CompileFile(PluginPath); + if(script.IsNull()) + { + LOGERROR("Unable to run script \"%s\"", m_PluginName); + } + + try { + script.Run(); + + Sqrat::Function construct(Sqrat::RootTable(), m_PluginName); + + if(construct.IsNull()) + { + LOGERROR("Constructor for Plugin \"%s\" not found.", m_PluginName); + return false; + } + + Sqrat::Object obj = construct.Evaluate(); + + ((cSquirrelBaseClass *) obj.GetInstanceUP())->setInstance(this); + + m_Plugin = new SquirrelObject(obj); + + + Sqrat::Object PluginName = obj.GetSlot("name"); + if(!PluginName.IsNull()) + { + this->SetName(PluginName.Cast()); + } + + Sqrat::Function init = m_Plugin->GetFunction("Initialize"); + if(init.IsNull()) + { + LOGERROR("Can not initialize plugin \"%s\"", m_PluginName); + return false; + } + + return init.Evaluate(); + + } catch(Sqrat::Exception &e) + { + LOGERROR("Initialisation of \"%s\" failed: %s", m_PluginName, e.Message().c_str()); + return false; + } +} + + + + + +void cPlugin_Squirrel::OnDisable() +{ + cCSLock Lock(m_CriticalSection); + + m_Plugin->GetFunction("OnDisable").Execute(); +} + + + + + +void cPlugin_Squirrel::Tick(float a_Dt) +{ + cCSLock Lock( m_CriticalSection ); + + m_Plugin->GetFunction("OnTick").Execute(a_Dt); +} + + + + + +bool cPlugin_Squirrel::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnCollectItem").Evaluate(a_Pickup, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + + return m_Plugin->GetFunction("OnDisconnect").Evaluate(a_Reason, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnBlockPlace").Evaluate(a_PacketData, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnBlockDig").Evaluate(a_PacketData, a_Player, a_PickupItem); +} + + + + + +bool cPlugin_Squirrel::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnChat").Evaluate(a_Chat, a_Player); + +} + + + + + +bool cPlugin_Squirrel::OnLogin( cPacket_Login* a_PacketData ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnLogin").Evaluate(a_PacketData); +} + + + + + +void cPlugin_Squirrel::OnPlayerSpawn( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerSpawn").Execute(a_Player); + +} + + + + + +bool cPlugin_Squirrel::OnPlayerJoin( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerJoin").Evaluate(a_Player); +} + + + + + +void cPlugin_Squirrel::OnPlayerMove( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerMove").Execute(a_Player); + +} + + + + + +void cPlugin_Squirrel::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnTakeDamage")(a_Pawn, a_TakeDamageInfo); +} + + + + + +bool cPlugin_Squirrel::OnKilled( cPawn* a_Killed, cEntity* a_Killer ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnKilled").Evaluate(a_Killed, a_Killer); +} + + + + + +void cPlugin_Squirrel::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnChunkGenerated")(a_World, a_ChunkX, a_ChunkZ); +} + + + + + +bool cPlugin_Squirrel::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnChunkGenerating").Evaluate(a_World, a_ChunkX, a_ChunkZ, a_pLuaChunk); +} + + + + + +bool cPlugin_Squirrel::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnPreCrafting").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); + +} + + + + + +bool cPlugin_Squirrel::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnCraftingNoRecipe").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); +} + + + + + +bool cPlugin_Squirrel::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnPostCrafting").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); +} + + + + + +bool cPlugin_Squirrel::OnBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnBlockToPickup").Evaluate(a_BlockType, a_BlockMeta, (cPlayer *) a_Player, a_EquippedItem, a_Pickups); + +} + + + + + +bool cPlugin_Squirrel::OnWeatherChanged(cWorld * a_World) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnWeatherChanged").Evaluate(a_World); +} + + + + + +bool cPlugin_Squirrel::OnUpdatingSign( + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, + AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4 +) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnUpdatingSign") + .Evaluate( + a_World, + a_BlockX, + a_BlockY, + a_BlockZ, + a_Line1, + a_Line2, + a_Line3, + a_Line4 + ); +} + + + + + +bool cPlugin_Squirrel::OnUpdatedSign( + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, + const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 +) +{ + return m_Plugin->GetFunction("OnUpdatedSign") + .Evaluate( + a_World, + a_BlockX, + a_BlockY, + a_BlockZ, + a_Line1, + a_Line2, + a_Line3, + a_Line4 + ); +} diff --git a/source/cPlugin_Squirrel.h b/source/cPlugin_Squirrel.h new file mode 100644 index 000000000..cd05e117a --- /dev/null +++ b/source/cPlugin_Squirrel.h @@ -0,0 +1,42 @@ +#pragma once +#include "cPlugin.h" +#include +#include "squirrelbindings/SquirrelObject.h" + +class cPlugin_Squirrel : public cPlugin +{ +public: + cPlugin_Squirrel(const char* a_PluginName); + ~cPlugin_Squirrel(); + + void OnDisable(); + bool Initialize(); + + void Tick(float a_Dt); + + bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; + bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override; + bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override; + bool OnChat (const char* a_Chat, cPlayer* a_Player ) override; + bool OnLogin (cPacket_Login* a_PacketData ) override; + void OnPlayerSpawn (cPlayer* a_Player ) override; + bool OnPlayerJoin (cPlayer* a_Player ) override; + void OnPlayerMove (cPlayer* a_Player ) override; + void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override; + bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; + void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; + bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + bool OnWeatherChanged (cWorld * a_World) override; + bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) override; + bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + +protected: + const char * m_PluginName; + cCriticalSection m_CriticalSection; + SquirrelObject *m_Plugin; +}; \ No newline at end of file diff --git a/source/cVine.h b/source/cVine.h index a99a98aca..d4bc99c1a 100644 --- a/source/cVine.h +++ b/source/cVine.h @@ -19,6 +19,5 @@ public: default: return 0xf; }; - return 0xf; } //tolua_export }; //tolua_export \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index d379fdd17..03dea6f01 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -6,16 +6,17 @@ #include //std::exception #include //std::signal #include //exit() +#include "squirrelbindings/SquirrelFunctions.h" #ifdef _WIN32 #include #endif // _WIN32 -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" #if USE_SQUIRREL #pragma warning(push) #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include + #pragma warning(pop) #endif @@ -189,7 +190,7 @@ int main( int argc, char **argv ) } #if USE_SQUIRREL - SquirrelVM::Shutdown(); + CloseSquirrelVM(); #endif #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) diff --git a/source/squirrelbindings/SquirrelBindings.cpp b/source/squirrelbindings/SquirrelBindings.cpp new file mode 100644 index 000000000..27a82c306 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.cpp @@ -0,0 +1,52 @@ +#include "Globals.h" +#include "SquirrelBindings.h" +#include "SquirrelFunctions.h" + +#include "cSquirrelBaseClass.h" + +#include "../cPlayer.h" + +using namespace Sqrat; + + + +void BindSquirrel(HSQUIRRELVM vm) +{ + RootTable() + .Bind("Plugin", Class() + .Func("AddHook", &cSquirrelBaseClass::AddHook) + ); + RootTable().Bind("cPlayer", Class() + .Func("GetName", &cPlayer::GetName) + ); + + + RootTable().Func("print", &sqPrint); + + + ConstTable().Enum("Hook", Enumeration() + .Const("Tick", cPluginManager::HOOK_TICK) + .Const("Chat", cPluginManager::HOOK_CHAT) + .Const("CollectItem", cPluginManager::HOOK_COLLECT_ITEM) + .Const("BlockDig", cPluginManager::HOOK_BLOCK_DIG) + .Const("BlockPlace", cPluginManager::HOOK_BLOCK_PLACE) + .Const("Disconnect", cPluginManager::HOOK_DISCONNECT) + .Const("Handshake", cPluginManager::HOOK_HANDSHAKE) + .Const("Login", cPluginManager::HOOK_LOGIN) + .Const("PlayerSpawn", cPluginManager::HOOK_PLAYER_SPAWN) + .Const("PlayerJoin", cPluginManager::HOOK_PLAYER_JOIN) + .Const("PlayerMove", cPluginManager::HOOK_PLAYER_MOVE) + .Const("TakeDamage", cPluginManager::HOOK_TAKE_DAMAGE) + .Const("Killed", cPluginManager::HOOK_KILLED) + .Const("ChunkGenerated", cPluginManager::HOOK_CHUNK_GENERATED) + .Const("ChunkGenerating", cPluginManager::HOOK_CHUNK_GENERATING) + .Const("BlockToDrops", cPluginManager::HOOK_BLOCK_TO_DROPS) + .Const("PreCrafting", cPluginManager::HOOK_PRE_CRAFTING) + .Const("CraftingNoRecipe", cPluginManager::HOOK_CRAFTING_NO_RECIPE) + .Const("PostCrafting", cPluginManager::HOOK_POST_CRAFTING) + .Const("BlockToPickup", cPluginManager::HOOK_BLOCK_TO_PICKUP) + .Const("WeatherChanged", cPluginManager::HOOK_WEATHER_CHANGED) + .Const("UpdatingSign", cPluginManager::HOOK_UPDATING_SIGN) + .Const("UpdatedSign", cPluginManager::HOOK_UPDATED_SIGN)); + +} \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelBindings.h b/source/squirrelbindings/SquirrelBindings.h new file mode 100644 index 000000000..1b71f5e86 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.h @@ -0,0 +1,13 @@ +#pragma once + + +#define USE_SQUIRREL 1 + +#if USE_SQUIRREL + +#include +#include + +void BindSquirrel(HSQUIRRELVM vm); + +#endif diff --git a/source/squirrelbindings/SquirrelFunctions.cpp b/source/squirrelbindings/SquirrelFunctions.cpp new file mode 100644 index 000000000..88871369d --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.cpp @@ -0,0 +1,65 @@ + +#include "Globals.h" +#include "SquirrelFunctions.h" +#include "SquirrelBindings.h" + +static HSQUIRRELVM squirrelvm = NULL; + +SQInteger runtimeErrorHandler(HSQUIRRELVM a_VM) +{ + const SQChar *sErr = 0; + if(sq_gettop(a_VM) >= 1) + { + if(SQ_SUCCEEDED(sq_getstring(a_VM, 2, &sErr))) + { + LOGERROR("Squirrel Error: %s", sErr); + } + else + { + LOGERROR("Squirrel Error: Unknown Error"); + } + } + return 0; +} + +void compilerErrorHandler(HSQUIRRELVM v, + const SQChar* a_Desc, + const SQChar* a_Source, + SQInteger a_Line, + SQInteger a_Column) +{ + + LOGERROR("Squirrel Error: %s (%d:%d) %s", a_Source, a_Line, a_Column, a_Desc); +} + +HSQUIRRELVM OpenSquirrelVM() +{ + if(!squirrelvm) + { + squirrelvm = sq_open(1024); + Sqrat::DefaultVM::Set(squirrelvm); + + sq_newclosure(squirrelvm, runtimeErrorHandler, 0); + sq_seterrorhandler(squirrelvm); + + sq_setcompilererrorhandler(squirrelvm, compilerErrorHandler); + + BindSquirrel(squirrelvm); + } + return squirrelvm; +} + +void CloseSquirrelVM() +{ + if(squirrelvm) + { + sq_close(squirrelvm); + squirrelvm = NULL; + } +} + + +void sqPrint(SQChar * text) +{ + LOGINFO("%s", text); +} \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelFunctions.h b/source/squirrelbindings/SquirrelFunctions.h new file mode 100644 index 000000000..0d08a726c --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.h @@ -0,0 +1,6 @@ +#pragma once +#include +HSQUIRRELVM OpenSquirrelVM(); +void CloseSquirrelVM(); + +void sqPrint(SQChar * text); \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelObject.h b/source/squirrelbindings/SquirrelObject.h new file mode 100644 index 000000000..1ac6fa105 --- /dev/null +++ b/source/squirrelbindings/SquirrelObject.h @@ -0,0 +1,24 @@ +#pragma once +#include + +class SquirrelObject +{ +public: + SquirrelObject(Sqrat::Object a_Obj) + { + m_SquirrelObject = a_Obj; + } + + Sqrat::Function GetFunction(const char *methodName) + { + if(m_SquirrelObject.IsNull()) + return Sqrat::Function(); + + Sqrat::Function method(m_SquirrelObject, methodName); + return method; + } + +protected: + Sqrat::Object m_SquirrelObject; + +}; \ No newline at end of file diff --git a/source/squirrelbindings/cSquirrelBaseClass.h b/source/squirrelbindings/cSquirrelBaseClass.h new file mode 100644 index 000000000..e06301555 --- /dev/null +++ b/source/squirrelbindings/cSquirrelBaseClass.h @@ -0,0 +1,29 @@ +#pragma once +#include "SquirrelBindings.h" +#include "../cPlugin_Squirrel.h" +#include "../cPluginManager.h" +#include "cRoot.h" + +//The baseclass for squirrel plugins +class cSquirrelBaseClass +{ +public: + cSquirrelBaseClass() + : m_Instance(0) + { + } + + void setInstance(cPlugin_Squirrel *a_Instance) + { + m_Instance = a_Instance; + } + + void AddHook(short a_Hook) + { + if(m_Instance) + cRoot::Get()->GetPluginManager()->AddHook(m_Instance, (cPluginManager::PluginHook) a_Hook); + } + +protected: + cPlugin_Squirrel *m_Instance; +}; \ No newline at end of file -- cgit v1.2.3