Merge pull request #891 from mc-server/fixes
Fixes to redstone & general
This commit is contained in:
commit
b7e074b10b
@ -46,6 +46,10 @@ macro(set_flags)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
|
||||
|
||||
add_flags_cxx("-pthread")
|
||||
endif()
|
||||
|
||||
@ -56,6 +60,10 @@ macro(set_flags)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
|
||||
endif()
|
||||
|
||||
# We use a signed char (fixes #640 on RasPi)
|
||||
|
@ -504,6 +504,10 @@ enum
|
||||
E_META_PLANKS_BIRCH = 2,
|
||||
E_META_PLANKS_JUNGLE = 3,
|
||||
|
||||
// E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas:
|
||||
E_META_PRESSURE_PLATE_RAISED = 0,
|
||||
E_META_PRESSURE_PLATE_DEPRESSED = 1,
|
||||
|
||||
// E_BLOCK_QUARTZ_BLOCK metas:
|
||||
E_META_QUARTZ_NORMAL = 0,
|
||||
E_META_QUARTZ_CHISELLED = 1,
|
||||
|
@ -2145,7 +2145,7 @@ void cClientHandle::SendExplosion(double a_BlockX, double a_BlockY, double a_Blo
|
||||
}
|
||||
|
||||
// Update the statistics:
|
||||
m_NumExplosionsThisTick += 1;
|
||||
m_NumExplosionsThisTick++;
|
||||
|
||||
m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion);
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ void cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
AddSpeed(a_TDI.Knockback * 2);
|
||||
}
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_HURT);
|
||||
m_World->BroadcastEntityStatus(*this, esGenericHurt);
|
||||
|
||||
if (m_Health <= 0)
|
||||
{
|
||||
@ -479,7 +479,7 @@ void cEntity::KilledBy(cEntity * a_Killer)
|
||||
GetDrops(Drops, a_Killer);
|
||||
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ());
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_DEAD);
|
||||
m_World->BroadcastEntityStatus(*this, esGenericDead);
|
||||
}
|
||||
|
||||
|
||||
@ -519,15 +519,14 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a_Chunk.IsValid())
|
||||
{
|
||||
cChunk * NextChunk = a_Chunk.GetNeighborChunk(POSX_TOINT, POSZ_TOINT);
|
||||
|
||||
if ((NextChunk == NULL) || !NextChunk->IsValid())
|
||||
if (!a_Chunk.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Position changed -> super::Tick() called
|
||||
GET_AND_VERIFY_CURRENT_CHUNK(NextChunk, POSX_TOINT, POSZ_TOINT)
|
||||
|
||||
TickBurning(*NextChunk);
|
||||
|
||||
if (GetPosY() < VOID_BOUNDARY)
|
||||
@ -548,9 +547,9 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
HandleAir();
|
||||
}
|
||||
|
||||
// None of the above functions change position, we remain in the chunk of NextChunk
|
||||
HandlePhysics(a_Dt, *NextChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -559,34 +558,30 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
int BlockX = POSX_TOINT;
|
||||
int BlockY = POSY_TOINT;
|
||||
int BlockZ = POSZ_TOINT;
|
||||
|
||||
// Position changed -> super::HandlePhysics() called
|
||||
GET_AND_VERIFY_CURRENT_CHUNK(NextChunk, BlockX, BlockZ)
|
||||
|
||||
// TODO Add collision detection with entities.
|
||||
a_Dt /= 1000; // Convert from msec to sec
|
||||
Vector3d NextPos = Vector3d(GetPosX(),GetPosY(),GetPosZ());
|
||||
Vector3d NextSpeed = Vector3d(GetSpeedX(),GetSpeedY(),GetSpeedZ());
|
||||
int BlockX = (int) floor(NextPos.x);
|
||||
int BlockY = (int) floor(NextPos.y);
|
||||
int BlockZ = (int) floor(NextPos.z);
|
||||
Vector3d NextPos = Vector3d(GetPosX(), GetPosY(), GetPosZ());
|
||||
Vector3d NextSpeed = Vector3d(GetSpeedX(), GetSpeedY(), GetSpeedZ());
|
||||
|
||||
if ((BlockY >= cChunkDef::Height) || (BlockY < 0))
|
||||
{
|
||||
// Outside of the world
|
||||
|
||||
cChunk * NextChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ);
|
||||
// See if we can commit our changes. If not, we will discard them.
|
||||
if (NextChunk != NULL)
|
||||
{
|
||||
SetSpeed(NextSpeed);
|
||||
NextPos += (NextSpeed * a_Dt);
|
||||
SetPosition(NextPos);
|
||||
}
|
||||
|
||||
AddSpeedY(m_Gravity * a_Dt);
|
||||
AddPosition(GetSpeed() * a_Dt);
|
||||
return;
|
||||
}
|
||||
|
||||
int RelBlockX = BlockX - (a_Chunk.GetPosX() * cChunkDef::Width);
|
||||
int RelBlockZ = BlockZ - (a_Chunk.GetPosZ() * cChunkDef::Width);
|
||||
BLOCKTYPE BlockIn = a_Chunk.GetBlock( RelBlockX, BlockY, RelBlockZ );
|
||||
BLOCKTYPE BlockBelow = (BlockY > 0) ? a_Chunk.GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
|
||||
int RelBlockX = BlockX - (NextChunk->GetPosX() * cChunkDef::Width);
|
||||
int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width);
|
||||
BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ );
|
||||
BLOCKTYPE BlockBelow = (BlockY > 0) ? NextChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
|
||||
if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block
|
||||
{
|
||||
if (m_bOnGround) // check if it's still on the ground
|
||||
@ -616,7 +611,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
bool IsNoAirSurrounding = true;
|
||||
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
|
||||
{
|
||||
if (!a_Chunk.UnboundedRelGetBlockType(RelBlockX + gCrossCoords[i].x, BlockY, RelBlockZ + gCrossCoords[i].z, GotBlock))
|
||||
if (!NextChunk->UnboundedRelGetBlockType(RelBlockX + gCrossCoords[i].x, BlockY, RelBlockZ + gCrossCoords[i].z, GotBlock))
|
||||
{
|
||||
// The pickup is too close to an unloaded chunk, bail out of any physics handling
|
||||
return;
|
||||
@ -764,20 +759,8 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
}
|
||||
|
||||
BlockX = (int) floor(NextPos.x);
|
||||
BlockZ = (int) floor(NextPos.z);
|
||||
|
||||
cChunk * NextChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ);
|
||||
// See if we can commit our changes. If not, we will discard them.
|
||||
if (NextChunk != NULL)
|
||||
{
|
||||
if (NextPos.x != GetPosX()) SetPosX(NextPos.x);
|
||||
if (NextPos.y != GetPosY()) SetPosY(NextPos.y);
|
||||
if (NextPos.z != GetPosZ()) SetPosZ(NextPos.z);
|
||||
if (NextSpeed.x != GetSpeedX()) SetSpeedX(NextSpeed.x);
|
||||
if (NextSpeed.y != GetSpeedY()) SetSpeedY(NextSpeed.y);
|
||||
if (NextSpeed.z != GetSpeedZ()) SetSpeedZ(NextSpeed.z);
|
||||
}
|
||||
SetPosition(NextPos);
|
||||
SetSpeed(NextSpeed);
|
||||
}
|
||||
|
||||
|
||||
@ -981,13 +964,13 @@ void cEntity::HandleAir(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AirTickTimer -= 1;
|
||||
m_AirTickTimer--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reduce air supply
|
||||
m_AirLevel -= 1;
|
||||
m_AirLevel--;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1099,15 +1082,15 @@ void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
|
||||
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
{
|
||||
//We need to keep updating the clients when there is movement or if there was a change in speed and after 2 ticks
|
||||
if( (m_Speed.SqrLength() > 0.0004f || m_bDirtySpeed) && (m_World->GetWorldAge() - m_TimeLastSpeedPacket >= 2))
|
||||
// Send velocity packet every two ticks if: speed is not negligible or speed was set (as indicated by the DirtySpeed flag)
|
||||
if (((m_Speed.SqrLength() > 0.0004f) || m_bDirtySpeed) && ((m_World->GetWorldAge() - m_TimeLastSpeedPacket) >= 2))
|
||||
{
|
||||
m_World->BroadcastEntityVelocity(*this,a_Exclude);
|
||||
m_bDirtySpeed = false;
|
||||
m_TimeLastSpeedPacket = m_World->GetWorldAge();
|
||||
}
|
||||
|
||||
//Have to process position related packets this every two ticks
|
||||
// Have to process position related packets this every two ticks
|
||||
if (m_World->GetWorldAge() % 2 == 0)
|
||||
{
|
||||
int DiffX = (int) (floor(GetPosX() * 32.0) - floor(m_LastPosX * 32.0));
|
||||
|
@ -32,6 +32,8 @@
|
||||
#define POSZ_TOINT (int)floor(GetPosZ())
|
||||
#define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT)
|
||||
|
||||
#define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; }
|
||||
|
||||
|
||||
|
||||
|
||||
@ -89,22 +91,41 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
enum
|
||||
enum eEntityStatus
|
||||
{
|
||||
ENTITY_STATUS_HURT = 2,
|
||||
ENTITY_STATUS_DEAD = 3,
|
||||
ENTITY_STATUS_WOLF_TAMING = 6,
|
||||
ENTITY_STATUS_WOLF_TAMED = 7,
|
||||
ENTITY_STATUS_WOLF_SHAKING = 8,
|
||||
ENTITY_STATUS_EATING_ACCEPTED = 9,
|
||||
ENTITY_STATUS_SHEEP_EATING = 10,
|
||||
ENTITY_STATUS_GOLEM_ROSING = 11,
|
||||
ENTITY_STATUS_VILLAGER_HEARTS = 12,
|
||||
ENTITY_STATUS_VILLAGER_ANGRY = 13,
|
||||
ENTITY_STATUS_VILLAGER_HAPPY = 14,
|
||||
ENTITY_STATUS_WITCH_MAGICKING = 15,
|
||||
// TODO: Investiagate 0, 1, and 5 as Wiki.vg is not certain
|
||||
|
||||
// Entity becomes coloured red
|
||||
esGenericHurt = 2,
|
||||
// Entity plays death animation (entity falls to ground)
|
||||
esGenericDead = 3,
|
||||
// Iron Golem plays attack animation (arms lift and fall)
|
||||
esIronGolemAttacking = 4,
|
||||
// Wolf taming particles spawn (smoke)
|
||||
esWolfTaming = 6,
|
||||
// Wolf tamed particles spawn (hearts)
|
||||
esWolfTamed = 7,
|
||||
// Wolf plays water removal animation (shaking and water particles)
|
||||
esWolfDryingWater = 8,
|
||||
// Informs client that eating was accepted
|
||||
esPlayerEatingAccepted = 9,
|
||||
// Sheep plays eating animation (head lowers to ground)
|
||||
esSheepEating = 10,
|
||||
// Iron Golem holds gift to villager children
|
||||
esIronGolemGivingPlant = 11,
|
||||
// Villager spawns heart particles
|
||||
esVillagerBreeding = 12,
|
||||
// Villager spawns thunderclound particles
|
||||
esVillagerAngry = 13,
|
||||
// Villager spawns green crosses
|
||||
esVillagerHappy = 14,
|
||||
// Witch spawns magic particle (TODO: investigation into what this is)
|
||||
esWitchMagicking = 15,
|
||||
|
||||
// It seems 16 (zombie conversion) is now done with metadata
|
||||
ENTITY_STATUS_FIREWORK_EXPLODE= 17,
|
||||
|
||||
// Informs client to explode a firework based on its metadata
|
||||
esFireworkExploding = 17,
|
||||
} ;
|
||||
|
||||
enum
|
||||
|
@ -98,15 +98,15 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
if (!m_bCollected)
|
||||
{
|
||||
int BlockY = (int) floor(GetPosY());
|
||||
int BlockY = POSY_TOINT;
|
||||
int BlockX = POSX_TOINT;
|
||||
int BlockZ = POSZ_TOINT;
|
||||
|
||||
if ((BlockY >= 0) && (BlockY < cChunkDef::Height)) // Don't do anything except for falling when outside the world
|
||||
{
|
||||
int BlockX = (int) floor(GetPosX());
|
||||
int BlockZ = (int) floor(GetPosZ());
|
||||
// Position might have changed due to physics. So we have to make sure we have the correct chunk.
|
||||
cChunk * CurrentChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ);
|
||||
if (CurrentChunk != NULL) // Make sure the chunk is loaded
|
||||
{
|
||||
GET_AND_VERIFY_CURRENT_CHUNK(CurrentChunk, BlockX, BlockZ)
|
||||
|
||||
int RelBlockX = BlockX - (CurrentChunk->GetPosX() * cChunkDef::Width);
|
||||
int RelBlockZ = BlockZ - (CurrentChunk->GetPosZ() * cChunkDef::Width);
|
||||
|
||||
@ -140,7 +140,6 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Timer > 500.f) // 0.5 second
|
||||
@ -156,7 +155,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetPosY() < -8) // Out of this world and no more visible!
|
||||
if (GetPosY() < VOID_BOUNDARY) // Out of this world and no more visible!
|
||||
{
|
||||
Destroy(true);
|
||||
return;
|
||||
|
@ -49,9 +49,6 @@ public:
|
||||
bool IsPlayerCreated(void) const { return m_bIsPlayerCreated; } // tolua_export
|
||||
|
||||
private:
|
||||
Vector3d m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;)
|
||||
|
||||
Vector3d m_WaterSpeed;
|
||||
|
||||
/** The number of ticks that the entity has existed / timer between collect and destroy; in msec */
|
||||
float m_Timer;
|
||||
|
@ -590,7 +590,7 @@ void cPlayer::FinishEating(void)
|
||||
m_EatingFinishTick = -1;
|
||||
|
||||
// Send the packets:
|
||||
m_ClientHandle->SendEntityStatus(*this, ENTITY_STATUS_EATING_ACCEPTED);
|
||||
m_ClientHandle->SendEntityStatus(*this, esPlayerEatingAccepted);
|
||||
m_World->BroadcastEntityAnimation(*this, 0);
|
||||
m_World->BroadcastEntityMetadata(*this);
|
||||
|
||||
|
@ -791,7 +791,7 @@ void cFireworkEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
if (m_ExplodeTimer == m_FireworkItem.m_FireworkItem.m_FlightTimeInTicks)
|
||||
{
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_FIREWORK_EXPLODE);
|
||||
m_World->BroadcastEntityStatus(*this, esFireworkExploding);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS)
|
||||
{
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_SHEEP_EATING);
|
||||
m_World->BroadcastEntityStatus(*this, esSheepEating);
|
||||
m_TimeToStopEating = 40;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ void cVillager::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
{
|
||||
if (m_World->GetTickRandomNumber(5) == 3)
|
||||
{
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_VILLAGER_ANGRY);
|
||||
m_World->BroadcastEntityStatus(*this, esVillagerAngry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,12 +75,12 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
|
||||
SetMaxHealth(20);
|
||||
SetIsTame(true);
|
||||
SetOwner(a_Player.GetName());
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMED);
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTamed);
|
||||
m_World->BroadcastParticleEffect("heart", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_WOLF_TAMING);
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTaming);
|
||||
m_World->BroadcastParticleEffect("smoke", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5);
|
||||
}
|
||||
}
|
||||
|
@ -69,18 +69,19 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
||||
// Checking only when a block is changed, as opposed to every tick, also improves performance
|
||||
|
||||
PoweredBlocksList * PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList();
|
||||
for (PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end(); ++itr)
|
||||
for (PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end();)
|
||||
{
|
||||
if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsPotentialSource(Block))
|
||||
{
|
||||
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
PoweredBlocks->erase(itr);
|
||||
break;
|
||||
itr = PoweredBlocks->erase(itr);
|
||||
continue;
|
||||
}
|
||||
else if (
|
||||
// Changeable sources
|
||||
@ -93,9 +94,10 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
||||
)
|
||||
{
|
||||
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
PoweredBlocks->erase(itr);
|
||||
break;
|
||||
itr = PoweredBlocks->erase(itr);
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
|
||||
LinkedBlocksList * LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList();
|
||||
@ -532,15 +534,22 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
|
||||
};
|
||||
|
||||
// Check to see if directly beside a power source
|
||||
if (IsWirePowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
unsigned char MyPower;
|
||||
if (!IsWirePowered(a_BlockX, a_BlockY, a_BlockZ, MyPower))
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MyPower);
|
||||
|
||||
if (MyPower < 1)
|
||||
{
|
||||
NIBBLETYPE MyMeta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
NIBBLETYPE MetaToSet = MyMeta;
|
||||
int TimesMetaSmaller = 0, TimesFoundAWire = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
MyPower--;
|
||||
|
||||
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power
|
||||
{
|
||||
@ -553,109 +562,70 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
|
||||
}
|
||||
else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us
|
||||
{
|
||||
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)))
|
||||
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
BLOCKTYPE SurroundType;
|
||||
NIBBLETYPE SurroundMeta;
|
||||
m_World.GetBlockTypeMeta(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, SurroundType, SurroundMeta);
|
||||
|
||||
if (SurroundType == E_BLOCK_REDSTONE_WIRE)
|
||||
if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_WIRE)
|
||||
{
|
||||
TimesFoundAWire++;
|
||||
|
||||
if (SurroundMeta > 1) // Wires of power 1 or 0 cannot transfer power TO ME, don't bother checking
|
||||
{
|
||||
// Does surrounding wire have a higher power level than the highest so far (MetaToSet)?
|
||||
// >= to fix a bug where wires bordering each other with the same power level will appear (in terms of meta) to power each other, when they aren't actually in the powered list
|
||||
if (SurroundMeta >= MetaToSet)
|
||||
{
|
||||
MetaToSet = SurroundMeta - 1; // To improve performance
|
||||
SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
}
|
||||
}
|
||||
|
||||
if (SurroundMeta < MyMeta) // Go through all surroundings to see if self power is larger than everyone else's
|
||||
{
|
||||
TimesMetaSmaller++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((TimesMetaSmaller == TimesFoundAWire) && (MyMeta != 0))
|
||||
{
|
||||
// All surrounding metas were smaller - self must have been a wire that was
|
||||
// transferring power to other wires around.
|
||||
// However, self not directly powered anymore, so source must have been removed,
|
||||
// therefore, self must be set to meta zero
|
||||
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, 0); // SetMeta & WakeUpSims doesn't seem to work here, so SetBlock
|
||||
return; // No need to process block power sets because self not powered
|
||||
}
|
||||
else if (MyMeta != MetaToSet)
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaToSet);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire
|
||||
{
|
||||
for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them
|
||||
{
|
||||
if (m_World.GetBlock(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF)
|
||||
{
|
||||
SetBlockPowered(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
|
||||
switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
case REDSTONE_NONE:
|
||||
{
|
||||
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
break;
|
||||
}
|
||||
case REDSTONE_X_POS:
|
||||
{
|
||||
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
break;
|
||||
}
|
||||
case REDSTONE_X_NEG:
|
||||
{
|
||||
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
break;
|
||||
}
|
||||
case REDSTONE_Z_POS:
|
||||
{
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
break;
|
||||
}
|
||||
case REDSTONE_Z_NEG:
|
||||
{
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE);
|
||||
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE, MyPower);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1046,16 +1016,13 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
{
|
||||
class cPressurePlateCallback :
|
||||
public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
||||
m_Entity(NULL),
|
||||
m_World(a_World),
|
||||
cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
m_NumberOfEntities(0),
|
||||
m_X(a_BlockX),
|
||||
m_Y(a_BlockY),
|
||||
m_Z(a_BlockZ)
|
||||
@ -1070,7 +1037,140 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
|
||||
|
||||
if (Distance <= 0.7)
|
||||
{
|
||||
m_Entity = a_Entity;
|
||||
m_NumberOfEntities++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetPowerLevel(unsigned char & a_PowerLevel) const
|
||||
{
|
||||
a_PowerLevel = std::min(m_NumberOfEntities, MAX_POWER_LEVEL);
|
||||
return (a_PowerLevel > 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_NumberOfEntities;
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
int m_Z;
|
||||
};
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
|
||||
unsigned char Power;
|
||||
NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (PressurePlateCallback.GetPowerLevel(Power))
|
||||
{
|
||||
if (Meta == E_META_PRESSURE_PLATE_RAISED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
|
||||
SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
{class cPressurePlateCallback :
|
||||
public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
m_NumberOfEntities(0),
|
||||
m_X(a_BlockX),
|
||||
m_Y(a_BlockY),
|
||||
m_Z(a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cEntity * a_Entity) override
|
||||
{
|
||||
Vector3f EntityPos = a_Entity->GetPosition();
|
||||
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
|
||||
double Distance = (EntityPos - BlockPos).Length();
|
||||
|
||||
if (Distance <= 0.7)
|
||||
{
|
||||
m_NumberOfEntities++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetPowerLevel(unsigned char & a_PowerLevel) const
|
||||
{
|
||||
a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL);
|
||||
return (a_PowerLevel > 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_NumberOfEntities;
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
int m_Z;
|
||||
};
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
|
||||
unsigned char Power;
|
||||
NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (PressurePlateCallback.GetPowerLevel(Power))
|
||||
{
|
||||
if (Meta == E_META_PRESSURE_PLATE_RAISED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
|
||||
SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
{
|
||||
class cPressurePlateCallback :
|
||||
public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
m_FoundEntity(false),
|
||||
m_X(a_BlockX),
|
||||
m_Y(a_BlockY),
|
||||
m_Z(a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cEntity * a_Entity) override
|
||||
{
|
||||
Vector3f EntityPos = a_Entity->GetPosition();
|
||||
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
|
||||
double Distance = (EntityPos - BlockPos).Length();
|
||||
|
||||
if (Distance <= 0.7)
|
||||
{
|
||||
m_FoundEntity = true;
|
||||
return true; // Break out, we only need to know for plates that at least one entity is on top
|
||||
}
|
||||
return false;
|
||||
@ -1078,46 +1178,47 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
|
||||
|
||||
bool FoundEntity(void) const
|
||||
{
|
||||
return m_Entity != NULL;
|
||||
return m_FoundEntity;
|
||||
}
|
||||
|
||||
protected:
|
||||
cEntity * m_Entity;
|
||||
cWorld * m_World;
|
||||
bool m_FoundEntity;
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
int m_Z;
|
||||
} ;
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ, &m_World);
|
||||
cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
|
||||
NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (PressurePlateCallback.FoundEntity())
|
||||
{
|
||||
if (Meta == 0x0)
|
||||
if (Meta == E_META_PRESSURE_PLATE_RAISED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int) ((a_BlockX + 0.5) * 8.0), (int) ((a_BlockY + 0.1) * 8.0), (int) ((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x1);
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
|
||||
SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Meta == 0x1)
|
||||
if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
|
||||
{
|
||||
m_World.BroadcastSoundEffect("random.click", (int) ((a_BlockX + 0.5) * 8.0), (int) ((a_BlockY + 0.1) * 8.0), (int) ((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x0);
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGD("Unimplemented pressure plate type %s in cRedstoneSimulator", ItemToFullString(a_MyType).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1323,28 +1424,23 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY,
|
||||
|
||||
|
||||
|
||||
bool cIncrementalRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
bool cIncrementalRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ, unsigned char & a_PowerLevel)
|
||||
{
|
||||
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr)
|
||||
a_PowerLevel = 0;
|
||||
|
||||
for (auto itr = m_PoweredBlocks->cbegin(); itr != m_PoweredBlocks->cend(); ++itr) // Check powered list
|
||||
{
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
|
||||
if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
|
||||
}
|
||||
|
||||
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr)
|
||||
for (auto itr = m_LinkedPoweredBlocks->cbegin(); itr != m_LinkedPoweredBlocks->cend(); ++itr) // Check linked powered list
|
||||
{
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
|
||||
}
|
||||
|
||||
if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Source was in front of the piston's front face
|
||||
return (a_PowerLevel != 0); // Source was in front of the piston's front face
|
||||
}
|
||||
|
||||
|
||||
@ -1374,7 +1470,7 @@ bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_Block
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType)
|
||||
void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType, unsigned char a_PowerLevel)
|
||||
{
|
||||
switch (a_Direction)
|
||||
{
|
||||
@ -1382,11 +1478,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ);
|
||||
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1394,11 +1490,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ);
|
||||
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1406,11 +1502,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
|
||||
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1418,11 +1514,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
|
||||
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1430,11 +1526,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
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);
|
||||
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1442,11 +1538,11 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
{
|
||||
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);
|
||||
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
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, a_PowerLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1462,7 +1558,7 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock)
|
||||
void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
@ -1479,7 +1575,7 @@ void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_Bloc
|
||||
|
||||
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through struct to power all directions
|
||||
{
|
||||
SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_SourceBlock);
|
||||
SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_SourceBlock, a_PowerLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1487,7 +1583,7 @@ void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_Bloc
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock)
|
||||
void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel)
|
||||
{
|
||||
BLOCKTYPE Block = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (Block == E_BLOCK_AIR)
|
||||
@ -1496,16 +1592,32 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY,
|
||||
return;
|
||||
}
|
||||
|
||||
PoweredBlocksList * Powered = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorPoweredBlocksList();
|
||||
|
||||
for (PoweredBlocksList::const_iterator itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
|
||||
auto Powered = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorPoweredBlocksList();
|
||||
for (auto itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
|
||||
{
|
||||
if (
|
||||
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
|
||||
// Check for duplicates, update power level if everything else the same but either way, don't add a new listing
|
||||
if (itr->a_PowerLevel != a_PowerLevel)
|
||||
{
|
||||
itr->a_PowerLevel = a_PowerLevel;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto OtherPowered = m_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ)->GetRedstoneSimulatorPoweredBlocksList();
|
||||
for (auto itr = OtherPowered->cbegin(); itr != OtherPowered->cend(); ++itr) // Check powered list
|
||||
{
|
||||
if (
|
||||
itr->a_BlockPos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) &&
|
||||
itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))
|
||||
)
|
||||
{
|
||||
// Powered wires try to power their source - don't let them!
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1513,6 +1625,7 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY,
|
||||
sPoweredBlocks RC;
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
|
||||
RC.a_PowerLevel = a_PowerLevel;
|
||||
Powered->push_back(RC);
|
||||
}
|
||||
|
||||
@ -1524,7 +1637,7 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ,
|
||||
int a_MiddleX, int a_MiddleY, int a_MiddleZ,
|
||||
int a_SourceX, int a_SourceY, int a_SourceZ,
|
||||
BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock
|
||||
BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock, unsigned char a_PowerLevel
|
||||
)
|
||||
{
|
||||
BLOCKTYPE DestBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
@ -1538,9 +1651,8 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedBlocksList * Linked = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorLinkedBlocksList();
|
||||
|
||||
for (LinkedBlocksList::const_iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list
|
||||
auto Linked = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorLinkedBlocksList();
|
||||
for (auto itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list
|
||||
{
|
||||
if (
|
||||
itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
|
||||
@ -1548,7 +1660,11 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
||||
itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
|
||||
)
|
||||
{
|
||||
// Check for duplicates
|
||||
// Check for duplicates, update power level if everything else the same but either way, don't add a new listing
|
||||
if (itr->a_PowerLevel != a_PowerLevel)
|
||||
{
|
||||
itr->a_PowerLevel = a_PowerLevel;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1557,6 +1673,7 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
RC.a_MiddlePos = Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ);
|
||||
RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
|
||||
RC.a_PowerLevel = a_PowerLevel;
|
||||
Linked->push_back(RC);
|
||||
}
|
||||
|
||||
@ -1621,7 +1738,7 @@ void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
||||
// Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.)
|
||||
// * 2 because apparently, MCS ticks are way faster than vanilla ticks, so repeater aren't noticeably delayed
|
||||
// * 2 because in MCS, 1 redstone tick = 1 world tick, but in Vanilla, 1 redstone tick = 2 world ticks, and we need to maintain compatibility
|
||||
RC.a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2;
|
||||
|
||||
RC.a_ElapsedTicks = 0;
|
||||
@ -1697,12 +1814,3 @@ bool cIncrementalRedstoneSimulator::IsLeverOn(NIBBLETYPE a_BlockMeta)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cIncrementalRedstoneSimulator::IsButtonOn(NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
return IsLeverOn(a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -36,31 +36,35 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
#define MAX_POWER_LEVEL 15
|
||||
|
||||
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
||||
{
|
||||
Vector3i a_BlockPos; // Position of powered block
|
||||
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
||||
unsigned char a_PowerLevel;
|
||||
};
|
||||
|
||||
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_MiddlePos;
|
||||
Vector3i a_MiddlePos; // Position of block that is betwixt a source and the destination
|
||||
Vector3i a_SourcePos;
|
||||
unsigned char a_PowerLevel;
|
||||
};
|
||||
|
||||
struct sSimulatedPlayerToggleableList
|
||||
struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player)
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
bool WasLastStatePowered;
|
||||
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
|
||||
};
|
||||
|
||||
struct sRepeatersDelayList
|
||||
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
unsigned char a_DelayTicks;
|
||||
unsigned char a_ElapsedTicks;
|
||||
bool ShouldPowerOn;
|
||||
unsigned char a_DelayTicks; // For how many ticks should the repeater delay
|
||||
unsigned char a_ElapsedTicks; // How much of the previous has been elapsed?
|
||||
bool ShouldPowerOn; // What happens when the delay time is fulfilled?
|
||||
};
|
||||
|
||||
public:
|
||||
@ -132,15 +136,15 @@ private:
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock);
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock);
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Queues a repeater to be powered or unpowered */
|
||||
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||
|
||||
@ -159,15 +163,14 @@ private:
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a wire is powered
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire
|
||||
*/
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ, unsigned char & a_PowerLevel);
|
||||
|
||||
|
||||
/** Returns if lever metadata marks it as emitting power */
|
||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||
/** Returns if button metadata marks it as emitting power */
|
||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta);
|
||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta) { return IsLeverOn(a_BlockMeta); }
|
||||
/* ============================== */
|
||||
|
||||
/* ====== Misc Functions ====== */
|
||||
|
@ -108,6 +108,11 @@ public:
|
||||
return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3<T> & a_Rhs) const
|
||||
{
|
||||
return Equals(a_Rhs);
|
||||
}
|
||||
|
||||
inline bool operator < (const Vector3<T> & a_Rhs)
|
||||
{
|
||||
// return (x < a_Rhs.x) && (y < a_Rhs.y) && (z < a_Rhs.z); ?
|
||||
|
@ -574,7 +574,7 @@ void cWorld::Start(void)
|
||||
m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false);
|
||||
m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true);
|
||||
m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true);
|
||||
int TNTShrapnelLevel = IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", (int)slNone);
|
||||
int TNTShrapnelLevel = IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", (int)slAll);
|
||||
m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false);
|
||||
m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true);
|
||||
m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true);
|
||||
@ -1632,7 +1632,6 @@ bool cWorld::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
|
||||
|
||||
void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed, bool IsPlayerCreated)
|
||||
{
|
||||
MTRand r1;
|
||||
a_FlyAwaySpeed /= 100; // Pre-divide, so that we don't have to divide each time inside the loop
|
||||
for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
|
||||
{
|
||||
@ -1642,9 +1641,9 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
|
||||
continue;
|
||||
}
|
||||
|
||||
float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(10) - 5));
|
||||
float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(50));
|
||||
float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(10) - 5));
|
||||
float SpeedX = (float)(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
||||
float SpeedY = (float)(a_FlyAwaySpeed * GetTickRandomNumber(50));
|
||||
float SpeedZ = (float)(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
||||
|
||||
cPickup * Pickup = new cPickup(
|
||||
a_BlockX, a_BlockY, a_BlockZ,
|
||||
|
@ -231,7 +231,7 @@ void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkIte
|
||||
|
||||
|
||||
|
||||
int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta)
|
||||
int cFireworkItem::GetVanillaColourCodeFromDye(NIBBLETYPE a_DyeMeta)
|
||||
{
|
||||
/*
|
||||
Colours are supposed to be calculated via: R << 16 + G << 8 + B
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem);
|
||||
|
||||
/** Returns a colour code for fireworks used by the network code */
|
||||
static int GetVanillaColourCodeFromDye(short a_DyeMeta);
|
||||
static int GetVanillaColourCodeFromDye(NIBBLETYPE a_DyeMeta);
|
||||
|
||||
bool m_HasFlicker;
|
||||
bool m_HasTrail;
|
||||
|
Loading…
Reference in New Issue
Block a user