2014-02-09 12:56:16 -05:00
|
|
|
|
|
|
|
// LuaChunkStay.cpp
|
|
|
|
|
2014-02-10 16:47:10 -05:00
|
|
|
// Implements the cLuaChunkStay class representing a cChunkStay binding for plugins, used by cWorld:ChunkStay() Lua API
|
2014-02-09 12:56:16 -05:00
|
|
|
|
|
|
|
#include "Globals.h"
|
|
|
|
#include "LuaChunkStay.h"
|
2014-02-10 16:47:10 -05:00
|
|
|
#include "PluginLua.h"
|
2014-02-09 12:56:16 -05:00
|
|
|
#include "../World.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-10 16:47:10 -05:00
|
|
|
cLuaChunkStay::cLuaChunkStay(cPluginLua & a_Plugin) :
|
|
|
|
m_Plugin(a_Plugin),
|
|
|
|
m_LuaState(NULL)
|
2014-02-09 14:39:45 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-10 16:47:10 -05:00
|
|
|
bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos)
|
2014-02-09 12:56:16 -05:00
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
// This function is expected to be called just once, with all the coords in a table
|
|
|
|
ASSERT(m_Chunks.empty());
|
|
|
|
|
|
|
|
cPluginLua::cOperation Op(m_Plugin);
|
|
|
|
cLuaState & L = Op();
|
|
|
|
|
|
|
|
// Check that we got a table:
|
|
|
|
if (!lua_istable(L, a_ChunkCoordTableStackPos))
|
2014-02-09 12:56:16 -05:00
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
LOGWARNING("%s: The parameter is not a table of coords (got %s). Ignoring the call.",
|
|
|
|
__FUNCTION__, lua_typename(L, lua_type(L, a_ChunkCoordTableStackPos))
|
|
|
|
);
|
|
|
|
L.LogStackTrace();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add each set of coords:
|
|
|
|
int NumChunks = luaL_getn(L, a_ChunkCoordTableStackPos);
|
2014-05-01 17:38:35 -04:00
|
|
|
m_Chunks.reserve((size_t)NumChunks);
|
2014-02-10 16:47:10 -05:00
|
|
|
for (int idx = 1; idx <= NumChunks; idx++)
|
|
|
|
{
|
|
|
|
// Push the idx-th element of the array onto stack top, check that it's a table:
|
|
|
|
lua_rawgeti(L, a_ChunkCoordTableStackPos, idx);
|
|
|
|
if (!lua_istable(L, -1))
|
|
|
|
{
|
|
|
|
LOGWARNING("%s: Element #%d is not a table (got %s). Ignoring the element.",
|
|
|
|
__FUNCTION__, idx, lua_typename(L, -1)
|
|
|
|
);
|
|
|
|
L.LogStackTrace();
|
|
|
|
lua_pop(L, 1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
AddChunkCoord(L, idx);
|
|
|
|
lua_pop(L, 1);
|
2014-02-09 12:56:16 -05:00
|
|
|
}
|
2014-02-10 16:47:10 -05:00
|
|
|
|
|
|
|
// If there are no chunks, log a warning and return failure:
|
|
|
|
if (m_Chunks.empty())
|
|
|
|
{
|
|
|
|
LOGWARNING("%s: Zero chunks to stay.", __FUNCTION__);
|
|
|
|
L.LogStackTrace();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// All ok
|
|
|
|
return true;
|
2014-02-09 12:56:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-17 16:15:34 -04:00
|
|
|
void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index)
|
2014-02-09 14:39:45 -05:00
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
// Check that the element has 2 coords:
|
|
|
|
int NumCoords = luaL_getn(L, -1);
|
|
|
|
if (NumCoords != 2)
|
2014-02-09 14:39:45 -05:00
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
LOGWARNING("%s: Element #%d doesn't contain 2 coords (got %d). Ignoring the element.",
|
|
|
|
__FUNCTION__, a_Index, NumCoords
|
|
|
|
);
|
2014-02-09 14:39:45 -05:00
|
|
|
return;
|
|
|
|
}
|
2014-02-10 16:47:10 -05:00
|
|
|
|
|
|
|
// Read the two coords from the element:
|
|
|
|
lua_rawgeti(L, -1, 1);
|
|
|
|
lua_rawgeti(L, -2, 2);
|
|
|
|
int ChunkX = luaL_checkint(L, -2);
|
|
|
|
int ChunkZ = luaL_checkint(L, -1);
|
|
|
|
lua_pop(L, 2);
|
|
|
|
|
|
|
|
// Check that a coord is not yet present:
|
|
|
|
for (cChunkCoordsVector::iterator itr = m_Chunks.begin(), end = m_Chunks.end(); itr != end; ++itr)
|
|
|
|
{
|
|
|
|
if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
|
|
|
|
{
|
|
|
|
LOGWARNING("%s: Element #%d is a duplicate, ignoring it.",
|
|
|
|
__FUNCTION__, a_Index
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} // for itr - m_Chunks[]
|
|
|
|
|
|
|
|
m_Chunks.push_back(cChunkCoords(ChunkX, ZERO_CHUNK_Y, ChunkZ));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cLuaChunkStay::Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPos, int a_OnAllChunksAvailableStackPos)
|
|
|
|
{
|
|
|
|
// Get the references to the callback functions:
|
|
|
|
m_LuaState = &m_Plugin.GetLuaState();
|
|
|
|
m_OnChunkAvailable.RefStack(*m_LuaState, a_OnChunkAvailableStackPos);
|
|
|
|
m_OnAllChunksAvailable.RefStack(*m_LuaState, a_OnAllChunksAvailableStackPos);
|
|
|
|
|
|
|
|
// Enable the ChunkStay:
|
|
|
|
super::Enable(a_ChunkMap);
|
2014-02-09 14:39:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-09 12:56:16 -05:00
|
|
|
void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ)
|
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
cPluginLua::cOperation Op(m_Plugin);
|
|
|
|
Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ);
|
2014-02-09 12:56:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-10 16:47:10 -05:00
|
|
|
bool cLuaChunkStay::OnAllChunksAvailable(void)
|
2014-02-09 12:56:16 -05:00
|
|
|
{
|
2014-02-10 16:47:10 -05:00
|
|
|
{
|
|
|
|
// Call the callback:
|
|
|
|
cPluginLua::cOperation Op(m_Plugin);
|
|
|
|
Op().Call((int)m_OnAllChunksAvailable);
|
|
|
|
|
|
|
|
// Remove the callback references - they won't be needed anymore
|
|
|
|
m_OnChunkAvailable.UnRef();
|
|
|
|
m_OnAllChunksAvailable.UnRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable the ChunkStay by returning true
|
|
|
|
return true;
|
2014-02-09 12:56:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-10 16:47:10 -05:00
|
|
|
void cLuaChunkStay::OnDisabled(void)
|
|
|
|
{
|
|
|
|
// This object is no longer needed, delete it
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|