Implemented weighted pressure plates
This commit is contained in:
parent
82b3d543e7
commit
2151ee997c
@ -503,6 +503,10 @@ enum
|
||||
E_META_PLANKS_CONIFER = 1,
|
||||
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,
|
||||
|
@ -537,13 +537,14 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
|
||||
unsigned char MyPower;
|
||||
if (!IsWirePowered(a_BlockX, a_BlockY, a_BlockZ, MyPower))
|
||||
{
|
||||
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, 0);
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
return;
|
||||
}
|
||||
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MyPower); // Maximum power
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MyPower);
|
||||
|
||||
if (MyPower < 2)
|
||||
if (MyPower < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1015,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)
|
||||
@ -1039,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;
|
||||
@ -1047,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1426,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
|
||||
{
|
||||
@ -1443,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1460,21 +1592,25 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
PoweredBlocksList * OtherPowered = m_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ)->GetRedstoneSimulatorPoweredBlocksList();
|
||||
for (PoweredBlocksList::const_iterator itr = OtherPowered->begin(); itr != OtherPowered->end(); ++itr) // Check powered list
|
||||
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)) &&
|
||||
@ -1515,8 +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)) &&
|
||||
@ -1524,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;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
#define MAX_POWER_LEVEL 15
|
||||
|
||||
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
||||
{
|
||||
Vector3i a_BlockPos; // Position of powered block
|
||||
@ -134,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, unsigned char a_PowerLevel = 15);
|
||||
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, unsigned char a_PowerLevel = 15);
|
||||
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, unsigned char a_PowerLevel = 15);
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user