1
0

Merge pull request #891 from mc-server/fixes

Fixes to redstone & general
This commit is contained in:
Mattes D 2014-04-17 22:37:00 +02:00
commit b7e074b10b
18 changed files with 462 additions and 335 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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);
}

View File

@ -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,37 +519,36 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
}
else
{
if (a_Chunk.IsValid())
if (!a_Chunk.IsValid())
{
cChunk * NextChunk = a_Chunk.GetNeighborChunk(POSX_TOINT, POSZ_TOINT);
if ((NextChunk == NULL) || !NextChunk->IsValid())
{
return;
}
TickBurning(*NextChunk);
if (GetPosY() < VOID_BOUNDARY)
{
TickInVoid(*NextChunk);
}
else
{
m_TicksSinceLastVoidDamage = 0;
}
if (IsMob() || IsPlayer())
{
// Set swimming state
SetSwimState(*NextChunk);
// Handle drowning
HandleAir();
}
HandlePhysics(a_Dt, *NextChunk);
return;
}
// Position changed -> super::Tick() called
GET_AND_VERIFY_CURRENT_CHUNK(NextChunk, POSX_TOINT, POSZ_TOINT)
TickBurning(*NextChunk);
if (GetPosY() < VOID_BOUNDARY)
{
TickInVoid(*NextChunk);
}
else
{
m_TicksSinceLastVoidDamage = 0;
}
if (IsMob() || IsPlayer())
{
// Set swimming state
SetSwimState(*NextChunk);
// Handle drowning
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));

View File

@ -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

View File

@ -98,45 +98,44 @@ 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);
// If the pickup is on the bottommost block position, make it think the void is made of air: (#131)
BLOCKTYPE BlockBelow = (BlockY > 0) ? CurrentChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
BLOCKTYPE BlockIn = CurrentChunk->GetBlock(RelBlockX, BlockY, RelBlockZ);
if (
IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) ||
IsBlockLava(BlockIn) || (BlockIn == E_BLOCK_FIRE)
)
{
int RelBlockX = BlockX - (CurrentChunk->GetPosX() * cChunkDef::Width);
int RelBlockZ = BlockZ - (CurrentChunk->GetPosZ() * cChunkDef::Width);
// If the pickup is on the bottommost block position, make it think the void is made of air: (#131)
BLOCKTYPE BlockBelow = (BlockY > 0) ? CurrentChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR;
BLOCKTYPE BlockIn = CurrentChunk->GetBlock(RelBlockX, BlockY, RelBlockZ);
if (
IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) ||
IsBlockLava(BlockIn) || (BlockIn == E_BLOCK_FIRE)
)
m_bCollected = true;
m_Timer = 0; // We have to reset the timer.
m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
if (m_Timer > 500.f)
{
m_bCollected = true;
m_Timer = 0; // We have to reset the timer.
m_Timer += a_Dt; // In case we have to destroy the pickup in the same tick.
if (m_Timer > 500.f)
{
Destroy(true);
return;
}
Destroy(true);
return;
}
}
if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me
if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me
{
cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this);
m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries
if (PickupCombiningCallback.FoundMatchingPickup())
{
cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this);
m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries
if (PickupCombiningCallback.FoundMatchingPickup())
{
m_World->BroadcastEntityMetadata(*this);
}
m_World->BroadcastEntityMetadata(*this);
}
}
}
@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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,128 +534,96 @@ 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;
}
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power
MyPower--;
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power
{
if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above...
{
if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above...
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) // If there is something solid above us (wire cut off)...
{
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) // If there is something solid above us (wire cut off)...
{
continue; // We don't receive power from that wire
}
continue; // We don't receive power from that wire
}
else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us
}
else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us
{
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)))
{
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)
{
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
}
}
if (SurroundMeta < MyMeta) // Go through all surroundings to see if self power is larger than everyone else's
{
TimesMetaSmaller++;
}
continue;
}
}
if ((TimesMetaSmaller == TimesFoundAWire) && (MyMeta != 0))
if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_WIRE)
{
// 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);
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 (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
{
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)
{
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);
// Wire still powered, power blocks beneath
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))
switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
{
case REDSTONE_NONE:
{
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);
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);
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);
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);
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);
break;
}
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, 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, 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, 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, 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,45 +1178,46 @@ 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; }
if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE)
{
return true;
}
a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
}
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);
}

View File

@ -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 ====== */

View File

@ -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); ?

View File

@ -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,

View File

@ -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

View File

@ -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;