1
0

Merge branch 'master' into cmake

This commit is contained in:
Tycho Bickerstaff 2013-12-10 23:01:35 +00:00
commit dd633d5a94
35 changed files with 641 additions and 566 deletions

View File

@ -88,7 +88,7 @@ CXX_OPTIONS += -Wall
###################################################
# Fix Crypto++ warnings in clang
ifeq ($(shell $(CXX) --version 2>&1 | grep -i -c "clang version"),1)
ifeq ($(shell $(CXX) --version 2>&1 | grep -i -c "clang"),1)
CC_OPTIONS += -DCRYPTOPP_DISABLE_ASM
CXX_OPTIONS += -DCRYPTOPP_DISABLE_ASM
endif

View File

@ -1862,6 +1862,17 @@ end
},
}, -- cServer
cTNTEntity =
{
Desc = "This class manages a TNT entity.",
Functions =
{
GetCounterTime = { Return = "number", Notes = "Returns the time until the entity explodes." },
GetMaxFuseTime = { Return = "number", Notes = "Returns how long the fuse was." },
},
Inherits = "cEntity",
},
cTracer =
{
Desc = [[

View File

@ -0,0 +1,24 @@
return
{
HOOK_WORLD_STARTED =
{
CalledWhen = "A {{cWorld|world}} is initialized",
DefaultFnName = "OnWorldStarted", -- also used as pagename
Desc = [[
This hook is called whenever a {{cWorld|world}} is initialized.
]],
Params =
{
{ Name = "World", Type = "{{cWorld}}", Notes = "World that is started" },
},
Returns = [[
If the function returns false or no value, the next plugin's callback is called. If the function
returns true, no other callback is called for this event. There is no overridable behavior.
]],
}, -- HOOK_WORLD_STARTED
}

@ -1 +1 @@
Subproject commit ede668bc7c310af49ad7354c00d3f11adbae792a
Subproject commit 351aff7efa94ce3c7ba733d5f83013e8a3fdfbfd

View File

@ -1,3 +0,0 @@
[Banned]
;PlayerName=1

View File

@ -1,17 +0,0 @@
[Admins]
Permissions=*
Color=c
[Mods]
Color=5
Inherits=Vips
Permissions=core.time,core.item
[Vips]
Permissions=core.teleport
Color=2
Inherits=Default
[Default]
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn,transapi.setlang,core.tell,core.me
Color=7

View File

@ -1,23 +0,0 @@
[FakeTruth]
Groups=Admins
[Duralex]
Groups=Admins
[Luthrandel]
Groups=Admins
[cruisecho]
Groups=Admins
[Kwen]
Groups=Admins
[aloe_vera]
Groups=Admins
[xoft]
Groups=Admins
[Player]
Groups=Admins

View File

@ -1,6 +0,0 @@
[WhiteListSettings]
WhiteListOn=0
[WhiteList]
;PlayerName=1

View File

@ -36,6 +36,7 @@ $cfile "../Entities/Pawn.h"
$cfile "../Entities/Player.h"
$cfile "../Entities/Pickup.h"
$cfile "../Entities/ProjectileEntity.h"
$cfile "../Entities/TNTEntity.h"
$cfile "../Server.h"
$cfile "../World.h"
$cfile "../Inventory.h"

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/08/13 18:11:12.
** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:45.
*/
#ifndef __cplusplus
@ -34,6 +34,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
#include "../Entities/Player.h"
#include "../Entities/Pickup.h"
#include "../Entities/ProjectileEntity.h"
#include "../Entities/TNTEntity.h"
#include "../Server.h"
#include "../World.h"
#include "../Inventory.h"
@ -218,7 +219,7 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cItemGrid");
tolua_usertype(tolua_S,"cHTTPServer::cCallbacks");
tolua_usertype(tolua_S,"cLuaWindow");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cHopperEntity");
tolua_usertype(tolua_S,"std::vector<AString>");
tolua_usertype(tolua_S,"cBlockEntityWithItems");
@ -226,15 +227,16 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cBlockArea");
tolua_usertype(tolua_S,"cGroup");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cTracer");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cBoundingBox");
tolua_usertype(tolua_S,"cArrowEntity");
tolua_usertype(tolua_S,"cDropSpenserEntity");
tolua_usertype(tolua_S,"cBoundingBox");
tolua_usertype(tolua_S,"cCuboid");
tolua_usertype(tolua_S,"Vector3i");
tolua_usertype(tolua_S,"cNoteEntity");
tolua_usertype(tolua_S,"Vector3d");
tolua_usertype(tolua_S,"cNoteEntity");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cBlockEntity");
tolua_usertype(tolua_S,"cCriticalSection");
tolua_usertype(tolua_S,"HTTPTemplateRequest");
@ -254,8 +256,8 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cDropperEntity");
tolua_usertype(tolua_S,"cProjectileEntity");
tolua_usertype(tolua_S,"cItemGrid::cListener");
tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cPlayer");
tolua_usertype(tolua_S,"cTNTEntity");
}
/* method: new of class cIniFile */
@ -11518,6 +11520,70 @@ static int tolua_AllToLua_cArrowEntity_SetIsCritical00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetCounterTime of class cTNTEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cTNTEntity_GetCounterTime00
static int tolua_AllToLua_cTNTEntity_GetCounterTime00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cTNTEntity",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cTNTEntity* self = (const cTNTEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCounterTime'", NULL);
#endif
{
double tolua_ret = (double) self->GetCounterTime();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetCounterTime'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetMaxFuseTime of class cTNTEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cTNTEntity_GetMaxFuseTime00
static int tolua_AllToLua_cTNTEntity_GetMaxFuseTime00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cTNTEntity",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cTNTEntity* self = (const cTNTEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxFuseTime'", NULL);
#endif
{
double tolua_ret = (double) self->GetMaxFuseTime();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetMaxFuseTime'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetDescription of class cServer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetDescription00
static int tolua_AllToLua_cServer_GetDescription00(lua_State* tolua_S)
@ -19926,6 +19992,41 @@ static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: CreateAndInitializeWorld of class cRoot */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_CreateAndInitializeWorld00
static int tolua_AllToLua_cRoot_CreateAndInitializeWorld00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateAndInitializeWorld'", NULL);
#endif
{
cWorld* tolua_ret = (cWorld*) self->CreateAndInitializeWorld(a_WorldName);
tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld");
tolua_pushcppstring(tolua_S,(const char*)a_WorldName);
}
}
return 2;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'CreateAndInitializeWorld'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetPrimaryServerVersion of class cRoot */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPrimaryServerVersion00
static int tolua_AllToLua_cRoot_GetPrimaryServerVersion00(lua_State* tolua_S)
@ -29797,6 +29898,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"HOOK_UPDATING_SIGN",cPluginManager::HOOK_UPDATING_SIGN);
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED);
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGING",cPluginManager::HOOK_WEATHER_CHANGING);
tolua_constant(tolua_S,"HOOK_WORLD_STARTED",cPluginManager::HOOK_WORLD_STARTED);
tolua_constant(tolua_S,"HOOK_WORLD_TICK",cPluginManager::HOOK_WORLD_TICK);
tolua_constant(tolua_S,"HOOK_NUM_HOOKS",cPluginManager::HOOK_NUM_HOOKS);
tolua_constant(tolua_S,"HOOK_MAX",cPluginManager::HOOK_MAX);
@ -30957,6 +31059,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_cclass(tolua_S,"cFireChargeEntity","cFireChargeEntity","cProjectileEntity",NULL);
tolua_beginmodule(tolua_S,"cFireChargeEntity");
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cTNTEntity","cTNTEntity","cEntity",NULL);
tolua_beginmodule(tolua_S,"cTNTEntity");
tolua_function(tolua_S,"GetCounterTime",tolua_AllToLua_cTNTEntity_GetCounterTime00);
tolua_function(tolua_S,"GetMaxFuseTime",tolua_AllToLua_cTNTEntity_GetMaxFuseTime00);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cServer","cServer","",NULL);
tolua_beginmodule(tolua_S,"cServer");
tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00);
@ -31348,6 +31455,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00);
tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00);
tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00);
tolua_function(tolua_S,"CreateAndInitializeWorld",tolua_AllToLua_cRoot_CreateAndInitializeWorld00);
tolua_function(tolua_S,"GetPrimaryServerVersion",tolua_AllToLua_cRoot_GetPrimaryServerVersion00);
tolua_function(tolua_S,"SetPrimaryServerVersion",tolua_AllToLua_cRoot_SetPrimaryServerVersion00);
tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/08/13 18:11:13.
** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:46.
*/
/* Exported function */

View File

@ -93,6 +93,7 @@ public:
virtual 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, cPlayer * a_Player) = 0;
virtual bool OnWeatherChanged (cWorld & a_World) = 0;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0;
virtual bool OnWorldStarted (cWorld & a_World) = 0;
virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) = 0;
/** Handles the command split into a_Split, issued by player a_Player.

View File

@ -1143,6 +1143,21 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
bool cPluginLua::OnWorldStarted(cWorld & a_World)
{
cCSLock Lock(m_CriticalSection);
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WORLD_STARTED];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), &a_World);
}
return false;
}
bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{
cCSLock Lock(m_CriticalSection);

View File

@ -90,6 +90,7 @@ public:
virtual 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, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld & a_World) override;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override;
virtual bool OnWorldStarted (cWorld & a_World) override;
virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override;
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override;

View File

@ -1209,6 +1209,27 @@ bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewW
bool cPluginManager::CallHookWorldStarted(cWorld & a_World)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_STARTED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWorldStarted(a_World))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK);

View File

@ -106,6 +106,7 @@ public: // tolua_export
HOOK_UPDATING_SIGN,
HOOK_WEATHER_CHANGED,
HOOK_WEATHER_CHANGING,
HOOK_WORLD_STARTED,
HOOK_WORLD_TICK,
// Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants,
@ -191,6 +192,7 @@ public: // tolua_export
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld & a_World);
bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather);
bool CallHookWorldStarted (cWorld & a_World);
bool CallHookWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec);
bool DisablePlugin(const AString & a_PluginName); // tolua_export

View File

@ -375,7 +375,7 @@ void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX
MicroY = a_BlockY + 0.5;
MicroZ = a_BlockZ + 0.5;
// Add random offset second (this causes pickups to spawn inside blocks most times, it's a little buggy)
// Add random offset second
MicroX += r1.rand(1) - 0.5;
MicroZ += r1.rand(1) - 0.5;

View File

@ -773,6 +773,28 @@ void cByteBuffer::ReadAll(AString & a_Data)
bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes)
{
if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes))
{
// There's not enough source bytes or space in the dest BB
return false;
}
char buf[1024];
while (a_NumBytes > 0)
{
int num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes;
VERIFY(ReadBuf(buf, num));
VERIFY(a_Dst.Write(buf, num));
a_NumBytes -= num;
}
return true;
}
void cByteBuffer::CommitRead(void)
{
CHECK_THREAD;

View File

@ -42,6 +42,9 @@ public:
/// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already)
int GetReadableSpace(void) const;
/// Returns the current data start index. For debugging purposes.
int GetDataStart(void) const { return m_DataStart; }
/// Returns true if the specified amount of bytes are available for reading
bool CanReadBytes(int a_Count) const;
@ -106,6 +109,9 @@ public:
/// Reads all available data into a_Data
void ReadAll(AString & a_Data);
/// Reads the specified number of bytes and writes it into the destinatio bytebuffer. Returns true on success.
bool ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes);
/// Removes the bytes that have been read from the ringbuffer
void CommitRead(void);

View File

@ -706,8 +706,7 @@ void cChunk::ProcessQueuedSetBlocks(void)
{
// Current world age is bigger than/equal to target world age - delay time reached AND
// Previous block type was the same as current block type (to prevent duplication)
// Since blocktypes were the same, we just need to set the meta
SetMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockMeta);
SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); // SetMeta doesn't send to client
itr = m_SetBlockQueue.erase(itr);
LOGD("Successfully set queued block - previous and current types matched");
}
@ -1335,6 +1334,7 @@ void cChunk::WakeUpSimulators(void)
{
cSimulator * WaterSimulator = m_World->GetWaterSimulator();
cSimulator * LavaSimulator = m_World->GetLavaSimulator();
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
int BaseX = m_PosX * cChunkDef::Width;
int BaseZ = m_PosZ * cChunkDef::Width;
for (int x = 0; x < Width; x++)
@ -1345,7 +1345,16 @@ void cChunk::WakeUpSimulators(void)
int BlockZ = z + BaseZ;
for (int y = GetHeight(x, z); y >= 0; y--)
{
switch (cChunkDef::GetBlock(m_BlockTypes, x, y, z))
BLOCKTYPE Block = cChunkDef::GetBlock(m_BlockTypes, x, y, z);
// The redstone sim takes multiple blocks, use the inbuilt checker
if (RedstoneSimulator->IsAllowedBlock(Block))
{
RedstoneSimulator->AddBlock(BlockX, y, BlockZ, this);
continue;
}
switch (Block)
{
case E_BLOCK_WATER:
{
@ -1357,6 +1366,10 @@ void cChunk::WakeUpSimulators(void)
LavaSimulator->AddBlock(BlockX, y, BlockZ, this);
break;
}
default:
{
break;
}
} // switch (BlockType)
} // for y
} // for z

View File

@ -2160,12 +2160,12 @@ void cClientHandle::PacketBufferFull(void)
void cClientHandle::PacketUnknown(unsigned char a_PacketType)
void cClientHandle::PacketUnknown(UInt32 a_PacketType)
{
LOGERROR("Unknown packet type 0x%02x from client \"%s\" @ %s", a_PacketType, m_Username.c_str(), m_IPString.c_str());
LOGERROR("Unknown packet type 0x%x from client \"%s\" @ %s", a_PacketType, m_Username.c_str(), m_IPString.c_str());
AString Reason;
Printf(Reason, "Unknown [C->S] PacketType: 0x%02x", a_PacketType);
Printf(Reason, "Unknown [C->S] PacketType: 0x%x", a_PacketType);
SendDisconnect(Reason);
Destroy();
}

View File

@ -160,7 +160,7 @@ public:
// Calls that cProtocol descendants use to report state:
void PacketBufferFull(void);
void PacketUnknown(unsigned char a_PacketType);
void PacketUnknown(UInt32 a_PacketType);
void PacketError(unsigned char a_PacketType);
// Calls that cProtocol descendants use for handling packets:

View File

@ -7,6 +7,7 @@
#include "DeadlockDetect.h"
#include "Root.h"
#include "World.h"
# include <cstdlib>
@ -137,11 +138,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
void cDeadlockDetect::DeadlockDetected(void)
{
ASSERT(!"Deadlock detected");
// TODO: Make a crashdump / coredump
// Crash the server intentionally:
*((volatile int *)0) = 0;
abort();
}

View File

@ -40,21 +40,25 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client)
void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
{
cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 4));
if (a_ClosestPlayer)
cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 5));
if (a_ClosestPlayer != NULL)
{
Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition());
a_PlayerPos.y++;
Vector3f a_Distance(a_PlayerPos - GetPosition());
if (a_Distance.Length() < 0.1f)
double Distance(a_Distance.Length());
if (Distance < 0.1f)
{
LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward);
a_ClosestPlayer->DeltaExperience(m_Reward);
a_ClosestPlayer->SendExperience();
Destroy(true);
}
a_Distance.y = 0;
a_Distance.Normalize();
a_Distance *= 3;
a_Distance *= ((float) (5.5 - Distance));
SetSpeedX( a_Distance.x );
SetSpeedY( a_Distance.y );
SetSpeedZ( a_Distance.z );
BroadcastMovementUpdate();
}
HandlePhysics(a_Dt, a_Chunk);
}

View File

@ -1393,7 +1393,12 @@ void cPlayer::LoadPermissionsFromDisk()
}
else
{
LOGWARN("Failed to read the users.ini file. The player will be added only to the Default group.");
LOGWARN("Regenerating users.ini, player %s will be added to the \"Default\" group", m_PlayerName.c_str());
IniFile.AddHeaderComment(" This is the file in which the group the player belongs to is stored");
IniFile.AddHeaderComment(" The format is: [PlayerName] | Groups=GroupName");
IniFile.SetValue(m_PlayerName, "Groups", "Default");
IniFile.WriteFile("users.ini");
AddToGroup("Default");
}
ResolvePermissions();
@ -1410,7 +1415,7 @@ bool cPlayer::LoadFromDisk()
LOGINFO("Player %s has permissions:", m_PlayerName.c_str() );
for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
{
if( itr->second ) LOGINFO("%s", itr->first.c_str() );
if( itr->second ) LOG(" - %s", itr->first.c_str() );
}
AString SourceFile;

View File

@ -6,13 +6,14 @@
// tolua_begin
class cTNTEntity :
public cEntity
{
typedef cEntity super;
public:
// tolua_end
CLASS_PROTODEF(cTNTEntity);
cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec);
@ -21,11 +22,14 @@ public:
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
double GetCounterTime(void) const { return m_Counter; } // tolua_export
double GetMaxFuseTime(void) const { return m_MaxFuseTime; } // tolua_export
protected:
double m_Counter; ///< How much time has elapsed since the object was created, in seconds
double m_MaxFuseTime; ///< How long the fuse is, in seconds
};
}; // tolua_export

View File

@ -47,8 +47,25 @@ cGroupManager::cGroupManager()
cIniFile IniFile;
if (!IniFile.ReadFile("groups.ini"))
{
LOGWARNING("groups.ini inaccessible, no groups are defined");
return;
LOGWARNING("Regenerating groups.ini, all groups will be reset");
IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file");
IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators");
IniFile.SetValue("Owner", "Permissions", "*", true);
IniFile.SetValue("Owner", "Color", "2", true);
IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.teleport,core.ban,core.unban,core.save-all,core.toggledownfall");
IniFile.SetValue("Moderator", "Color", "2", true);
IniFile.SetValue("Moderator", "Inherits", "Player", true);
IniFile.SetValue("Player", "Permissions", "core.build", true);
IniFile.SetValue("Player", "Color", "f", true);
IniFile.SetValue("Player", "Inherits", "Default", true);
IniFile.SetValue("Default", "Permissions", "core.help,core.playerlist,core.pluginlist,core.spawn,core.listworlds,core.back,core.motd,core.gotoworld,core.coords,core.viewdistance", true);
IniFile.SetValue("Default", "Color", "f", true);
IniFile.WriteFile("groups.ini");
}
unsigned int NumKeys = IniFile.GetNumKeys();

View File

@ -274,6 +274,7 @@ void cMonster::KilledBy(cEntity * a_Killer)
case cMonster::mtWolf:
{
Reward = m_World->GetTickRandomNumber(2) + 1;
break;
}
// Monsters
@ -291,25 +292,30 @@ void cMonster::KilledBy(cEntity * a_Killer)
case cMonster::mtMagmaCube:
{
Reward = 6 + (m_World->GetTickRandomNumber(2));
break;
}
case cMonster::mtBlaze:
{
Reward = 10;
break;
}
// Bosses
case cMonster::mtEnderDragon:
{
Reward = 12000;
break;
}
case cMonster::mtWither:
{
Reward = 50;
break;
}
default:
{
Reward = 0;
break;
}
}
m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward);

View File

@ -29,23 +29,23 @@ Implements the 1.7.x protocol classes:
#define HANDLE_READ(Proc, Type, Var) \
#define HANDLE_READ(ByteBuf, Proc, Type, Var) \
Type Var; \
m_ReceivedData.Proc(Var);
ByteBuf.Proc(Var);
#define HANDLE_PACKET_READ(Proc, Type, Var) \
#define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \
Type Var; \
{ \
if (!m_ReceivedData.Proc(Var)) \
if (!ByteBuf.Proc(Var)) \
{ \
m_ReceivedData.CheckValid(); \
ByteBuf.CheckValid(); \
return false; \
} \
m_ReceivedData.CheckValid(); \
ByteBuf.CheckValid(); \
}
@ -921,6 +921,7 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property
void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
{
LOGD("Received %d bytes of data", a_Size);
if (!m_ReceivedData.Write(a_Data, a_Size))
{
// Too much data in the incoming queue, report to caller:
@ -932,6 +933,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
while (true)
{
UInt32 PacketLen;
int PacketStart = m_ReceivedData.GetDataStart();
if (!m_ReceivedData.ReadVarInt(PacketLen))
{
// Not enough data
@ -942,35 +944,38 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
// The full packet hasn't been received yet
return;
}
cByteBuffer bb(PacketLen + 1);
VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen));
m_ReceivedData.CommitRead();
// Write one NUL extra, so that we can detect over-reads
bb.Write("\0", 1);
UInt32 PacketType;
UInt32 Mark1 = m_ReceivedData.GetReadableSpace();
if (!m_ReceivedData.ReadVarInt(PacketType))
if (!bb.ReadVarInt(PacketType))
{
// Not enough data
return;
}
UInt32 NumBytesRead = Mark1 - m_ReceivedData.GetReadableSpace();
HandlePacket(PacketType, PacketLen - NumBytesRead);
// DEBUG:
LOGD("Packet 0x%x, len %d (0x%x), start at %d", PacketType, PacketLen, PacketLen, PacketStart);
if (Mark1 - m_ReceivedData.GetReadableSpace() > PacketLen)
HandlePacket(bb, PacketType);
if (bb.GetReadableSpace() != 1)
{
// Read more than packet length, report as error
// Read more or less than packet length, report as error
ASSERT(!"Read wrong number of bytes!");
m_Client->PacketError(PacketType);
}
// Go to packet end in any case:
m_ReceivedData.ResetRead();
m_ReceivedData.ReadVarInt(PacketType);
m_ReceivedData.SkipRead(PacketLen);
m_ReceivedData.CommitRead();
} // while (true)
}
void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
switch (m_State)
{
@ -979,8 +984,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Status
switch (a_PacketType)
{
case 0x00: HandlePacketStatusRequest(a_RemainingBytes); return;
case 0x01: HandlePacketStatusPing (a_RemainingBytes); return;
case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return;
case 0x01: HandlePacketStatusPing (a_ByteBuffer); return;
}
break;
}
@ -990,8 +995,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Login
switch (a_PacketType)
{
case 0x00: HandlePacketLoginStart(a_RemainingBytes); return;
case 0x01: HandlePacketLoginEncryptionResponse(a_RemainingBytes); return;
case 0x00: HandlePacketLoginStart (a_ByteBuffer); return;
case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return;
}
break;
}
@ -1001,29 +1006,29 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Game
switch (a_PacketType)
{
case 0x00: HandlePacketKeepAlive (a_RemainingBytes); return;
case 0x01: HandlePacketChatMessage (a_RemainingBytes); return;
case 0x02: HandlePacketUseEntity (a_RemainingBytes); return;
case 0x03: HandlePacketPlayer (a_RemainingBytes); return;
case 0x04: HandlePacketPlayerPos (a_RemainingBytes); return;
case 0x05: HandlePacketPlayerLook (a_RemainingBytes); return;
case 0x06: HandlePacketPlayerPosLook (a_RemainingBytes); return;
case 0x07: HandlePacketBlockDig (a_RemainingBytes); return;
case 0x08: HandlePacketBlockPlace (a_RemainingBytes); return;
case 0x09: HandlePacketSlotSelect (a_RemainingBytes); return;
case 0x0a: HandlePacketAnimation (a_RemainingBytes); return;
case 0x0b: HandlePacketEntityAction (a_RemainingBytes); return;
case 0x0c: HandlePacketSteerVehicle (a_RemainingBytes); return;
case 0x0d: HandlePacketWindowClose (a_RemainingBytes); return;
case 0x0e: HandlePacketWindowClick (a_RemainingBytes); return;
case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return;
case 0x01: HandlePacketChatMessage (a_ByteBuffer); return;
case 0x02: HandlePacketUseEntity (a_ByteBuffer); return;
case 0x03: HandlePacketPlayer (a_ByteBuffer); return;
case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return;
case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return;
case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return;
case 0x07: HandlePacketBlockDig (a_ByteBuffer); return;
case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return;
case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return;
case 0x0a: HandlePacketAnimation (a_ByteBuffer); return;
case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return;
case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return;
case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return;
case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return;
case 0x0f: // Confirm transaction - not used in MCS
case 0x10: HandlePacketCreativeInventoryAction(a_RemainingBytes); return;
case 0x12: HandlePacketUpdateSign (a_RemainingBytes); return;
case 0x13: HandlePacketPlayerAbilities (a_RemainingBytes); return;
case 0x14: HandlePacketTabComplete (a_RemainingBytes); return;
case 0x15: HandlePacketClientSettings (a_RemainingBytes); return;
case 0x16: HandlePacketClientStatus (a_RemainingBytes); return;
case 0x17: HandlePacketPluginMessage (a_RemainingBytes); return;
case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return;
case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return;
case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return;
case 0x14: HandlePacketTabComplete (a_ByteBuffer); return;
case 0x15: HandlePacketClientSettings (a_ByteBuffer); return;
case 0x16: HandlePacketClientStatus (a_ByteBuffer); return;
case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return;
}
break;
}
@ -1031,27 +1036,16 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Unknown packet type, report to the client:
m_Client->PacketUnknown(a_PacketType);
m_ReceivedData.SkipRead(a_RemainingBytes);
m_ReceivedData.CommitRead();
}
void cProtocol172::HandlePacketStatusPing(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer)
{
ASSERT(a_RemainingBytes == 8);
if (a_RemainingBytes != 8)
{
m_Client->PacketError(0x01);
m_ReceivedData.SkipRead(a_RemainingBytes);
m_ReceivedData.CommitRead();
return;
}
Int64 Timestamp;
m_ReceivedData.ReadBEInt64(Timestamp);
m_ReceivedData.CommitRead();
a_ByteBuffer.ReadBEInt64(Timestamp);
cPacketizer Pkt(*this, 0x01); // Ping packet
Pkt.WriteInt64(Timestamp);
@ -1061,12 +1055,8 @@ void cProtocol172::HandlePacketStatusPing(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketStatusRequest(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{
// No more bytes in this packet
ASSERT(a_RemainingBytes == 0);
m_ReceivedData.CommitRead();
// Send the response:
AString Response = "{\"version\":{\"name\":\"1.7.2\",\"protocol\":4},\"players\":{";
AppendPrintf(Response, "\"max\":%u,\"online\":%u,\"sample\":[]},",
@ -1086,7 +1076,7 @@ void cProtocol172::HandlePacketStatusRequest(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer)
{
// TODO: Add protocol encryption
}
@ -1095,10 +1085,10 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginStart(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
{
AString Username;
m_ReceivedData.ReadVarUTF8String(Username);
a_ByteBuffer.ReadVarUTF8String(Username);
// TODO: Protocol encryption should be set up here if not localhost / auth
@ -1117,10 +1107,10 @@ void cProtocol172::HandlePacketLoginStart(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketAnimation(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, EntityID);
HANDLE_READ(ReadByte, Byte, Animation);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Animation);
m_Client->HandleAnimation(Animation);
}
@ -1128,13 +1118,13 @@ void cProtocol172::HandlePacketAnimation(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockDig(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadByte, Byte, Status);
HANDLE_READ(ReadBEInt, int, BlockX);
HANDLE_READ(ReadByte, Byte, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ);
HANDLE_READ(ReadByte, Byte, Face);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, Face, Status);
}
@ -1142,18 +1132,18 @@ void cProtocol172::HandlePacketBlockDig(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockPlace(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, BlockX);
HANDLE_READ(ReadByte, Byte, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ);
HANDLE_READ(ReadByte, Byte, Face);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
cItem Item;
ReadItem(Item);
ReadItem(a_ByteBuffer, Item);
HANDLE_READ(ReadByte, Byte, CursorX);
HANDLE_READ(ReadByte, Byte, CursorY);
HANDLE_READ(ReadByte, Byte, CursorZ);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ);
m_Client->HandleRightClick(BlockX, BlockY, BlockZ, Face, CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem());
}
@ -1161,9 +1151,9 @@ void cProtocol172::HandlePacketBlockPlace(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketChatMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadVarUTF8String, AString, Message);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message);
m_Client->HandleChat(Message);
}
@ -1171,14 +1161,14 @@ void cProtocol172::HandlePacketChatMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientSettings(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadVarUTF8String, AString, Locale);
HANDLE_READ(ReadByte, Byte, ViewDistance);
HANDLE_READ(ReadByte, Byte, ChatFlags);
HANDLE_READ(ReadByte, Byte, Unused);
HANDLE_READ(ReadByte, Byte, Difficulty);
HANDLE_READ(ReadByte, Byte, ShowCape);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Difficulty);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape);
// TODO: handle in m_Client
}
@ -1186,9 +1176,9 @@ void cProtocol172::HandlePacketClientSettings(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientStatus(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadByte, Byte, ActionID);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ActionID);
switch (ActionID)
{
case 0:
@ -1216,11 +1206,11 @@ void cProtocol172::HandlePacketClientStatus(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEShort, short, SlotNum);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
cItem Item;
if (!ReadItem(Item))
if (!ReadItem(a_ByteBuffer, Item))
{
return;
}
@ -1231,11 +1221,11 @@ void cProtocol172::HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketEntityAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, PlayerID);
HANDLE_READ(ReadByte, Byte, Action);
HANDLE_READ(ReadBEInt, int, JumpBoost);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, PlayerID);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Action);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, JumpBoost);
m_Client->HandleEntityAction(PlayerID, Action);
}
@ -1243,9 +1233,9 @@ void cProtocol172::HandlePacketEntityAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketKeepAlive(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, KeepAliveID);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, KeepAliveID);
m_Client->HandleKeepAlive(KeepAliveID);
}
@ -1253,9 +1243,9 @@ void cProtocol172::HandlePacketKeepAlive(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayer(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayer(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBool, bool, IsOnGround);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
// TODO: m_Client->HandlePlayerOnGround(IsOnGround);
}
@ -1263,11 +1253,11 @@ void cProtocol172::HandlePacketPlayer(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerAbilities(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadByte, Byte, Flags);
HANDLE_READ(ReadBEFloat, float, FlyingSpeed);
HANDLE_READ(ReadBEFloat, float, WalkingSpeed);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed);
// TODO: m_Client->HandlePlayerAbilities();
}
@ -1275,11 +1265,11 @@ void cProtocol172::HandlePacketPlayerAbilities(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEFloat, float, Yaw);
HANDLE_READ(ReadBEFloat, float, Pitch);
HANDLE_READ(ReadBool, bool, IsOnGround);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround);
}
@ -1287,13 +1277,13 @@ void cProtocol172::HandlePacketPlayerLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPos(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEDouble, double, PosX);
HANDLE_READ(ReadBEDouble, double, PosY);
HANDLE_READ(ReadBEDouble, double, Stance);
HANDLE_READ(ReadBEDouble, double, PosZ);
HANDLE_READ(ReadBool, bool, IsOnGround);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerPos(PosX, PosY, PosZ, Stance, IsOnGround);
}
@ -1301,15 +1291,15 @@ void cProtocol172::HandlePacketPlayerPos(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPosLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEDouble, double, PosX);
HANDLE_READ(ReadBEDouble, double, PosY);
HANDLE_READ(ReadBEDouble, double, Stance);
HANDLE_READ(ReadBEDouble, double, PosZ);
HANDLE_READ(ReadBEFloat, float, Yaw);
HANDLE_READ(ReadBEFloat, float, Pitch);
HANDLE_READ(ReadBool, bool, IsOnGround);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Stance, Yaw, Pitch, IsOnGround);
}
@ -1317,12 +1307,12 @@ void cProtocol172::HandlePacketPlayerPosLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPluginMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadVarUTF8String, AString, Channel);
HANDLE_READ(ReadBEShort, short, Length);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length);
AString Data;
m_ReceivedData.ReadString(Data, Length);
a_ByteBuffer.ReadString(Data, Length);
// TODO: m_Client->HandlePluginMessage(Channel, Data);
}
@ -1330,9 +1320,9 @@ void cProtocol172::HandlePacketPluginMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSlotSelect(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEShort, short, SlotNum);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
m_Client->HandleSlotSelected(SlotNum);
}
@ -1340,12 +1330,12 @@ void cProtocol172::HandlePacketSlotSelect(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSteerVehicle(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEFloat, float, Forward);
HANDLE_READ(ReadBEFloat, float, Sideways);
HANDLE_READ(ReadBool, bool, ShouldJump);
HANDLE_READ(ReadBool, bool, ShouldUnmount);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldJump);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldUnmount);
if (ShouldUnmount)
{
m_Client->HandleUnmount();
@ -1360,9 +1350,9 @@ void cProtocol172::HandlePacketSteerVehicle(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketTabComplete(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadVarUTF8String, AString, Text);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text);
m_Client->HandleTabCompletion(Text);
}
@ -1370,15 +1360,15 @@ void cProtocol172::HandlePacketTabComplete(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUpdateSign(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, BlockX);
HANDLE_READ(ReadBEShort, short, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ);
HANDLE_READ(ReadVarUTF8String, AString, Line1);
HANDLE_READ(ReadVarUTF8String, AString, Line2);
HANDLE_READ(ReadVarUTF8String, AString, Line3);
HANDLE_READ(ReadVarUTF8String, AString, Line4);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, BlockY);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line1);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line2);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line3);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line4);
m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
}
@ -1386,10 +1376,10 @@ void cProtocol172::HandlePacketUpdateSign(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUseEntity(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadBEInt, int, EntityID);
HANDLE_READ(ReadByte, Byte, MouseButton);
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, MouseButton);
m_Client->HandleUseEntity(EntityID, (MouseButton == 1));
}
@ -1397,15 +1387,15 @@ void cProtocol172::HandlePacketUseEntity(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadChar, char, WindowID);
HANDLE_READ(ReadBEShort, short, SlotNum);
HANDLE_READ(ReadByte, Byte, Button);
HANDLE_READ(ReadBEShort, short, TransactionID);
HANDLE_READ(ReadByte, Byte, Mode);
HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Button);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode);
cItem Item;
ReadItem(Item);
ReadItem(a_ByteBuffer, Item);
// Convert Button, Mode, SlotNum and HeldItem into eClickAction:
eClickAction Action;
@ -1434,6 +1424,12 @@ void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes)
case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break;
case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break;
case 0x0600: Action = caDblClick; break;
default:
{
LOGWARNING("Unhandled window click mode / button combination: %d (0x%x)", (Mode << 8) | Button, (Mode << 8) | Button);
Action = caUnknown;
break;
}
}
m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item);
@ -1443,9 +1439,9 @@ void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClose(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(ReadChar, char, WindowID);
HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
m_Client->HandleWindowClose(WindowID);
}
@ -1492,9 +1488,9 @@ void cProtocol172::SendData(const char * a_Data, int a_Size)
bool cProtocol172::ReadItem(cItem & a_Item)
bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
{
HANDLE_PACKET_READ(ReadBEShort, short, ItemType);
HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType);
if (ItemType == -1)
{
// The item is empty, no more data follows
@ -1503,8 +1499,8 @@ bool cProtocol172::ReadItem(cItem & a_Item)
}
a_Item.m_ItemType = ItemType;
HANDLE_PACKET_READ(ReadChar, char, ItemCount);
HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage);
HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, ItemCount);
HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemDamage);
a_Item.m_ItemCount = ItemCount;
a_Item.m_ItemDamage = ItemDamage;
if (ItemCount <= 0)
@ -1512,7 +1508,7 @@ bool cProtocol172::ReadItem(cItem & a_Item)
a_Item.Empty();
}
HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength);
HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, MetadataLength);
if (MetadataLength <= 0)
{
return true;
@ -1520,7 +1516,7 @@ bool cProtocol172::ReadItem(cItem & a_Item)
// Read the metadata
AString Metadata;
if (!m_ReceivedData.ReadString(Metadata, MetadataLength))
if (!a_ByteBuffer.ReadString(Metadata, MetadataLength))
{
return false;
}

View File

@ -205,39 +205,39 @@ protected:
void AddReceivedData(const char * a_Data, int a_Size);
/// Reads and handles the packet. The packet length and type have already been read.
void HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes);
void HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType);
// Packet handlers while in the Status state (m_State == 1):
void HandlePacketStatusPing (UInt32 a_RemainingBytes);
void HandlePacketStatusRequest(UInt32 a_RemainingBytes);
void HandlePacketStatusPing (cByteBuffer & a_ByteBuffer);
void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer);
// Packet handlers while in the Login state (m_State == 2):
void HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes);
void HandlePacketLoginStart (UInt32 a_RemainingBytes);
void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer);
void HandlePacketLoginStart (cByteBuffer & a_ByteBuffer);
// Packet handlers while in the Game state (m_State == 3):
void HandlePacketAnimation (UInt32 a_RemainingBytes);
void HandlePacketBlockDig (UInt32 a_RemainingBytes);
void HandlePacketBlockPlace (UInt32 a_RemainingBytes);
void HandlePacketChatMessage (UInt32 a_RemainingBytes);
void HandlePacketClientSettings (UInt32 a_RemainingBytes);
void HandlePacketClientStatus (UInt32 a_RemainingBytes);
void HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes);
void HandlePacketEntityAction (UInt32 a_RemainingBytes);
void HandlePacketKeepAlive (UInt32 a_RemainingBytes);
void HandlePacketPlayer (UInt32 a_RemainingBytes);
void HandlePacketPlayerAbilities (UInt32 a_RemainingBytes);
void HandlePacketPlayerLook (UInt32 a_RemainingBytes);
void HandlePacketPlayerPos (UInt32 a_RemainingBytes);
void HandlePacketPlayerPosLook (UInt32 a_RemainingBytes);
void HandlePacketPluginMessage (UInt32 a_RemainingBytes);
void HandlePacketSlotSelect (UInt32 a_RemainingBytes);
void HandlePacketSteerVehicle (UInt32 a_RemainingBytes);
void HandlePacketTabComplete (UInt32 a_RemainingBytes);
void HandlePacketUpdateSign (UInt32 a_RemainingBytes);
void HandlePacketUseEntity (UInt32 a_RemainingBytes);
void HandlePacketWindowClick (UInt32 a_RemainingBytes);
void HandlePacketWindowClose (UInt32 a_RemainingBytes);
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer);
void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer);
void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);
void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer);
void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer);
void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
/// Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here.
@ -249,7 +249,7 @@ protected:
void SendCompass(const cWorld & a_World);
/// Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data
bool ReadItem(cItem & a_Item);
bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
/// Parses item metadata as read by ReadItem(), into the item enchantments.
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);

View File

@ -299,12 +299,31 @@ void cRoot::LoadWorlds(cIniFile & IniFile)
cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName)
{
if (m_WorldsByName[a_WorldName] != NULL)
{
return NULL;
}
cWorld* NewWorld = new cWorld(a_WorldName.c_str());
m_WorldsByName[a_WorldName] = NewWorld;
NewWorld->Start();
NewWorld->InitializeSpawn();
m_PluginManager->CallHookWorldStarted(*NewWorld);
return NewWorld;
}
void cRoot::StartWorlds(void)
{
for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
{
itr->second->Start();
itr->second->InitializeSpawn();
m_PluginManager->CallHookWorldStarted(*itr->second);
}
}

View File

@ -42,6 +42,7 @@ public:
cServer * GetServer(void) { return m_Server; } // tolua_export
cWorld * GetDefaultWorld(void); // tolua_export
cWorld * GetWorld(const AString & a_WorldName); // tolua_export
cWorld * CreateAndInitializeWorld(const AString & a_WorldName); // tolua_export
/// Calls the callback for each world; returns true if the callback didn't abort (return true)
bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<

View File

@ -50,7 +50,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu
// Check for duplicates:
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
for (cRedstoneSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
for (cRedstoneSimulatorChunkData::const_iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
{
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
{
@ -79,22 +79,20 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
// Check to see if PoweredBlocks have invalid items (source is air or unpowered)
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();)
{
sPoweredBlocks & Change = *itr;
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType;
NIBBLETYPE SourceBlockMeta;
if (!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta))
if (!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta))
{
continue;
}
if (SourceBlockType != Change.a_SourceBlock)
if (SourceBlockType != itr->a_SourceBlock)
{
itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock).c_str());
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
}
else if (
// Changeable sources
@ -105,7 +103,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
)
{
itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock).c_str());
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
}
else
{
@ -116,33 +114,31 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
// Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();)
{
sLinkedPoweredBlocks & Change = *itr;
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int MidRelX = itr->a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
int MidRelZ = itr->a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType;
NIBBLETYPE SourceBlockMeta;
BLOCKTYPE MiddleBlockType;
if (
!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
!a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType)
!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
!a_Chunk->UnboundedRelGetBlockType(MidRelX, itr->a_MiddlePos.y, MidRelZ, MiddleBlockType)
)
{
continue;
}
if (SourceBlockType != Change.a_SourceBlock)
if (SourceBlockType != itr->a_SourceBlock)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock).c_str());
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
}
else if (MiddleBlockType != Change.a_MiddleBlock)
else if (MiddleBlockType != itr->a_MiddleBlock)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock).c_str());
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
}
else if (
// Things that can send power through a block but which depends on meta
@ -152,7 +148,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock).c_str());
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
}
else
{
@ -162,19 +158,17 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end();)
{
sSimulatedPlayerToggleableList & Change = *itr;
int RelX = Change.a_BlockPos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType;
if (!a_Chunk->UnboundedRelGetBlockType(RelX, Change.a_BlockPos.y, RelZ, SourceBlockType))
if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType))
{
continue;
}
else if (!IsAllowedBlock(SourceBlockType))
{
LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list due to power state change", ItemToFullString(SourceBlockType).c_str());
LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list as block is no longer redstone", ItemToFullString(SourceBlockType).c_str());
itr = m_SimulatedPlayerToggleableBlocks.erase(itr);
}
else
@ -282,7 +276,7 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B
int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ;
AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
if (AreCoordsPowered(X, Y, Z))
if (AreCoordsDirectlyPowered(X, Y, Z))
{
// There was a match, torch goes off
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
@ -329,7 +323,7 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B
AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
// See if off state torch can be turned on again
if (AreCoordsPowered(X, Y, Z))
if (AreCoordsDirectlyPowered(X, Y, Z))
{
return; // Something matches, torch still powered
}
@ -416,7 +410,6 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
{
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath
}
else
{
@ -464,10 +457,12 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
{
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaToSet);
}
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath
}
// Wire still powered, power blocks beneath
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE);
if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire
{
switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
@ -630,7 +625,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int
// Self not in list, add self to list
sRepeatersDelayList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1;
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2); // Repeaters power off slower than they power on, so no +1. Why? No idea.
RC.a_ElapsedTicks = 0;
m_RepeatersDelayList.push_back(RC);
return;
@ -826,23 +821,27 @@ void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ
bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
bool cRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
{
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
{
sPoweredBlocks & Change = *itr;
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
return true;
}
}
return false;
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
bool cRedstoneSimulator::AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
{
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
{
sLinkedPoweredBlocks & Change = *itr;
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
return true;
}
@ -858,64 +857,60 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
{
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{
sPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta)
{
case 0x0:
{
// Flip the coords to check the back of the repeater
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break;
}
case 0x1:
{
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
case 0x2:
{
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break;
}
case 0x3:
{
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
}
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{
sLinkedPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta)
{
case 0x0:
{
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break;
}
case 0x1:
{
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
case 0x2:
{
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break;
}
case 0x3:
{
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
}
@ -932,15 +927,13 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ;
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{
sPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); // Piston meta is based on what direction they face, so we can do this
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
return true;
}
@ -950,15 +943,13 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
a_BlockZ = OldZ;
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{
sLinkedPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta);
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (!itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
return true;
}
@ -976,13 +967,11 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
bool cRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered)
{
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
for (SimulatedPlayerToggleableList::const_iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
{
sSimulatedPlayerToggleableList & Change = *itr;
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
if (Change.WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current?
if (itr->WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current?
{
return false; // It was, coordinates are no longer simulated
}
@ -1007,222 +996,72 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE) // Wires can't power another wire through a block
{
if (m_World.GetBlock(a_BlockX - 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
break;
}
case BLOCK_FACE_XP:
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX + 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
break;
}
case BLOCK_FACE_YM:
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
break;
}
case BLOCK_FACE_YP:
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY + 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
break;
}
case BLOCK_FACE_ZM:
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1);
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 2) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break;
}
case BLOCK_FACE_ZP:
{
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1);
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 2) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break;
}
default:
@ -1270,13 +1109,11 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block
return;
}
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
{
sPoweredBlocks & Change = *itr;
if (
Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
)
{
// Check for duplicates
@ -1302,24 +1139,28 @@ void cRedstoneSimulator::SetBlockLinkedPowered(
BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock
)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR)
BLOCKTYPE DestBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (DestBlock == E_BLOCK_AIR)
{
// Don't set air, fixes some bugs (wires powering themselves)
return;
}
if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ)))
if (!IsViableMiddleBlock(a_MiddleBlock))
{
return;
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
if ((a_SourceBlock == E_BLOCK_REDSTONE_WIRE) && (DestBlock == E_BLOCK_REDSTONE_WIRE))
{
sLinkedPoweredBlocks & Change = *itr;
// Wires cannot power another wire through a block
return;
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
{
if (
Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
Change.a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) &&
Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
itr->a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) &&
itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
)
{
// Check for duplicates
@ -1344,24 +1185,25 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a
{
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
{
sSimulatedPlayerToggleableList & Change = *itr;
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
if (Change.WasLastStatePowered != WasLastStatePowered)
{
// If power states different, erase the old listing in preparation to add new one
m_SimulatedPlayerToggleableBlocks.erase(itr);
break;
}
else
{
// If states the same, just ignore
return;
}
continue;
}
if (itr->WasLastStatePowered != WasLastStatePowered)
{
// If power states different, update listing
itr->WasLastStatePowered = WasLastStatePowered;
return;
}
else
{
// If states the same, just ignore
return;
}
}
// We have arrive here; no block must be in list - add one
sSimulatedPlayerToggleableList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.WasLastStatePowered = WasLastStatePowered;

View File

@ -127,7 +127,11 @@ private:
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
/// <summary>Returns if a coordinate is powered or linked powered</summary>
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
/// <summary>Returns if a coordinate is in the directly powered blocks list</summary>
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Returns if a coordinate is in the indirectly powered blocks list</summary>
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Returns if a coordinate was marked as simulated (for blocks toggleable by players)</summary>
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
/// <summary>Returns if a repeater is powered</summary>
@ -150,6 +154,9 @@ private:
switch (Block)
{
// Add SOLID but not viable middle blocks here
case E_BLOCK_PISTON:
case E_BLOCK_PISTON_EXTENSION:
case E_BLOCK_STICKY_PISTON:
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
{

View File

@ -392,6 +392,7 @@ public:
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
/// Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp