Merge branch 'master' into entities
This commit is contained in:
commit
706b9181e6
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ nbproject/
|
||||
ipch/
|
||||
Win32/
|
||||
MCServer/MCServer
|
||||
MCServer/itemblacklist
|
||||
ChunkWorxSave.ini
|
||||
doxy/
|
||||
Profiling
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 39d980e3a3447ac23f61c7d65426b33ee6c0718d
|
||||
Subproject commit 6e9d612b9eb548d888d2bf986488aad762a99be0
|
@ -277,12 +277,12 @@ ActivatorRail, 6 = IronIngot, 1:1, 1:2, 1:3, 3:1, 3:2, 3:3 | Stick, 2:1, 2:3 | R
|
||||
#******************************************************#
|
||||
# Mechanisms
|
||||
#
|
||||
WoodenDoor, 3 = OakPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
SpruceDoor, 3 = SprucePlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
BirchDoor, 3 = BirchPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
JungleDoor, 3 = JunglePlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
AcaciaDoor, 3 = AcaciaPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
DarkOakDoor, 3 = DarkOakPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
WoodenDoor, 3 = OakPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
IronDoor, 3 = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
TrapDoor, 2 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronTrapDoor = IronIngot, 1:1, 1:2, 2:1, 2:2
|
||||
@ -358,21 +358,21 @@ IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Paper, 3 = Sugarcane, 1:1, 2:1, 3:1
|
||||
Book = Paper, *, *, * | leather, *
|
||||
Bookandquill = Book, * | feather, * | inksac, *
|
||||
Fence, 3 = OakPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
SpruceFence, 3 = SprucePlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
BirchFence, 3 = BirchPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
JungleFence, 3 = JunglePlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
DarkOakFence, 3 = DarkOakPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
AcaciaFence, 3 = AcaciaPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
Fence, 3 = OakPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
Cobblestonewall, 6 = cobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
mossycobblestonewall, 6 = mossycobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
NetherBrickFence, 6 = NetherBrick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | OakPlanks, 2:1, 2:2
|
||||
SpruceFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | SprucePlanks, 2:1, 2:2
|
||||
BirchFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | BirchPlanks, 2:1, 2:2
|
||||
JungleFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | JunglePlanks, 2:1, 2:2
|
||||
DarkOakFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | DarkOakPlanks, 2:1, 2:2
|
||||
AcaciaFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | AcaciaPlanks, 2:1, 2:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | OakPlanks, 2:1, 2:2
|
||||
Bed = Planks, 1:2, 2:2, 3:2 | Wool, 1:1, 2:1, 3:1
|
||||
GoldIngot = GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EyeOfEnder = EnderPearl, * | BlazePowder, *
|
||||
|
@ -49,6 +49,7 @@ NetherQuartzOre = NetherQuartz
|
||||
Sand = Glass
|
||||
Pork = CookedPork
|
||||
RawBeef = Steak
|
||||
Potato = BakedPotato
|
||||
RawChicken = CookedChicken
|
||||
Clay = Brick
|
||||
ClayBlock = HardenedClay
|
||||
|
@ -150,7 +150,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
||||
int RelZ = (int) (m_RelZ + (double)(Random.NextFloat() - Random.NextFloat()) * 4.0);
|
||||
|
||||
cChunk * Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(RelX, RelZ);
|
||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -162,7 +162,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
||||
double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ;
|
||||
|
||||
cMonster * Monster = cMonster::NewMonsterFromType(m_MobType);
|
||||
if (Monster == NULL)
|
||||
if (Monster == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -452,7 +452,6 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_AIR ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CAKE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CROPS ].m_IsSolid = false;
|
||||
|
96
src/Blocks/BlockCocoaPod.h
Normal file
96
src/Blocks/BlockCocoaPod.h
Normal file
@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../FastRandom.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockCocoaPodHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockCocoaPodHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockFace, true);
|
||||
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta);
|
||||
|
||||
return ((BlockType == E_BLOCK_LOG) && ((BlockMeta & 0x3) == E_META_LOG_JUNGLE));
|
||||
}
|
||||
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
cFastRandom Random;
|
||||
|
||||
if (Random.NextInt(5) == 0)
|
||||
{
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
NIBBLETYPE TypeMeta = Meta & 0x03;
|
||||
int GrowState = Meta >> 2;
|
||||
|
||||
if (GrowState < 2)
|
||||
{
|
||||
++GrowState;
|
||||
a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, (NIBBLETYPE) (GrowState << 2 | TypeMeta));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
int GrowState = a_BlockMeta >> 2;
|
||||
a_Pickups.Add(E_ITEM_DYE, ((GrowState >= 2) ? 3 : 1), E_META_DYE_BROWN);
|
||||
}
|
||||
|
||||
|
||||
static eBlockFace MetaToBlockFace(NIBBLETYPE a_Meta)
|
||||
{
|
||||
switch (a_Meta & 0x3)
|
||||
{
|
||||
case 0: return BLOCK_FACE_ZM;
|
||||
case 1: return BLOCK_FACE_XP;
|
||||
case 2: return BLOCK_FACE_ZP;
|
||||
case 3: return BLOCK_FACE_XM;
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Bad meta");
|
||||
return BLOCK_FACE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static NIBBLETYPE BlockFaceToMeta(eBlockFace a_BlockFace)
|
||||
{
|
||||
switch (a_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZM: return 0;
|
||||
case BLOCK_FACE_XM: return 3;
|
||||
case BLOCK_FACE_XP: return 1;
|
||||
case BLOCK_FACE_ZP: return 2;
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unknown face");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "BlockChest.h"
|
||||
#include "BlockCloth.h"
|
||||
#include "BlockCobWeb.h"
|
||||
#include "BlockCocoaPod.h"
|
||||
#include "BlockCommandBlock.h"
|
||||
#include "BlockComparator.h"
|
||||
#include "BlockCrops.h"
|
||||
@ -198,6 +199,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType);
|
||||
case E_BLOCK_CHEST: return new cBlockChestHandler (a_BlockType);
|
||||
case E_BLOCK_COAL_ORE: return new cBlockOreHandler (a_BlockType);
|
||||
case E_BLOCK_COCOA_POD: return new cBlockCocoaPodHandler (a_BlockType);
|
||||
case E_BLOCK_COMMAND_BLOCK: return new cBlockCommandBlockHandler (a_BlockType);
|
||||
case E_BLOCK_ACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
|
||||
case E_BLOCK_COBBLESTONE: return new cBlockStoneHandler (a_BlockType);
|
||||
|
@ -28,8 +28,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
|
||||
return (cBlockInfo::IsSolid(BlockBelow));
|
||||
return (cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)))
|
||||
if (!cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -130,7 +130,7 @@ public:
|
||||
// Too close to the edge, cannot simulate
|
||||
return true;
|
||||
}
|
||||
return cBlockInfo::IsSolid(BlockType);
|
||||
return cBlockInfo::FullyOccupiesVoxel(BlockType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
|
||||
virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop) override
|
||||
{
|
||||
if (a_CanDrop && (a_Digger != NULL) && (a_Digger->GetEquippedWeapon().m_ItemType == E_ITEM_SHEARS))
|
||||
if (a_CanDrop && (a_Digger != nullptr) && (a_Digger->GetEquippedWeapon().m_ItemType == E_ITEM_SHEARS))
|
||||
{
|
||||
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
cItems Drops;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../Chunk.h"
|
||||
#include "ChunkInterface.h"
|
||||
#include "MetaRotator.h"
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ SET (HDRS
|
||||
BlockChest.h
|
||||
BlockCloth.h
|
||||
BlockCobWeb.h
|
||||
BlockCocoaPod.h
|
||||
BlockCommandBlock.h
|
||||
BlockComparator.h
|
||||
BlockCrops.h
|
||||
|
@ -1371,9 +1371,9 @@ void cChunk::CreateBlockEntities(void)
|
||||
|
||||
void cChunk::WakeUpSimulators(void)
|
||||
{
|
||||
cSimulator<cChunk, cWorld> * WaterSimulator = m_World->GetWaterSimulator();
|
||||
cSimulator<cChunk, cWorld> * LavaSimulator = m_World->GetLavaSimulator();
|
||||
cSimulator<cChunk, cWorld> * RedstoneSimulator = m_World->GetRedstoneSimulator();
|
||||
cSimulator * WaterSimulator = m_World->GetWaterSimulator();
|
||||
cSimulator * LavaSimulator = m_World->GetLavaSimulator();
|
||||
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
|
||||
int BaseX = m_PosX * cChunkDef::Width;
|
||||
int BaseZ = m_PosZ * cChunkDef::Width;
|
||||
for (int x = 0; x < Width; x++)
|
||||
|
@ -3075,7 +3075,7 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
|
||||
)
|
||||
{
|
||||
// The cChunk destructor calls our GetChunk() while removing its entities
|
||||
// so we still need to be able to return the chunk. Therefore we first delete, then NULLify
|
||||
// so we still need to be able to return the chunk. Therefore we first delete, then nullptrify
|
||||
// Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355
|
||||
delete m_Chunks[i];
|
||||
m_Chunks[i] = nullptr;
|
||||
|
@ -1604,6 +1604,12 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
|
||||
// Update the view distance.
|
||||
m_ClientHandle->SetViewDistance(m_ClientHandle->GetRequestedViewDistance());
|
||||
|
||||
// Send current weather of target world to player
|
||||
if (a_World->GetDimension() == dimOverworld)
|
||||
{
|
||||
m_ClientHandle->SendWeather(a_World->GetWeather());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "ItemHandler.h"
|
||||
#include "../World.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Blocks/BlockCocoaPod.h"
|
||||
|
||||
|
||||
|
||||
@ -16,10 +17,9 @@ public:
|
||||
cItemDyeHandler(int a_ItemType)
|
||||
: cItemHandler(a_ItemType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
|
||||
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
// Handle growing the plants:
|
||||
if (a_Item.m_ItemDamage == E_META_DYE_WHITE)
|
||||
@ -34,8 +34,50 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((a_Item.m_ItemDamage == E_META_DYE_BROWN) && (a_BlockFace >= BLOCK_FACE_ZM) && (a_BlockFace <= BLOCK_FACE_XP))
|
||||
{
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
|
||||
|
||||
// Check if the block that the player clicked is a jungle log.
|
||||
if ((BlockType != E_BLOCK_LOG) || ((BlockMeta & 0x3) != E_META_LOG_JUNGLE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the location from the new cocoa pod.
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
|
||||
BlockMeta = cBlockCocoaPodHandler::BlockFaceToMeta(a_BlockFace);
|
||||
|
||||
if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_AIR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check plugins
|
||||
if (cRoot::Get()->GetPluginManager()->CallHookPlayerPlacingBlock(*a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, 0, 0, 0, E_BLOCK_COCOA_POD, BlockMeta))
|
||||
{
|
||||
a_World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
a_Player->GetInventory().SendEquippedSlot();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set block and broadcast place sound
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_COCOA_POD, BlockMeta);
|
||||
a_World->BroadcastSoundEffect("dig.stone", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f);
|
||||
|
||||
// Remove one cocoa pod from the inventory
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, 0, 0, 0, E_BLOCK_COCOA_POD, BlockMeta);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@ enum eMonsterType
|
||||
mtWolf = E_META_SPAWN_EGG_WOLF,
|
||||
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
|
||||
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
|
||||
mtMax = 120, // This is just a hotfix for http://forum.mc-server.org/showthread.php?tid=1616. Tolua is too bad to find the highest value, so this is needed.
|
||||
} ;
|
||||
|
||||
// tolua_end
|
||||
|
@ -16,7 +16,7 @@ it progresses to the next step (blockmeta++). This value is updated if a neighbo
|
||||
The simulator reads its parameters from the ini file given to the constructor.
|
||||
*/
|
||||
class cFireSimulator :
|
||||
public cSimulator<cChunk, cWorld>
|
||||
public cSimulator
|
||||
{
|
||||
public:
|
||||
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||
|
@ -83,7 +83,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// New meta for the spreading to neighbors:
|
||||
// If this is a source block or was falling, the new meta is just the falloff
|
||||
// Otherwise it is the current meta plus falloff (may be larger than max height, will be checked later)
|
||||
@ -103,6 +103,11 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
|
||||
SpreadFurther = false;
|
||||
}
|
||||
}
|
||||
// Spread to the neighbors:
|
||||
if (SpreadFurther && (NewMeta < 8))
|
||||
{
|
||||
SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
|
||||
}
|
||||
// If source creation is on, check for it here:
|
||||
else if (
|
||||
(m_NumNeighborsForSource > 0) && // Source creation is on
|
||||
@ -116,13 +121,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (SpreadFurther && (NewMeta < 8))
|
||||
{
|
||||
// Spread to the neighbors:
|
||||
SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
|
||||
}
|
||||
|
||||
|
||||
// Mark as processed:
|
||||
a_Chunk->FastSetBlock(a_RelX, a_RelY, a_RelZ, m_StationaryFluidBlock, MyMeta);
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ public:
|
||||
|
||||
|
||||
class cFluidSimulator :
|
||||
public cSimulator<cChunk, cWorld>
|
||||
public cSimulator
|
||||
{
|
||||
typedef cSimulator<cChunk, cWorld> super;
|
||||
typedef cSimulator super;
|
||||
|
||||
public:
|
||||
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,396 @@
|
||||
#pragma once
|
||||
|
||||
#include "RedstoneSimulator.h"
|
||||
#include "BlockEntities/RedstonePoweredEntity.h"
|
||||
|
||||
class cWorld;
|
||||
class cChunk;
|
||||
|
||||
cRedstoneSimulator<cChunk, cWorld> * MakeIncrementalRedstoneSimulator(cWorld & a_World);
|
||||
|
||||
|
||||
|
||||
|
||||
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
|
||||
|
||||
|
||||
|
||||
class cIncrementalRedstoneSimulator :
|
||||
public cRedstoneSimulator
|
||||
{
|
||||
typedef cRedstoneSimulator super;
|
||||
public:
|
||||
|
||||
cIncrementalRedstoneSimulator(cWorld & a_World)
|
||||
: cRedstoneSimulator(a_World)
|
||||
{
|
||||
}
|
||||
|
||||
virtual cRedstoneSimulatorChunkData * CreateChunkData() override
|
||||
{
|
||||
return new cIncrementalRedstoneSimulatorChunkData;
|
||||
}
|
||||
|
||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt); } // not used
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); }
|
||||
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
||||
|
||||
enum eRedstoneDirection
|
||||
{
|
||||
REDSTONE_NONE = 0,
|
||||
REDSTONE_X_POS = 0x1,
|
||||
REDSTONE_X_NEG = 0x2,
|
||||
REDSTONE_Z_POS = 0x4,
|
||||
REDSTONE_Z_NEG = 0x8,
|
||||
};
|
||||
eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
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; // Position of block that is betwixt a source and the destination
|
||||
Vector3i a_SourcePos;
|
||||
unsigned char a_PowerLevel;
|
||||
};
|
||||
|
||||
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_RelBlockPos;
|
||||
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
|
||||
};
|
||||
|
||||
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
|
||||
{
|
||||
Vector3i a_RelBlockPos;
|
||||
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?
|
||||
};
|
||||
|
||||
class cIncrementalRedstoneSimulatorChunkData :
|
||||
public cRedstoneSimulatorChunkData
|
||||
{
|
||||
public:
|
||||
/// Per-chunk data for the simulator, specified individual chunks to simulate
|
||||
cCoordWithBlockAndBoolVector m_ChunkData;
|
||||
cCoordWithBlockAndBoolVector m_QueuedChunkData;
|
||||
std::vector<sPoweredBlocks> m_PoweredBlocks;
|
||||
std::vector<sLinkedPoweredBlocks> m_LinkedBlocks;
|
||||
std::vector<sSimulatedPlayerToggleableList> m_SimulatedPlayerToggleableBlocks;
|
||||
std::vector<sRepeatersDelayList> m_RepeatersDelayList;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
||||
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
||||
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
|
||||
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
|
||||
|
||||
private:
|
||||
|
||||
cIncrementalRedstoneSimulatorChunkData * m_RedstoneSimulatorChunkData;
|
||||
PoweredBlocksList * m_PoweredBlocks;
|
||||
LinkedBlocksList * m_LinkedPoweredBlocks;
|
||||
SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks;
|
||||
RepeatersDelayList * m_RepeatersDelayList;
|
||||
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
|
||||
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk, cChunk * a_OtherChunk = nullptr);
|
||||
cChunk * m_Chunk;
|
||||
|
||||
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
|
||||
// In addition to being non-performant, it would stop the player from actually breaking said device
|
||||
|
||||
/* ====== SOURCES ====== */
|
||||
/** Handles the redstone torch */
|
||||
void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles the redstone block */
|
||||
void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles levers */
|
||||
void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles buttons */
|
||||
void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles daylight sensors */
|
||||
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles tripwire hooks
|
||||
Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook
|
||||
If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task
|
||||
*/
|
||||
void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles trapped chests */
|
||||
void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
/** Handles redstone wire */
|
||||
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles repeaters */
|
||||
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
/* ====== DEVICES ====== */
|
||||
/** Handles pistons */
|
||||
void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles dispensers and droppers */
|
||||
void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles TNT (exploding) */
|
||||
void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles redstone lamps */
|
||||
void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles doords */
|
||||
void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles command blocks */
|
||||
void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles activator, detector, and powered rails */
|
||||
void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles trapdoors */
|
||||
void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles fence gates */
|
||||
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles tripwires */
|
||||
void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, 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_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered);
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */
|
||||
bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||
/** Removes a block from the Powered and LinkedPowered lists
|
||||
Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests
|
||||
*/
|
||||
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk, bool a_IsFirstCall = true);
|
||||
void SetInvalidMiddleBlock(int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, cChunk * a_Chunk, bool a_IsFirstCall = true);
|
||||
|
||||
/** Returns if a coordinate is powered or linked powered */
|
||||
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
||||
/** Returns if a coordinate is in the directly powered blocks list */
|
||||
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, cChunk * a_Chunk);
|
||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||
bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
|
||||
/** Returns if a repeater is powered by testing for power sources behind the repeater */
|
||||
bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a repeater is locked */
|
||||
bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, 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_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel);
|
||||
/** Handles delayed updates to repeaters **/
|
||||
void HandleRedstoneRepeaterDelays(void);
|
||||
|
||||
/** 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) { return IsLeverOn(a_BlockMeta); }
|
||||
/* ============================== */
|
||||
|
||||
/* ====== Misc Functions ====== */
|
||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); }
|
||||
|
||||
/** Returns if a block is a mechanism (something that accepts power and does something)
|
||||
Used by torches to determine if they power a block whilst not standing on the ground
|
||||
*/
|
||||
inline static bool IsMechanism(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_ACACIA_DOOR:
|
||||
case E_BLOCK_ACACIA_FENCE_GATE:
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_BIRCH_DOOR:
|
||||
case E_BLOCK_BIRCH_FENCE_GATE:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_DARK_OAK_DOOR:
|
||||
case E_BLOCK_DARK_OAK_FENCE_GATE:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_IRON_TRAPDOOR:
|
||||
case E_BLOCK_JUNGLE_DOOR:
|
||||
case E_BLOCK_JUNGLE_FENCE_GATE:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_PISTON:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_SPRUCE_DOOR:
|
||||
case E_BLOCK_SPRUCE_FENCE_GATE:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block has the potential to output power */
|
||||
inline static bool IsPotentialSource(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_TRAPPED_CHEST:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block is any sort of redstone device */
|
||||
inline static bool IsRedstone(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
// All redstone devices, please alpha sort
|
||||
case E_BLOCK_ACACIA_DOOR:
|
||||
case E_BLOCK_ACACIA_FENCE_GATE:
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
case E_BLOCK_BIRCH_DOOR:
|
||||
case E_BLOCK_BIRCH_FENCE_GATE:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_DARK_OAK_DOOR:
|
||||
case E_BLOCK_DARK_OAK_FENCE_GATE:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_INACTIVE_COMPARATOR:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_IRON_TRAPDOOR:
|
||||
case E_BLOCK_JUNGLE_DOOR:
|
||||
case E_BLOCK_JUNGLE_FENCE_GATE:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_SPRUCE_DOOR:
|
||||
case E_BLOCK_SPRUCE_FENCE_GATE:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_TRAPPED_CHEST:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_TRIPWIRE:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_PISTON:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool AreCoordsOnChunkBoundary(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
return ( // Are we on a chunk boundary? +- 2 because of LinkedPowered blocks
|
||||
((a_BlockX % cChunkDef::Width) <= 1) ||
|
||||
((a_BlockX % cChunkDef::Width) >= 14) ||
|
||||
((a_BlockZ % cChunkDef::Width) <= 1) ||
|
||||
((a_BlockZ % cChunkDef::Width) >= 14)
|
||||
);
|
||||
}
|
||||
|
||||
inline static Vector3i AdjustRelativeCoords(const Vector3i & a_RelPosition)
|
||||
{
|
||||
if (
|
||||
(a_RelPosition.x >= 0) && (a_RelPosition.x < cChunkDef::Width) &&
|
||||
(a_RelPosition.z >= 0) && (a_RelPosition.z < cChunkDef::Width)
|
||||
)
|
||||
{
|
||||
return a_RelPosition;
|
||||
}
|
||||
|
||||
Vector3i RelPos = a_RelPosition;
|
||||
|
||||
// Request for a different chunk, calculate chunk offset:
|
||||
while (RelPos.x >= cChunkDef::Width)
|
||||
{
|
||||
RelPos.x -= cChunkDef::Width;
|
||||
}
|
||||
while (RelPos.x < 0)
|
||||
{
|
||||
RelPos.x += cChunkDef::Width;
|
||||
}
|
||||
while (RelPos.z >= cChunkDef::Width)
|
||||
{
|
||||
RelPos.z -= cChunkDef::Width;
|
||||
}
|
||||
while (RelPos.z < 0)
|
||||
{
|
||||
RelPos.z += cChunkDef::Width;
|
||||
}
|
||||
|
||||
return RelPos;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,9 +8,9 @@
|
||||
|
||||
|
||||
class cRedstoneNoopSimulator :
|
||||
public cRedstoneSimulator<cChunk, cWorld>
|
||||
public cRedstoneSimulator
|
||||
{
|
||||
typedef cRedstoneSimulator<cChunk, cWorld> super;
|
||||
typedef cRedstoneSimulator super;
|
||||
public:
|
||||
|
||||
cRedstoneNoopSimulator(cWorld & a_World) :
|
||||
|
@ -13,14 +13,14 @@ public:
|
||||
|
||||
inline cRedstoneSimulatorChunkData::~cRedstoneSimulatorChunkData() {}
|
||||
|
||||
template <class ChunkType, class WorldType>
|
||||
|
||||
class cRedstoneSimulator :
|
||||
public cSimulator<ChunkType, WorldType>
|
||||
public cSimulator
|
||||
{
|
||||
typedef cSimulator<ChunkType, WorldType> super;
|
||||
typedef cSimulator super;
|
||||
|
||||
public:
|
||||
cRedstoneSimulator(WorldType & a_World) :
|
||||
cRedstoneSimulator(cWorld & a_World) :
|
||||
super(a_World)
|
||||
{
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ typedef cCoordWithIntList cSandSimulatorChunkData;
|
||||
|
||||
/// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air.
|
||||
class cSandSimulator :
|
||||
public cSimulator<cChunk, cWorld>
|
||||
public cSimulator
|
||||
{
|
||||
public:
|
||||
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||
|
@ -6,13 +6,35 @@
|
||||
#include "../Defines.h"
|
||||
#include "../Chunk.h"
|
||||
|
||||
#include "Simulator.inc"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wweak-template-vtables"
|
||||
#endif // __clang__
|
||||
|
||||
template class cSimulator<cChunk, cWorld>;
|
||||
|
||||
|
||||
#include "Simulator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
||||
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
|
||||
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
|
||||
if (a_BlockY > 0)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
|
||||
}
|
||||
if (a_BlockY < cChunkDef::Height - 1)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,24 +3,28 @@
|
||||
|
||||
#include "../Vector3.h"
|
||||
|
||||
class cWorld;
|
||||
class cChunk;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class ChunkType, class WorldType>
|
||||
class cSimulator
|
||||
{
|
||||
public:
|
||||
cSimulator(WorldType & a_World);
|
||||
virtual ~cSimulator();
|
||||
cSimulator(cWorld & a_World)
|
||||
: m_World(a_World)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~cSimulator() {}
|
||||
|
||||
/// Called in each tick, a_Dt is the time passed since the last tick, in msec
|
||||
virtual void Simulate(float a_Dt) = 0;
|
||||
|
||||
/// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX,
|
||||
int a_ChunkZ, ChunkType * a_Chunk)
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||
{
|
||||
UNUSED(a_Dt);
|
||||
UNUSED(a_ChunkX);
|
||||
@ -29,7 +33,7 @@ public:
|
||||
}
|
||||
|
||||
/// Called when a block changes
|
||||
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk);
|
||||
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
|
||||
|
||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
||||
|
||||
@ -37,9 +41,9 @@ protected:
|
||||
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
||||
|
||||
/// Called to simulate a new block
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) = 0;
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0;
|
||||
|
||||
WorldType & m_World;
|
||||
cWorld & m_World;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
|
||||
|
||||
#include "Simulator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
template <class ChunkType, class WorldType>
|
||||
cSimulator<ChunkType, WorldType>::cSimulator(WorldType & a_World)
|
||||
: m_World(a_World)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class ChunkType, class WorldType>
|
||||
cSimulator<ChunkType, WorldType>::~cSimulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class ChunkType, class WorldType>
|
||||
void cSimulator<ChunkType, WorldType>::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
||||
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
|
||||
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
|
||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
|
||||
if (a_BlockY > 0)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
|
||||
}
|
||||
if (a_BlockY < cChunkDef::Height - 1)
|
||||
{
|
||||
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk
|
||||
|
||||
|
||||
|
||||
void cSimulatorManager::RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate)
|
||||
void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate)
|
||||
{
|
||||
m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ public:
|
||||
|
||||
void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
|
||||
|
||||
void RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
|
||||
void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
|
||||
|
||||
protected:
|
||||
typedef std::vector <std::pair<cSimulator<cChunk, cWorld> *, int> > cSimulators;
|
||||
typedef std::vector <std::pair<cSimulator *, int> > cSimulators;
|
||||
|
||||
cWorld & m_World;
|
||||
cSimulators m_Simulators;
|
||||
|
@ -1520,7 +1520,21 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case E_BLOCK_COCOA_POD:
|
||||
{
|
||||
NIBBLETYPE TypeMeta = BlockMeta & 0x03;
|
||||
int GrowState = BlockMeta >> 2;
|
||||
|
||||
if (GrowState < 2)
|
||||
{
|
||||
GrowState++;
|
||||
FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, (NIBBLETYPE) (GrowState << 2 | TypeMeta));
|
||||
BroadcastSoundParticleEffect(2005, a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case E_BLOCK_CROPS:
|
||||
{
|
||||
if (a_IsByBonemeal && !m_IsCropsBonemealable)
|
||||
@ -3280,7 +3294,6 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
return -1;
|
||||
}
|
||||
|
||||
BroadcastSpawnEntity(*a_Monster);
|
||||
cPluginManager::Get()->CallHookSpawnedMonster(*this, *a_Monster);
|
||||
|
||||
return a_Monster->GetUniqueID();
|
||||
@ -3373,7 +3386,7 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke
|
||||
|
||||
|
||||
|
||||
cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||
cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||
{
|
||||
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental");
|
||||
|
||||
@ -3383,11 +3396,11 @@ cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFil
|
||||
SimulatorName = "Incremental";
|
||||
}
|
||||
|
||||
cRedstoneSimulator<cChunk, cWorld> * res = nullptr;
|
||||
cRedstoneSimulator * res = nullptr;
|
||||
|
||||
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
||||
{
|
||||
res = MakeIncrementalRedstoneSimulator(*this);
|
||||
res = new cIncrementalRedstoneSimulator(*this);
|
||||
}
|
||||
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
||||
{
|
||||
|
@ -34,7 +34,6 @@
|
||||
class cFireSimulator;
|
||||
class cFluidSimulator;
|
||||
class cSandSimulator;
|
||||
template <class ChunkType, class WorldType>
|
||||
class cRedstoneSimulator;
|
||||
class cItem;
|
||||
class cPlayer;
|
||||
@ -518,7 +517,7 @@ public:
|
||||
|
||||
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
|
||||
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
|
||||
inline cRedstoneSimulator<cChunk, cWorld> * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
||||
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
||||
|
||||
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
@ -935,7 +934,7 @@ private:
|
||||
cFluidSimulator * m_WaterSimulator;
|
||||
cFluidSimulator * m_LavaSimulator;
|
||||
std::unique_ptr<cFireSimulator> m_FireSimulator;
|
||||
cRedstoneSimulator<cChunk, cWorld> * m_RedstoneSimulator;
|
||||
cRedstoneSimulator * m_RedstoneSimulator;
|
||||
|
||||
cCriticalSection m_CSPlayers;
|
||||
cPlayerList m_Players;
|
||||
@ -1079,7 +1078,7 @@ private:
|
||||
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
|
||||
|
||||
/** Creates a new redstone simulator.*/
|
||||
cRedstoneSimulator<cChunk, cWorld> * InitializeRedstoneSimulator(cIniFile & a_IniFile);
|
||||
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile);
|
||||
|
||||
/** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
|
||||
Assumes it is called from the Tick thread. */
|
||||
|
@ -5,4 +5,3 @@ enable_testing()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(ChunkData)
|
||||
add_subdirectory(Redstone)
|
||||
|
@ -1,10 +0,0 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
enable_testing()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/)
|
||||
|
||||
add_definitions(-DTEST_GLOBALS=1)
|
||||
|
||||
add_executable(Redstone-creatable-exe creatable.cpp ../../src/BoundingBox.cpp)
|
||||
add_test(NAME creatable-test COMMAND Redstone-creatable-exe)
|
@ -1,164 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
class MockChest;
|
||||
typedef cItemCallback<MockChest> cChestCallback;
|
||||
|
||||
AString ItemToFullString(const cItem & a_Item)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
class cEntity
|
||||
{
|
||||
public:
|
||||
const Vector3d & GetPosition (void) const { return m_pos;}
|
||||
double GetWidth (void) const { return 0; }
|
||||
double GetHeight (void) const { return 0; }
|
||||
static const Vector3d m_pos;
|
||||
};
|
||||
|
||||
const Vector3d cEntity::m_pos = Vector3d(0,0,0);
|
||||
|
||||
class cItem
|
||||
{
|
||||
public:
|
||||
cItem(BLOCKTYPE val) {}
|
||||
};
|
||||
|
||||
void cBlockInfo::Initialize(cBlockInfoArray & a_Info) {}
|
||||
cBlockInfo::~cBlockInfo () {}
|
||||
|
||||
#include "Blocks/ChunkInterface.h"
|
||||
|
||||
bool cChunkInterface::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "Simulator/Simulator.inc"
|
||||
|
||||
#include "Simulator/IncrementalRedstoneSimulator.inc"
|
||||
|
||||
class MockWorld;
|
||||
|
||||
|
||||
class MockHandler
|
||||
{
|
||||
public:
|
||||
static eBlockFace MetadataToDirection(NIBBLETYPE a_MetaData) { return BLOCK_FACE_NONE; }
|
||||
static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData) { return BLOCK_FACE_NONE; }
|
||||
static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_MetaData) { return BLOCK_FACE_NONE; }
|
||||
static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { return 0; }
|
||||
static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, MockWorld * a_World) {}
|
||||
static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, MockWorld * a_World) {}
|
||||
static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) {}
|
||||
|
||||
};
|
||||
|
||||
template<unsigned char val>
|
||||
class MockHandlerFetcher
|
||||
{
|
||||
public:
|
||||
typedef MockHandler type;
|
||||
};
|
||||
|
||||
class MockWorld
|
||||
{
|
||||
public:
|
||||
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ) { return false; }
|
||||
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback) { return false; }
|
||||
|
||||
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL) {}
|
||||
|
||||
|
||||
NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) { return 0; }
|
||||
|
||||
cPlayer * FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true) { return NULL; }
|
||||
|
||||
|
||||
void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) {}
|
||||
|
||||
void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1) {}
|
||||
|
||||
|
||||
bool SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) {return false; }
|
||||
|
||||
|
||||
cChunkMap * GetChunkMap (void) { return NULL; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
class MockChunk
|
||||
{
|
||||
public:
|
||||
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData() { return NULL; }
|
||||
void SetRedstoneSimulatorData(cRedstoneSimulatorChunkData * a_Data) {}
|
||||
bool IsRedstoneDirty() { return true; }
|
||||
void SetIsRedstoneDirty(bool a_Param) {}
|
||||
|
||||
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) {}
|
||||
|
||||
void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true) {}
|
||||
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) {}
|
||||
|
||||
int GetPosX(void) const { return 0; }
|
||||
int GetPosZ(void) const { return 0; }
|
||||
|
||||
MockChunk * GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const { return NULL; }
|
||||
|
||||
|
||||
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const { return 0; }
|
||||
BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return 0; }
|
||||
|
||||
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const { return 0; }
|
||||
void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) {}
|
||||
|
||||
|
||||
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { return false; }
|
||||
|
||||
bool UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType) const { return false; }
|
||||
|
||||
MockChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ) { return NULL; }
|
||||
|
||||
MockChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ) { return NULL; }
|
||||
|
||||
bool IsValid(void) const { return false; }
|
||||
|
||||
NIBBLETYPE GetTimeAlteredLight(NIBBLETYPE a_Skylight) const { return 0; }
|
||||
|
||||
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL) {}
|
||||
void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) {}
|
||||
|
||||
bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback) { return false; }
|
||||
|
||||
template <class T>
|
||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, T & a_Callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
class MockChest
|
||||
{
|
||||
public:
|
||||
BLOCKTYPE GetBlockType(void) const { return 0; }
|
||||
int GetNumberOfPlayers(void) const { return 0; }
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
|
||||
|
||||
MockWorld World;
|
||||
|
||||
cIncrementalRedstoneSimulator<MockChunk, MockWorld, MockHandlerFetcher, MockChest> Simulator(World);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user