1
0
Fork 0

Merge branch 'master' into portals

Conflicts:
	src/Chunk.cpp
	src/Entities/Entity.h
	src/Entities/Player.h
This commit is contained in:
Tiger Wang 2014-06-21 22:14:23 +01:00
commit 7615ed90c0
103 changed files with 5739 additions and 3568 deletions

View File

@ -1,5 +1,6 @@
Many people have contributed to MCServer, and this list attempts to broadcast at least some of them.
BasedDoge - Donated AlchemistVillage prefabs
bearbin (Alexander Harkness)
derouinw
Diusrex
@ -26,5 +27,6 @@ tonibm19
UltraCoderRU
worktycho
xoft
Yeeeeezus - Donated AlchemistVillage prefabs
Please add yourself to this list if you contribute to MCServer.

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="BiomeVisualiser"
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
RootNamespace="BiomeVisualiser"
@ -327,6 +327,14 @@
<Filter
Name="Shared"
>
<File
RelativePath="..\..\src\BiomeDef.cpp"
>
</File>
<File
RelativePath="..\..\src\BiomeDef.h"
>
</File>
<File
RelativePath="..\..\src\BlockID.cpp"
>
@ -355,6 +363,14 @@
RelativePath="..\..\src\WorldStorage\FastNBT.h"
>
</File>
<File
RelativePath="..\..\src\FastRandom.cpp"
>
</File>
<File
RelativePath="..\..\src\FastRandom.h"
>
</File>
<File
RelativePath="..\..\src\Globals.cpp"
>

109
src/AllocationPool.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#include <memory>
template<class T>
class cAllocationPool
{
public:
class cStarvationCallbacks
{
public:
virtual ~cStarvationCallbacks() {}
/** Is called when the reserve buffer starts to be used **/
virtual void OnStartUsingReserve() = 0;
/** Is called once the reserve buffer has returned to normal size **/
virtual void OnEndUsingReserve() = 0;
/** Is called when the allocation pool is unable to allocate memory. Will be repeatedly
called if it does not free sufficient memory **/
virtual void OnOutOfReserve() = 0;
};
virtual ~cAllocationPool() {}
/** Allocates a pointer to T **/
virtual T * Allocate() = 0;
/** Frees the pointer passed in a_ptr, invalidating it **/
virtual void Free(T * a_ptr) = 0;
};
/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/
template<class T, size_t NumElementsInReserve>
class cListAllocationPool : public cAllocationPool<T>
{
public:
cListAllocationPool(std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks) :
m_Callbacks(a_Callbacks)
{
for (size_t i = 0; i < NumElementsInReserve; i++)
{
void * space = malloc(sizeof(T));
if (space == NULL)
{
m_Callbacks->OnStartUsingReserve();
break;
}
m_FreeList.push_front(space);
}
}
virtual ~cListAllocationPool()
{
while (!m_FreeList.empty())
{
free (m_FreeList.front());
m_FreeList.pop_front();
}
}
virtual T * Allocate() override
{
if (m_FreeList.size() <= NumElementsInReserve)
{
void * space = malloc(sizeof(T));
if (space != NULL)
{
return new(space) T;
}
else if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnStartUsingReserve();
}
else if (m_FreeList.empty())
{
m_Callbacks->OnOutOfReserve();
// Try again until the memory is avalable
return Allocate();
}
}
// placement new, used to initalize the object
T * ret = new (m_FreeList.front()) T;
m_FreeList.pop_front();
return ret;
}
virtual void Free(T * a_ptr) override
{
if (a_ptr == NULL)
{
return;
}
// placement destruct.
a_ptr->~T();
m_FreeList.push_front(a_ptr);
if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnEndUsingReserve();
}
}
private:
std::list<void *> m_FreeList;
std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
};

1
src/Bindings/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
lua51.dll

View File

@ -1765,6 +1765,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
if (!ChunkStay->AddChunks(2))
{
delete ChunkStay;
ChunkStay = NULL;
return 0;
}

View File

@ -1571,6 +1571,7 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType);
m_LuaState.LogStackTrace();
delete Ref;
Ref = NULL;
return false;
}

View File

@ -1467,6 +1467,7 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin)
a_Plugin->OnDisable();
}
delete a_Plugin;
a_Plugin = NULL;
}

Binary file not shown.

View File

@ -295,9 +295,9 @@ cBlockArea::~cBlockArea()
void cBlockArea::Clear(void)
{
delete[] m_BlockTypes; m_BlockTypes = NULL;
delete[] m_BlockMetas; m_BlockMetas = NULL;
delete[] m_BlockLight; m_BlockLight = NULL;
delete[] m_BlockTypes; m_BlockTypes = NULL;
delete[] m_BlockMetas; m_BlockMetas = NULL;
delete[] m_BlockLight; m_BlockLight = NULL;
delete[] m_BlockSkyLight; m_BlockSkyLight = NULL;
m_Origin.Set(0, 0, 0);
m_Size.Set(0, 0, 0);
@ -1013,8 +1013,8 @@ void cBlockArea::RotateCCW(void)
} // for x
std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas);
delete[] NewTypes;
delete[] NewMetas;
delete[] NewTypes; NewTypes = NULL;
delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z);
}
@ -1058,8 +1058,8 @@ void cBlockArea::RotateCW(void)
} // for x
std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas);
delete[] NewTypes;
delete[] NewMetas;
delete[] NewTypes; NewTypes = NULL;
delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z);
}
@ -1206,7 +1206,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z
} // for x
std::swap(m_BlockTypes, NewTypes);
delete[] NewTypes;
delete[] NewTypes; NewTypes = NULL;
}
if (HasBlockMetas())
{
@ -1224,7 +1224,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z
} // for x
std::swap(m_BlockMetas, NewMetas);
delete[] NewMetas;
delete[] NewMetas; NewMetas = NULL;
}
std::swap(m_Size.x, m_Size.z);
}
@ -1251,7 +1251,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x
} // for z
std::swap(m_BlockTypes, NewTypes);
delete[] NewTypes;
delete[] NewTypes; NewTypes = NULL;
}
if (HasBlockMetas())
{
@ -1269,7 +1269,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x
} // for z
std::swap(m_BlockMetas, NewMetas);
delete[] NewMetas;
delete[] NewMetas; NewMetas = NULL;
}
std::swap(m_Size.x, m_Size.z);
}
@ -1658,6 +1658,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockMetas == NULL)
{
delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false;
}
}
@ -1667,7 +1668,9 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockLight == NULL)
{
delete[] m_BlockMetas;
m_BlockMetas = NULL;
delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false;
}
}
@ -1677,8 +1680,11 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockSkyLight == NULL)
{
delete[] m_BlockLight;
m_BlockLight = NULL;
delete[] m_BlockMetas;
m_BlockMetas = NULL;
delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false;
}
}

View File

@ -70,6 +70,8 @@ void cMobHeadEntity::SetOwner(const AString & a_Owner)
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
{
cWorld * World = a_Client.GetPlayer()->GetWorld();
a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(m_PosX, m_PosY, m_PosZ));
a_Client.SendUpdateBlockEntity(*this);
}

View File

@ -34,6 +34,7 @@ cBlockInfo::cBlockInfo()
cBlockInfo::~cBlockInfo()
{
delete m_Handler;
m_Handler = NULL;
}
@ -341,6 +342,8 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
ms_Info[E_BLOCK_FENCE ].m_IsSolid = false;
ms_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
ms_Info[E_BLOCK_FIRE ].m_IsSolid = false;
ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;

View File

@ -156,10 +156,10 @@ public:
if (a_BlockX > 0)
{
NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
return (DownMeta & 0x07) | 0x08 | (Meta << 4);
return (NIBBLETYPE) ((DownMeta & 0x07) | 0x08 | (Meta << 4));
}
// This is the top part of the door at the bottommost layer of the world, there's no bottom:
return 0x08 | (Meta << 4);
return (NIBBLETYPE) (0x08 | (Meta << 4));
}
else
{
@ -167,7 +167,7 @@ public:
if (a_BlockY < cChunkDef::Height - 1)
{
NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ);
return Meta | (UpMeta << 4);
return (NIBBLETYPE) (Meta | (UpMeta << 4));
}
// This is the bottom part of the door at the topmost layer of the world, there's no top:
return Meta;

View File

@ -36,8 +36,8 @@ public:
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
*/
a_BlockY--; // Because we want the block below the fire
FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface);
// a_BlockY - 1: Because we want the block below the fire
FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
}
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override

View File

@ -38,6 +38,7 @@
#include "BlockGlass.h"
#include "BlockGlowstone.h"
#include "BlockGravel.h"
#include "BlockHayBale.h"
#include "BlockMobHead.h"
#include "BlockHopper.h"
#include "BlockIce.h"
@ -56,6 +57,7 @@
#include "BlockPlanks.h"
#include "BlockPortal.h"
#include "BlockPumpkin.h"
#include "BlockPressurePlate.h"
#include "BlockQuartz.h"
#include "BlockRail.h"
#include "BlockRedstone.h"
@ -130,10 +132,12 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType);
case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
@ -149,6 +153,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
@ -186,12 +191,15 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType);
case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType);
case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STATIONARY_LAVA: return new cBlockLavaHandler (a_BlockType);
case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType);
case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STONE_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_STONE_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType);
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
@ -203,6 +211,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_WOODEN_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType);

29
src/Blocks/BlockHayBale.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "BlockHandler.h"
#include "BlockSideways.h"
class cBlockHayBaleHandler :
public cBlockSidewaysHandler
{
public:
cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
: cBlockSidewaysHandler(a_BlockType)
{
}
virtual const char * GetStepSound(void) override
{
return "step.grass";
}
} ;

View File

@ -19,24 +19,69 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
// The drop spawn is in OnDestroyed method
}
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
if (a_Player->IsGameModeCreative())
{
// No drops in creative mode
return;
}
class cCallback : public cBlockEntityCallback
{
virtual bool Item(cBlockEntity * a_BlockEntity)
{
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
cItems Pickups;
Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType());
MTRand r1;
// Mid-block position first
double MicroX, MicroY, MicroZ;
MicroX = MobHeadEntity->GetPosX() + 0.5;
MicroY = MobHeadEntity->GetPosY() + 0.5;
MicroZ = MobHeadEntity->GetPosZ() + 0.5;
// Add random offset second
MicroX += r1.rand(1) - 0.5;
MicroZ += r1.rand(1) - 0.5;
MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
return false;
}
} Callback;
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
}
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
if (a_BlockY < 2)
{
return false;
}
class cCallback : public cMobHeadCallback
class cCallback : public cBlockEntityCallback
{
bool m_IsWither;
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
virtual bool Item(cBlockEntity * a_BlockEntity)
{
m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
return false;
}
@ -70,7 +115,7 @@ public:
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
if (!CallbackA.IsWither())
{
@ -87,8 +132,8 @@ public:
return false;
}
a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
@ -101,15 +146,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities
a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
a_World->ForEachPlayer(PlayerCallback);
a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@ -117,8 +162,8 @@ public:
CallbackA.Reset();
CallbackB.Reset();
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
@ -131,15 +176,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
// Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
a_World->ForEachPlayer(PlayerCallback);
a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@ -154,23 +199,29 @@ public:
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
class cCallback : public cMobHeadCallback
class cCallback : public cBlockEntityCallback
{
cPlayer * m_Player;
NIBBLETYPE m_OldBlockMeta;
NIBBLETYPE m_NewBlockMeta;
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
virtual bool Item(cBlockEntity * a_BlockEntity)
{
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
int Rotation = 0;
if (m_NewBlockMeta == 1)
{
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
}
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
return false;
}
@ -184,8 +235,7 @@ public:
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
cWorld * World = (cWorld *) &a_WorldInterface;
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
if (a_BlockMeta == SKULL_TYPE_WITHER)
@ -200,7 +250,7 @@ public:
};
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
{
if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
{
break;
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "BlockHandler.h"
class cBlockPressurePlateHandler :
public cBlockHandler
{
public:
cBlockPressurePlateHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// Reset meta to 0
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 0)
{
return false;
}
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow));
}
} ;

View File

@ -80,6 +80,7 @@ public:
if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
{
a_BlockType = GetDoubleSlabType(m_BlockType);
a_BlockMeta = a_BlockMeta & 0x7;
}
return true;

View File

@ -6,6 +6,12 @@
class cItems;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
class cWorldInterface
{
public:
@ -29,6 +35,9 @@ public:
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
/** Sends the block on those coords to the player */
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;

View File

@ -165,6 +165,7 @@ cByteBuffer::~cByteBuffer()
{
CheckValid();
delete[] m_Buffer;
m_Buffer = NULL;
}

View File

@ -82,17 +82,36 @@ set(BINDING_DEPENDECIES
include_directories(Bindings)
include_directories(.)
ADD_CUSTOM_COMMAND(
# add any new generated bindings here
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
if (WIN32)
ADD_CUSTOM_COMMAND(
# add any new generated bindings here
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
# command execuded to regerate bindings
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
# Copy the Lua DLL into the Bindings folder, so that tolua can run from there:
COMMAND copy /y ..\\..\\MCServer\\lua51.dll .
# add any new generation dependencies here
DEPENDS ${BINDING_DEPENDECIES}
)
# Regenerate bindings:
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
# add any new generation dependencies here
DEPENDS ${BINDING_DEPENDECIES}
)
else ()
ADD_CUSTOM_COMMAND(
# add any new generated bindings here
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
# Regenerate bindings:
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
# add any new generation dependencies here
DEPENDS ${BINDING_DEPENDECIES}
)
endif ()
set_source_files_properties(Bindings/Bindings.cpp PROPERTIES GENERATED TRUE)
set_source_files_properties(Bindings/Bindings.h PROPERTIES GENERATED TRUE)
if (NOT MSVC)
@ -149,16 +168,6 @@ if (NOT MSVC)
else ()
# MSVC-specific handling: Put all files into one project, separate by the folders:
# Generate the Bindings if they don't exist:
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/Bindings/Bindings.cpp")
message("Bindings.cpp not found, generating now")
set(tolua_executable ${PROJECT_SOURCE_DIR}/Bindings/tolua++.exe)
execute_process(
COMMAND ${tolua_executable} -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/Bindings
)
endif()
# Get all files in this folder:
file(GLOB_RECURSE SOURCE
"*.cpp"
@ -167,6 +176,9 @@ else ()
)
source_group("" FILES ${SOURCE})
LIST(APPEND SOURCE "Bindings/Bindings.cpp" "Bindings/Bindings.h")
source_group(Bindings FILES "Bindings/Bindings.cpp" "Bindings/Bindings.h")
# Add all subfolders as solution-folders:
list(APPEND FOLDERS "Resources")
list(APPEND FOLDERS "Bindings")

View File

@ -64,7 +64,8 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc
cChunk::cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
cChunkMap * a_ChunkMap, cWorld * a_World,
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
) :
m_IsValid(false),
m_IsLightValid(false),
@ -77,6 +78,7 @@ cChunk::cChunk(
m_PosZ(a_ChunkZ),
m_World(a_World),
m_ChunkMap(a_ChunkMap),
m_ChunkData(a_Pool),
m_BlockTickX(0),
m_BlockTickY(0),
m_BlockTickZ(0),
@ -150,7 +152,9 @@ cChunk::~cChunk()
m_NeighborZP->m_NeighborZM = NULL;
}
delete m_WaterSimulatorData;
m_WaterSimulatorData = NULL;
delete m_LavaSimulatorData;
m_LavaSimulatorData = NULL;
}
@ -597,7 +601,7 @@ void cChunk::Tick(float a_Dt)
itr = m_Entities.erase(itr);
delete ToDelete;
}
else if ((*itr)->IsTravellingThroughPortal())
else if ((*itr)->IsTravellingThroughPortal()) // Remove all entities that are travelling to another world
{
MarkDirty();
(*itr)->SetIsTravellingThroughPortal(false);
@ -1416,6 +1420,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
BlockEntity->Destroy();
RemoveBlockEntity(BlockEntity);
delete BlockEntity;
BlockEntity = NULL;
}
// If the new block is a block entity, create the entity object:

View File

@ -65,7 +65,8 @@ public:
cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
cAllocationPool<cChunkData::sChunkSection> & a_Pool
);
cChunk(cChunk & other);
~cChunk();

View File

@ -27,11 +27,12 @@ template <typename T> inline bool IsAllValue(const T * a_Array, size_t a_NumElem
cChunkData::cChunkData(void)
cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool) :
#if __cplusplus < 201103L
// auto_ptr style interface for memory management
: m_IsOwner(true)
m_IsOwner(true),
#endif
m_Pool(a_Pool)
{
for (size_t i = 0; i < NumSections; i++)
{
@ -66,7 +67,8 @@ cChunkData::~cChunkData()
#if __cplusplus < 201103L
// auto_ptr style interface for memory management
cChunkData::cChunkData(const cChunkData & a_Other) :
m_IsOwner(true)
m_IsOwner(true),
m_Pool(a_Other.m_Pool)
{
// Move contents and ownership from a_Other to this, pointer-wise:
for (size_t i = 0; i < NumSections; i++)
@ -97,7 +99,7 @@ cChunkData::~cChunkData()
m_Sections[i] = NULL;
}
}
// Move contents and ownership from a_Other to this, pointer-wise:
m_IsOwner = true;
for (size_t i = 0; i < NumSections; i++)
@ -105,13 +107,15 @@ cChunkData::~cChunkData()
m_Sections[i] = a_Other.m_Sections[i];
}
a_Other.m_IsOwner = false;
ASSERT(&m_Pool == &a_Other.m_Pool);
return *this;
}
#else
// unique_ptr style interface for memory management
cChunkData::cChunkData(cChunkData && other)
cChunkData::cChunkData(cChunkData && other) :
m_Pool(other.m_Pool)
{
for (size_t i = 0; i < NumSections; i++)
{
@ -128,6 +132,7 @@ cChunkData::~cChunkData()
{
if (&other != this)
{
ASSERT(&m_Pool == &other.m_Pool);
for (size_t i = 0; i < NumSections; i++)
{
Free(m_Sections[i]);
@ -317,12 +322,12 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
cChunkData cChunkData::Copy(void) const
{
cChunkData copy;
cChunkData copy(m_Pool);
for (size_t i = 0; i < NumSections; i++)
{
if (m_Sections[i] != NULL)
{
copy.m_Sections[i] = Allocate();
copy.m_Sections[i] = copy.Allocate();
*copy.m_Sections[i] = *m_Sections[i];
}
}
@ -561,8 +566,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src)
cChunkData::sChunkSection * cChunkData::Allocate(void)
{
// TODO: Use an allocation pool
return new cChunkData::sChunkSection;
return m_Pool.Allocate();
}
@ -571,8 +575,7 @@ cChunkData::sChunkSection * cChunkData::Allocate(void)
void cChunkData::Free(cChunkData::sChunkSection * a_Section)
{
// TODO: Use an allocation pool
delete a_Section;
m_Pool.Free(a_Section);
}

View File

@ -15,6 +15,7 @@
#include "ChunkDef.h"
#include "AllocationPool.h"
@ -26,9 +27,17 @@
class cChunkData
{
private:
static const size_t SectionHeight = 16;
static const size_t NumSections = (cChunkDef::Height / SectionHeight);
static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
public:
cChunkData(void);
struct sChunkSection;
cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool);
~cChunkData();
#if __cplusplus < 201103L
@ -53,17 +62,17 @@ public:
/** Creates a (deep) copy of self. */
cChunkData Copy(void) const;
/** Copies the blocktype data into the specified flat array.
Optionally, only a part of the data is copied, as specified by the a_Idx and a_Length parameters. */
void CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const;
/** Copies the metadata into the specified flat array. */
void CopyMetas(NIBBLETYPE * a_Dest) const;
/** Copies the block light data into the specified flat array. */
void CopyBlockLight(NIBBLETYPE * a_Dest) const;
/** Copies the skylight data into the specified flat array. */
void CopySkyLight (NIBBLETYPE * a_Dest) const;
@ -71,12 +80,12 @@ public:
Allocates sections that are needed for the operation.
Requires that a_Src is a valid pointer. */
void SetBlockTypes(const BLOCKTYPE * a_Src);
/** Copies the metadata from the specified flat array into the internal representation.
Allocates sectios that are needed for the operation.
Requires that a_Src is a valid pointer. */
void SetMetas(const NIBBLETYPE * a_Src);
/** Copies the blocklight data from the specified flat array into the internal representation.
Allocates sectios that are needed for the operation.
Allows a_Src to be NULL, in which case it doesn't do anything. */
@ -86,36 +95,35 @@ public:
Allocates sectios that are needed for the operation.
Allows a_Src to be NULL, in which case it doesn't do anything. */
void SetSkyLight(const NIBBLETYPE * a_Src);
struct sChunkSection
{
BLOCKTYPE m_BlockTypes [SectionHeight * 16 * 16] ;
NIBBLETYPE m_BlockMetas [SectionHeight * 16 * 16 / 2];
NIBBLETYPE m_BlockLight [SectionHeight * 16 * 16 / 2];
NIBBLETYPE m_BlockSkyLight[SectionHeight * 16 * 16 / 2];
};
private:
static const size_t SectionHeight = 16;
static const size_t NumSections = (cChunkDef::Height / SectionHeight);
static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
#if __cplusplus < 201103L
// auto_ptr style interface for memory management
mutable bool m_IsOwner;
#endif
struct sChunkSection {
BLOCKTYPE m_BlockTypes [SectionBlockCount];
NIBBLETYPE m_BlockMetas [SectionBlockCount / 2];
NIBBLETYPE m_BlockLight [SectionBlockCount / 2];
NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2];
};
sChunkSection * m_Sections[NumSections];
cAllocationPool<cChunkData::sChunkSection> & m_Pool;
/** Allocates a new section. Entry-point to custom allocators. */
static sChunkSection * Allocate(void);
sChunkSection * Allocate(void);
/** Frees the specified section, previously allocated using Allocate().
Note that a_Section may be NULL. */
static void Free(sChunkSection * a_Section);
void Free(sChunkSection * a_Section);
/** Sets the data in the specified section to their default values. */
void ZeroSection(sChunkSection * a_Section) const;
};

View File

@ -34,8 +34,15 @@
// cChunkMap:
cChunkMap::cChunkMap(cWorld * a_World )
: m_World( a_World )
: m_World( a_World ),
m_Pool(
new cListAllocationPool<cChunkData::sChunkSection, 1600>(
std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>(
new cStarvationCallbacks())
)
)
{
}
@ -78,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
}
// Not found, create new:
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this);
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool);
if (Layer == NULL)
{
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
@ -2671,11 +2678,16 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
////////////////////////////////////////////////////////////////////////////////
// cChunkMap::cChunkLayer:
cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent)
cChunkMap::cChunkLayer::cChunkLayer(
int a_LayerX, int a_LayerZ,
cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
)
: m_LayerX( a_LayerX )
, m_LayerZ( a_LayerZ )
, m_Parent( a_Parent )
, m_NumChunksLoaded( 0 )
, m_Pool(a_Pool)
{
memset(m_Chunks, 0, sizeof(m_Chunks));
}
@ -2717,7 +2729,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ);
cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1);
cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1);
m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp);
m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool);
}
return m_Chunks[Index];
}

View File

@ -35,8 +35,8 @@ class cBlockArea;
class cMobCensus;
class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
@ -351,7 +351,11 @@ private:
class cChunkLayer
{
public:
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
cChunkLayer(
int a_LayerX, int a_LayerZ,
cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
);
~cChunkLayer();
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
@ -395,6 +399,25 @@ private:
int m_LayerZ;
cChunkMap * m_Parent;
int m_NumChunksLoaded;
cAllocationPool<cChunkData::sChunkSection> & m_Pool;
};
class cStarvationCallbacks
: public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
{
virtual void OnStartUsingReserve() override
{
LOG("Using backup memory buffer");
}
virtual void OnEndUsingReserve() override
{
LOG("Stoped using backup memory buffer");
}
virtual void OnOutOfReserve() override
{
LOG("Out of Memory");
}
};
typedef std::list<cChunkLayer *> cChunkLayerList;
@ -427,6 +450,8 @@ private:
/** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays;
std::auto_ptr<cAllocationPool<cChunkData::sChunkSection> > m_Pool;
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate

View File

@ -952,6 +952,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ;
// Check for clickthrough-blocks:
/* When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
return;
}
}
if (
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
@ -978,22 +998,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
}
}
}

View File

@ -59,6 +59,7 @@ cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) :
cCraftingGrid::~cCraftingGrid()
{
delete[] m_Items;
m_Items = NULL;
}

View File

@ -274,8 +274,19 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace)
}
}
inline eBlockFace ReverseBlockFace(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
case BLOCK_FACE_YP: return BLOCK_FACE_YM;
case BLOCK_FACE_XP: return BLOCK_FACE_XM;
case BLOCK_FACE_ZP: return BLOCK_FACE_ZM;
case BLOCK_FACE_YM: return BLOCK_FACE_YP;
case BLOCK_FACE_XM: return BLOCK_FACE_XP;
case BLOCK_FACE_ZM: return BLOCK_FACE_ZP;
default: return a_BlockFace;
}
}
/** Returns the textual representation of the BlockFace constant. */

View File

@ -180,14 +180,9 @@ void cEntity::WrapRotation(void)
void cEntity::WrapSpeed(void)
{
// There shoudn't be a need for flipping the flag on because this function is called
// after any update, so the flag is already turned on
if (m_Speed.x > 78.0f) m_Speed.x = 78.0f;
else if (m_Speed.x < -78.0f) m_Speed.x = -78.0f;
if (m_Speed.y > 78.0f) m_Speed.y = 78.0f;
else if (m_Speed.y < -78.0f) m_Speed.y = -78.0f;
if (m_Speed.z > 78.0f) m_Speed.z = 78.0f;
else if (m_Speed.z < -78.0f) m_Speed.z = -78.0f;
m_Speed.x = Clamp(m_Speed.x, -78.0, 78.0);
m_Speed.y = Clamp(m_Speed.y, -78.0, 78.0);
m_Speed.z = Clamp(m_Speed.z, -78.0, 78.0);
}
@ -1234,6 +1229,17 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
void cEntity::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
WrapSpeed();
}
void cEntity::HandleAir(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Chunk_format
@ -1586,9 +1592,7 @@ void cEntity::SetRoll(double a_Roll)
void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
WrapSpeed();
DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
}
@ -1596,9 +1600,7 @@ void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
void cEntity::SetSpeedX(double a_SpeedX)
{
m_Speed.x = a_SpeedX;
WrapSpeed();
SetSpeed(a_SpeedX, m_Speed.y, m_Speed.z);
}
@ -1606,9 +1608,7 @@ void cEntity::SetSpeedX(double a_SpeedX)
void cEntity::SetSpeedY(double a_SpeedY)
{
m_Speed.y = a_SpeedY;
WrapSpeed();
SetSpeed(m_Speed.x, a_SpeedY, m_Speed.z);
}
@ -1616,9 +1616,7 @@ void cEntity::SetSpeedY(double a_SpeedY)
void cEntity::SetSpeedZ(double a_SpeedZ)
{
m_Speed.z = a_SpeedZ;
WrapSpeed();
SetSpeed(m_Speed.x, m_Speed.y, a_SpeedZ);
}

View File

@ -215,11 +215,22 @@ public:
void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180)
void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180)
void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180)
void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ);
void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
void SetSpeedX (double a_SpeedX);
void SetSpeedY (double a_SpeedY);
void SetSpeedZ (double a_SpeedZ);
/** Sets the speed of the entity, measured in m / sec */
void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
/** Sets the speed of the entity, measured in m / sec */
void SetSpeed(const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
/** Sets the speed in the X axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedX(double a_SpeedX);
/** Sets the speed in the Y axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedY(double a_SpeedY);
/** Sets the speed in the Z axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedZ(double a_SpeedZ);
void SetWidth (double a_Width);
void AddPosX (double a_AddPosX);
@ -441,6 +452,9 @@ protected:
static cCriticalSection m_CSCount;
static int m_EntityCount;
/** Measured in meter/second (m/s) */
Vector3d m_Speed;
int m_UniqueID;
int m_Health;
@ -500,11 +514,15 @@ protected:
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
int m_TicksSinceLastVoidDamage;
/** Does the actual speed-setting. The default implementation just sets the member variable value;
overrides can provide further processing, such as forcing players to move at the given speed. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
virtual void Destroyed(void) {} // Called after the entity has been destroyed
/** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir();
virtual void HandleAir(void);
/** Called once per tick to set IsSwimming and IsSubmerged */
virtual void SetSwimState(cChunk & a_Chunk);
@ -526,9 +544,6 @@ private:
/** Measured in degrees, [-180, +180) */
double m_HeadYaw;
/** Measured in meter/second (m/s) */
Vector3d m_Speed;
/** Measured in degrees, [-180, +180) */
Vector3d m_Rot;

View File

@ -22,6 +22,12 @@
#include "inifile/iniFile.h"
#include "json/json.h"
// 6000 ticks or 5 minutes
#define PLAYER_INVENTORY_SAVE_INTERVAL 6000
// 1000 = once per second
#define PLAYER_LIST_TIME_MS 1000
@ -64,6 +70,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_BowCharge(0)
, m_FloaterID(-1)
, m_Team(NULL)
, m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL)
{
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
@ -135,6 +142,7 @@ cPlayer::~cPlayer(void)
m_ClientHandle = NULL;
delete m_InventoryWindow;
m_InventoryWindow = NULL;
LOGD("Player %p deleted", this);
}
@ -244,7 +252,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
// Send Player List (Once per m_LastPlayerListTime/1000 ms)
cTimer t1;
if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime())
if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime())
{
m_World->SendPlayerList(this);
m_LastPlayerListTime = t1.GetNowTime();
@ -254,6 +262,16 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
{
m_LastGroundHeight = (float)GetPosY();
}
if (m_TicksUntilNextSave == 0)
{
SaveToDisk();
m_TicksUntilNextSave = PLAYER_INVENTORY_SAVE_INTERVAL;
}
else
{
m_TicksUntilNextSave--;
}
}
@ -1251,6 +1269,17 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
void cPlayer::ForceSetSpeed(const Vector3d & a_Speed)
{
SetSpeed(a_Speed);
}
void cPlayer::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
super::DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
// Send the speed to the client so he actualy moves
m_ClientHandle->SendEntityVelocity(*this);
}

View File

@ -194,7 +194,8 @@ public:
// Sets the current gamemode, doesn't check validity, doesn't send update packets to client
void LoginSetGameMode(eGameMode a_GameMode);
/** Forces the player to move in the given direction. */
/** Forces the player to move in the given direction.
@deprecated Use SetSpeed instead. */
void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export
/** Tries to move to a new position, with attachment-related checks (y == -999) */
@ -479,7 +480,6 @@ protected:
cItem m_DraggingItem;
long long m_LastPlayerListTime;
static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second
cClientHandle * m_ClientHandle;
@ -528,6 +528,9 @@ protected:
cStatManager m_Stats;
/** Sets the speed and sends it to the client, so that they are forced to move so. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
void ResolvePermissions(void);
void ResolveGroups(void);
@ -555,6 +558,10 @@ protected:
Set by a right click on unoccupied bed, unset by a time fast forward or teleport */
bool m_bIsInBed;
/** How long till the player's inventory will be saved
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
unsigned int m_TicksUntilNextSave;
} ; // tolua_export

View File

@ -36,10 +36,6 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
{
TotalDamage = 3;
}
else if (MobType == cMonster::mtEnderDragon)
{
TotalDamage = 1;
}
}
// TODO: If entity is Ender Crystal, destroy it
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);

View File

@ -42,6 +42,7 @@ cFurnaceRecipe::~cFurnaceRecipe()
{
ClearRecipes();
delete m_pState;
m_pState = NULL;
}
@ -187,7 +188,9 @@ void cFurnaceRecipe::ClearRecipes(void)
{
Recipe R = *itr;
delete R.In;
R.In = NULL;
delete R.Out;
R.Out = NULL;
}
m_pState->Recipes.clear();
@ -195,6 +198,7 @@ void cFurnaceRecipe::ClearRecipes(void)
{
Fuel F = *itr;
delete F.In;
F.In = NULL;
}
m_pState->Fuel.clear();
}

View File

@ -135,7 +135,9 @@ cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) :
cBioGenCache::~cBioGenCache()
{
delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder;
m_CacheOrder = NULL;
}
@ -745,7 +747,12 @@ cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) :
m_VoronoiSmall(a_Seed + 2000),
m_DistortX(a_Seed + 3000),
m_DistortZ(a_Seed + 4000),
m_Noise(a_Seed + 5000)
m_Noise1(a_Seed + 5001),
m_Noise2(a_Seed + 5002),
m_Noise3(a_Seed + 5003),
m_Noise4(a_Seed + 5004),
m_Noise5(a_Seed + 5005),
m_Noise6(a_Seed + 5006)
{
}
@ -767,12 +774,12 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
int BlockZ = BaseZ + z * 4;
float BlockXF = (float)(16 * BlockX) / 128;
float BlockZF = (float)(16 * BlockZ) / 128;
double NoiseX = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 1000);
NoiseX += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 2000);
NoiseX += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 3000);
double NoiseZ = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 4000);
NoiseZ += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 5000);
NoiseZ += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 6000);
double NoiseX = m_Noise1.CubicNoise2D(BlockXF / 16, BlockZF / 16);
NoiseX += 0.5 * m_Noise2.CubicNoise2D(BlockXF / 8, BlockZF / 8);
NoiseX += 0.08 * m_Noise3.CubicNoise2D(BlockXF, BlockZF);
double NoiseZ = m_Noise4.CubicNoise2D(BlockXF / 16, BlockZF / 16);
NoiseZ += 0.5 * m_Noise5.CubicNoise2D(BlockXF / 8, BlockZF / 8);
NoiseZ += 0.08 * m_Noise6.CubicNoise2D(BlockXF, BlockZF);
DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX);
DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
@ -786,8 +793,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
{
for (int x = 0; x < cChunkDef::Width; x++)
{
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z]) / 7;
int MinDist1, MinDist2;
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
}

View File

@ -261,7 +261,12 @@ protected:
/// The noise used to distort the inupt Z coord
cPerlinNoise m_DistortZ;
cNoise m_Noise;
cNoise m_Noise1;
cNoise m_Noise2;
cNoise m_Noise3;
cNoise m_Noise4;
cNoise m_Noise5;
cNoise m_Noise6;
// cBiomeGen overrides:

View File

@ -125,7 +125,7 @@ public:
int m_BlockX;
int m_BlockZ;
cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
~cCaveSystem();
protected:
@ -574,8 +574,8 @@ AString cCaveTunnel::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) cons
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves::cCaveSystem:
cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
super(a_OriginX, a_OriginZ),
cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Size(a_Size)
{
int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3;
@ -690,9 +690,9 @@ int cStructGenWormNestCaves::cCaveSystem::GetRadius(cNoise & a_Noise, int a_Orig
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves:
cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
return cStructurePtr(new cCaveSystem(a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
return cStructurePtr(new cCaveSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
}

View File

@ -69,7 +69,7 @@ class cStructGenWormNestCaves :
typedef cGridStructGen super;
public:
cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) :
super(a_Seed, a_Grid, a_Grid, a_Size + a_MaxOffset, a_Size + a_MaxOffset, 100),
super(a_Seed, a_Grid, a_Grid, a_MaxOffset, a_MaxOffset, a_Size, a_Size, 100),
m_Noise(a_Seed),
m_Size(a_Size),
m_MaxOffset(a_MaxOffset),
@ -86,7 +86,7 @@ protected:
int m_Grid; // average spacing of the nests
// cGridStructGen override:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -672,7 +672,9 @@ cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_Cach
cCompoGenCache::~cCompoGenCache()
{
delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder;
m_CacheOrder = NULL;
}

View File

@ -26,6 +26,7 @@
#include "POCPieceGenerator.h"
#include "RainbowRoadsGen.h"
#include "Ravines.h"
#include "TestRailsGen.h"
#include "UnderwaterBaseGen.h"
#include "VillageGen.h"
@ -343,12 +344,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
else if (NoCaseCompare(*itr, "MineShafts") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxOffset", 256);
int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160);
int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600);
int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200);
int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
m_FinishGens.push_back(new cStructGenMineShafts(
Seed, GridSize, MaxSystemSize,
Seed, GridSize, MaxOffset, MaxSystemSize,
ChanceCorridor, ChanceCrossing, ChanceStaircase
));
}
@ -362,9 +364,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
}
else if (NoCaseCompare(*itr, "NetherForts") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth));
int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth));
}
else if (NoCaseCompare(*itr, "OreNests") == 0)
{
@ -380,10 +383,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
}
else if (NoCaseCompare(*itr, "RainbowRoads") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30);
int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260);
m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxDepth, MaxSize));
int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30);
int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260);
m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize));
}
else if (NoCaseCompare(*itr, "Ravines") == 0)
{
@ -397,25 +401,31 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
}
else if (NoCaseCompare(*itr, "TestRails") == 0)
{
m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50));
}
else if (NoCaseCompare(*itr, "Trees") == 0)
{
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
}
else if (NoCaseCompare(*itr, "UnderwaterBases") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7);
int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128);
m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen));
int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7);
int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128);
m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen));
}
else if (NoCaseCompare(*itr, "Villages") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "VillageMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2);
int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128);
int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen));
m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen));
}
else if (NoCaseCompare(*itr, "WaterLakes") == 0)
{
@ -428,7 +438,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
}
else if (NoCaseCompare(*itr, "WormNestCaves") == 0)
{
m_FinishGens.push_back(new cStructGenWormNestCaves(Seed));
int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64);
int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32);
m_FinishGens.push_back(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset));
}
else
{

View File

@ -21,8 +21,8 @@ class cEmptyStructure :
typedef cGridStructGen::cStructure super;
public:
cEmptyStructure(int a_OriginX, int a_OriginZ) :
super(a_OriginX, a_OriginZ)
cEmptyStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
{
}
@ -40,17 +40,20 @@ protected:
cGridStructGen::cGridStructGen(
int a_Seed,
int a_GridSizeX, int a_GridSizeZ,
int a_MaxOffsetX, int a_MaxOffsetZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize
) :
m_Seed(a_Seed),
m_Noise(a_Seed),
m_GridSizeX(a_GridSizeX),
m_GridSizeZ(a_GridSizeZ),
m_MaxOffsetX(a_MaxOffsetX),
m_MaxOffsetZ(a_MaxOffsetZ),
m_MaxStructureSizeX(a_MaxStructureSizeX),
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
m_MaxCacheSize(a_MaxCacheSize)
{
size_t NumStructuresPerQuery = (size_t)((m_MaxStructureSizeX / m_GridSizeX + 1) * (m_MaxStructureSizeZ / m_GridSizeZ + 1));
size_t NumStructuresPerQuery = (size_t)(((m_MaxStructureSizeX + m_MaxOffsetX) / m_GridSizeX + 1) * ((m_MaxStructureSizeZ + m_MaxOffsetZ) / m_GridSizeZ + 1));
if (NumStructuresPerQuery > m_MaxCacheSize)
{
m_MaxCacheSize = NumStructuresPerQuery * 4;
@ -68,10 +71,10 @@ cGridStructGen::cGridStructGen(
void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures)
{
// Calculate the min and max grid coords of the structures to be returned:
int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX;
int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ;
int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + cChunkDef::Width - 1;
int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1;
int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX - m_MaxOffsetX;
int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ - m_MaxOffsetZ;
int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + m_MaxOffsetX + cChunkDef::Width - 1;
int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + m_MaxOffsetZ + cChunkDef::Width - 1;
int MinGridX = MinBlockX / m_GridSizeX;
int MinGridZ = MinBlockZ / m_GridSizeZ;
int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
@ -85,8 +88,8 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
{
if (
((*itr)->m_OriginX >= MinX) && ((*itr)->m_OriginX < MaxX) &&
((*itr)->m_OriginZ >= MinZ) && ((*itr)->m_OriginZ < MaxZ)
((*itr)->m_GridX >= MinX) && ((*itr)->m_GridX < MaxX) &&
((*itr)->m_GridZ >= MinZ) && ((*itr)->m_GridZ < MaxZ)
)
{
// want
@ -103,14 +106,14 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
// Create those structures that haven't been in the cache:
for (int x = MinGridX; x < MaxGridX; x++)
{
int OriginX = x * m_GridSizeX;
int GridX = x * m_GridSizeX;
for (int z = MinGridZ; z < MaxGridZ; z++)
{
int OriginZ = z * m_GridSizeZ;
int GridZ = z * m_GridSizeZ;
bool Found = false;
for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr)
{
if (((*itr)->m_OriginX == OriginX) && ((*itr)->m_OriginZ == OriginZ))
if (((*itr)->m_GridX == GridX) && ((*itr)->m_GridZ == GridZ))
{
Found = true;
break;
@ -118,10 +121,12 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
} // for itr - a_Structures[]
if (!Found)
{
cStructurePtr Structure = CreateStructure(OriginX, OriginZ);
int OriginX = GridX + ((m_Noise.IntNoise2DInt(GridX + 3, GridZ + 5) / 7) % (m_MaxOffsetX * 2)) - m_MaxOffsetX;
int OriginZ = GridZ + ((m_Noise.IntNoise2DInt(GridX + 5, GridZ + 3) / 7) % (m_MaxOffsetZ * 2)) - m_MaxOffsetZ;
cStructurePtr Structure = CreateStructure(GridX, GridZ, OriginX, OriginZ);
if (Structure.get() == NULL)
{
Structure.reset(new cEmptyStructure(OriginX, OriginZ));
Structure.reset(new cEmptyStructure(GridX, GridZ, OriginX, OriginZ));
}
a_Structures.push_back(Structure);
}

View File

@ -10,6 +10,7 @@
#pragma once
#include "ComposableGenerator.h"
#include "../Noise.h"
@ -19,7 +20,12 @@
Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly
one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need
to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter
to determine how far away from the cell the structure can be at most.
to determine how far away from the cell the structure can be at most. Each structure has an offset from the
grid's center point, the offset is generated randomly from a range given to this class as a parameter.
Each structure thus contains the coords of its grid center (m_GridX, m_GridZ) and the actual origin from
which it's built (m_OriginX, m_OriginZ).
This class provides a cache for the structures generated for successive chunks and manages that cache. It
also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data.
@ -43,12 +49,17 @@ public:
class cStructure
{
public:
/** The origin (the coords of the gridpoint for which the structure is generated) */
/** The grid point for which the structure is generated. */
int m_GridX, m_GridZ;
/** The origin (the coords for which the structure is generated) */
int m_OriginX, m_OriginZ;
/** Creates a structure that has its originset at the specified coords. */
cStructure (int a_OriginX, int a_OriginZ) :
/** Creates a structure that has its origin set at the specified coords. */
cStructure (int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
m_GridX(a_GridX),
m_GridZ(a_GridZ),
m_OriginX(a_OriginX),
m_OriginZ(a_OriginZ)
{
@ -70,20 +81,30 @@ public:
cGridStructGen(
int a_Seed,
int a_GridSizeX, int a_GridSizeZ,
int a_MaxOffsetX, int a_MaxOffsetZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize
);
protected:
/** Seed for generating the semi-random grid. */
/** Seed for generating grid offsets and also available for descendants. */
int m_Seed;
/** The noise used for generating grid offsets. */
cNoise m_Noise;
/** The size of each grid's cell in the X axis */
int m_GridSizeX;
/** The size of each grid's cell in the Z axis */
int m_GridSizeZ;
/** The maximum offset of the structure's origin from the grid midpoint, in X coord. */
int m_MaxOffsetX;
/** The maximum offset of the structure's origin from the grid midpoint, in Z coord. */
int m_MaxOffsetZ;
/** Maximum theoretical size of the structure in the X axis.
This limits the structures considered for a single chunk, so the lesser the number, the better performance.
Structures large than this may get cropped. */
@ -115,7 +136,7 @@ protected:
// Functions for the descendants to override:
/** Create a new structure at the specified gridpoint */
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) = 0;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) = 0;
} ;

View File

@ -142,7 +142,9 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize)
cHeiGenCache::~cHeiGenCache()
{
delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder;
m_CacheOrder = NULL;
}

View File

@ -248,7 +248,8 @@ public:
/** Creates and generates the entire system */
cMineShaftSystem(
int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
);
@ -278,10 +279,11 @@ public:
// cStructGenMineShafts::cMineShaftSystem:
cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem(
int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
) :
super(a_OriginX, a_OriginZ),
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_GridSize(a_GridSize),
m_MaxRecursion(8), // TODO: settable
m_ProbLevelCorridor(a_ProbLevelCorridor),
@ -1280,10 +1282,10 @@ void cMineShaftStaircase::ProcessChunk(cChunkDesc & a_ChunkDesc)
// cStructGenMineShafts:
cStructGenMineShafts::cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize,
int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSystemSize, a_MaxSystemSize, 100),
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSystemSize, a_MaxSystemSize, 100),
m_Noise(a_Seed),
m_GridSize(a_GridSize),
m_MaxSystemSize(a_MaxSystemSize),
@ -1297,9 +1299,9 @@ cStructGenMineShafts::cStructGenMineShafts(
cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
return cStructurePtr(new cMineShaftSystem(a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
return cStructurePtr(new cMineShaftSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
}

View File

@ -23,7 +23,7 @@ class cStructGenMineShafts :
public:
cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize,
int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
);
@ -43,7 +43,7 @@ protected:
int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -26,8 +26,8 @@ public:
cPlacedPieces m_Pieces;
cNetherFort(cNetherFortGen & a_ParentGen, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
super(a_OriginX, a_OriginZ),
cNetherFort(cNetherFortGen & a_ParentGen, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_ParentGen(a_ParentGen),
m_GridSize(a_GridSize),
m_Seed(a_Seed)
@ -108,8 +108,8 @@ cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPr
cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200),
cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxDepth * 10, a_MaxDepth * 10, 200),
m_MaxDepth(a_MaxDepth)
{
/*
@ -124,8 +124,11 @@ cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
return cStructurePtr(new cNetherFort(*this, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
}

View File

@ -23,7 +23,7 @@ class cNetherFortGen :
typedef cGridStructGen super;
public:
cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth);
cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth);
protected:
friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp
@ -37,7 +37,7 @@ protected:
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

File diff suppressed because it is too large Load Diff

View File

@ -129,6 +129,176 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Farm:
// The data has been exported from the gallery Plains, area index 166, ID 554, created by Aloe_vera
{
// Size:
11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
10, 6, 12, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 3: 0\n" /* dirt */
"b: 60: 7\n" /* tilleddirt */
"c: 8: 0\n" /* water */
"d: 43: 0\n" /* doubleslab */
"e: 44: 0\n" /* step */
"f: 59: 7\n" /* crops */
"g: 83: 0\n" /* reedblock */
"h:113: 0\n" /* netherbrickfence */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "mmmmmmmmmmm"
/* 1 */ "maaaaaaaaam"
/* 2 */ "maaaaaaaaam"
/* 3 */ "maaaaaaaaam"
/* 4 */ "maaaaaaaaam"
/* 5 */ "maaaaaaaaam"
/* 6 */ "maaaaaaaaam"
/* 7 */ "maaaaaaaaam"
/* 8 */ "maaaaaaaaam"
/* 9 */ "maaaaaaaaam"
/* 10 */ "maaaaaaaaam"
/* 11 */ "maaaaaaaaam"
/* 12 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "mmmmmmmmmmm"
/* 1 */ "maaaaaaaaam"
/* 2 */ "mabbbbbbbam"
/* 3 */ "mabbbbbbbam"
/* 4 */ "mabbbbbbbam"
/* 5 */ "mabbbbbbbam"
/* 6 */ "mabcccccaam"
/* 7 */ "mabbbbbbbam"
/* 8 */ "mabbbbbbbam"
/* 9 */ "mabbbbbbbam"
/* 10 */ "mabbbbbbbam"
/* 11 */ "maaaaaaaaam"
/* 12 */ "mmmmmmmmmmm"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".deeeeeeed."
/* 2 */ ".efffffffe."
/* 3 */ ".efffffffe."
/* 4 */ ".efffffffe."
/* 5 */ ".efgggggfe."
/* 6 */ ".eg.....ge."
/* 7 */ ".efgggggfe."
/* 8 */ ".efffffffe."
/* 9 */ ".efffffffe."
/* 10 */ ".efffffffe."
/* 11 */ ".deeeeeeed."
/* 12 */ "..........."
// Level 3
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "...ggggg..."
/* 6 */ "..g.....g.."
/* 7 */ "...ggggg..."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 4
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "...ggggg..."
/* 6 */ "..g.....g.."
/* 7 */ "...ggggg..."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 5
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "..........."
/* 6 */ "..........."
/* 7 */ "..........."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 6
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ ".h.......h."
/* 1 */ "hhh.....hhh"
/* 2 */ ".h.......h."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "..........."
/* 6 */ "..........."
/* 7 */ "..........."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ ".h.......h."
/* 11 */ "hhh.....hhh"
/* 12 */ ".h.......h.",
// Connectors:
"-1: 10, 2, 6: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
true,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // Farm
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Forge:
// The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera
@ -2025,12 +2195,12 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
// Level 1
/* z\x* 0123456 */
/* 0 */ "bbbbbbb"
/* 1 */ "bbbbbbb"
/* 2 */ "bbbbbbb"
/* 3 */ "bbbabbb"
/* 4 */ "bbbbbbb"
/* 5 */ "bbbbbbb"
/* 0 */ "bmmmmmm"
/* 1 */ "bmmmmmm"
/* 2 */ "bmmmmmm"
/* 3 */ "bmmmmmm"
/* 4 */ "bmmmmmm"
/* 5 */ "bmmmmmm"
/* 6 */ "bbbbbbb"
// Level 2
@ -3005,159 +3175,157 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] =
"a: 1: 0\n" /* stone */
"b: 4: 0\n" /* cobblestone */
"c: 8: 0\n" /* water */
"d: 3: 0\n" /* dirt */
"e: 2: 0\n" /* grass */
"f: 13: 0\n" /* gravel */
"g: 67: 1\n" /* stairs */
"h: 67: 2\n" /* stairs */
"i: 67: 0\n" /* stairs */
"j: 67: 3\n" /* stairs */
"k: 85: 0\n" /* fence */
"l: 44: 8\n" /* step */
"m: 19: 0\n" /* sponge */
"n: 44: 0\n" /* step */
"o: 43: 0\n" /* doubleslab */,
"d: 13: 0\n" /* gravel */
"e: 67: 1\n" /* stairs */
"f: 67: 2\n" /* stairs */
"g: 67: 0\n" /* stairs */
"h: 67: 3\n" /* stairs */
"i: 85: 0\n" /* fence */
"j: 44: 8\n" /* step */
"k: 44: 0\n" /* step */
"l: 43: 0\n" /* doubleslab */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaaaaaa"
/* 1 */ "aaaaaaa"
/* 2 */ "aaaaaaa"
/* 3 */ "aaaaaaa"
/* 4 */ "aaaaaaa"
/* 5 */ "aaaaaaa"
/* 6 */ "aaaaaaa"
/* 0 */ "mmmmmmm"
/* 1 */ "maaaaam"
/* 2 */ "maaaaam"
/* 3 */ "maaaaam"
/* 4 */ "maaaaam"
/* 5 */ "maaaaam"
/* 6 */ "mmmmmmm"
// Level 1
/* z\x* 0123456 */
/* 0 */ "aaaaaaa"
/* 1 */ "abbbbba"
/* 2 */ "abcc.ba"
/* 3 */ "abcccba"
/* 4 */ "abcccba"
/* 5 */ "abbbbba"
/* 6 */ "aaaaaaa"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcc.bm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 2
/* z\x* 0123456 */
/* 0 */ "aaaaaaa"
/* 1 */ "abbbbba"
/* 2 */ "abcccba"
/* 3 */ "abcccba"
/* 4 */ "abcccba"
/* 5 */ "abbbbba"
/* 6 */ "aaaaaaa"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcccbm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 3
/* z\x* 0123456 */
/* 0 */ "aaaaaaa"
/* 1 */ "abbbbba"
/* 2 */ "abcccba"
/* 3 */ "abcccba"
/* 4 */ "abcccba"
/* 5 */ "abbbbba"
/* 6 */ "aaaaaaa"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcccbm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 4
/* z\x* 0123456 */
/* 0 */ "aaaaaaa"
/* 1 */ "abbbbba"
/* 2 */ "abcccba"
/* 3 */ "abcccba"
/* 4 */ "abcccba"
/* 5 */ "abbbbba"
/* 6 */ "aaaaaaa"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcccbm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 5
/* z\x* 0123456 */
/* 0 */ "ddddddd"
/* 1 */ "dbbbbbd"
/* 2 */ "dbcccbd"
/* 3 */ "dbcccbd"
/* 4 */ "dbcccbd"
/* 5 */ "dbbbbbd"
/* 6 */ "ddddddd"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcccbm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 6
/* z\x* 0123456 */
/* 0 */ "ddddddd"
/* 1 */ "dbbbbbd"
/* 2 */ "dbcccbd"
/* 3 */ "dbcccbd"
/* 4 */ "dbcccbd"
/* 5 */ "dbbbbbd"
/* 6 */ "ddddddd"
/* 0 */ "mmmmmmm"
/* 1 */ "mbbbbbm"
/* 2 */ "mbcccbm"
/* 3 */ "mbcccbm"
/* 4 */ "mbcccbm"
/* 5 */ "mbbbbbm"
/* 6 */ "mmmmmmm"
// Level 7
/* z\x* 0123456 */
/* 0 */ "ddddddd"
/* 1 */ "dbbbbbd"
/* 2 */ "dbcccbd"
/* 3 */ "dbcccbd"
/* 4 */ "dbcccbd"
/* 5 */ "dbbbbbd"
/* 6 */ "ddddddd"
/* 0 */ "mmbbbmm"
/* 1 */ "mbbbbbm"
/* 2 */ "bbcccbb"
/* 3 */ "bbcccbb"
/* 4 */ "bbcccbb"
/* 5 */ "mbbbbbm"
/* 6 */ "mmbbbmm"
// Level 8
/* z\x* 0123456 */
/* 0 */ "eefffee"
/* 1 */ "ebbbbbe"
/* 2 */ "fbcccbf"
/* 3 */ "fbcccbf"
/* 4 */ "fbcccbf"
/* 5 */ "ebbbbbe"
/* 6 */ "eefffee"
/* 0 */ "mmdddmm"
/* 1 */ "mbbbbbm"
/* 2 */ "dbcccbd"
/* 3 */ "dbcccbd"
/* 4 */ "dbcccbd"
/* 5 */ "mbbbbbm"
/* 6 */ "mmdddmm"
// Level 9
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".bghib."
/* 2 */ ".j...j."
/* 3 */ ".i...g."
/* 4 */ ".h...h."
/* 5 */ ".bgjib."
/* 6 */ "......."
/* 0 */ "mm...mm"
/* 1 */ "mbefgbm"
/* 2 */ ".h...h."
/* 3 */ ".g...e."
/* 4 */ ".f...f."
/* 5 */ "mbehgbm"
/* 6 */ "mm...mm"
// Level 10
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".k...k."
/* 0 */ "mm...mm"
/* 1 */ "mi...im"
/* 2 */ "......."
/* 3 */ "......."
/* 4 */ "......."
/* 5 */ ".k...k."
/* 6 */ "......."
/* 5 */ "mi...im"
/* 6 */ "mm...mm"
// Level 11
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".k...k."
/* 0 */ "mm...mm"
/* 1 */ "mi...im"
/* 2 */ "......."
/* 3 */ "......."
/* 4 */ "......."
/* 5 */ ".k...k."
/* 6 */ "......."
/* 5 */ "mi...im"
/* 6 */ "mm...mm"
// Level 12
/* z\x* 0123456 */
/* 0 */ ".lnnnl."
/* 1 */ "loooool"
/* 2 */ "nooooon"
/* 3 */ "nooooon"
/* 4 */ "nooooon"
/* 5 */ "loooool"
/* 6 */ ".lnnnl."
/* 0 */ "mjkkkjm"
/* 1 */ "jlllllj"
/* 2 */ "klllllk"
/* 3 */ "klllllk"
/* 4 */ "klllllk"
/* 5 */ "jlllllj"
/* 6 */ "mjkkkjm"
// Level 13
/* z\x* 0123456 */
/* 0 */ "n.....n"
/* 0 */ "k.....k"
/* 1 */ "......."
/* 2 */ "..nnn.."
/* 3 */ "..non.."
/* 4 */ "..nnn.."
/* 2 */ "..kkk.."
/* 3 */ "..klk.."
/* 4 */ "..kkk.."
/* 5 */ "......."
/* 6 */ "n.....n",
/* 6 */ "k.....k",
// Connectors:
"2: 0, 9, 3: 4\n" /* Type 2, direction X- */

View File

@ -362,29 +362,29 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "aaaaaaaaaaaaaaa"
/* 0 */ "aaaaaaabaaaaaaa"
/* 1 */ "aaaaaaaaaaaaaaa"
/* 2 */ "aaaaaaaaaaaaaaa"
/* 3 */ "aaaaaaaaaaaaaaa"
/* 4 */ "aaaaaaaaaaaaaaa"
/* 5 */ "aaaaaaaaaaaaaaa"
/* 6 */ "aaaaaaaaaaaaaaa"
/* 7 */ "aaaaaaaaaaaaaaa"
/* 8 */ "aaaaaaaaaaaaaaa"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "aaaaaaabaaaaaaa"
/* 1 */ "aaaaaaabaaaaaaa"
/* 2 */ "aaaaaaabaaaaaaa"
/* 3 */ "aaaaaaabaaaaaaa"
/* 4 */ "aaaaaaabaaaaaaa"
/* 5 */ "aaaaaaabaaaaaaa"
/* 6 */ "aaaaaaabaaaaaaa"
/* 7 */ "aaaaaaabaaaaaaa"
/* 8 */ "aaaaaaabaaaaaaa"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "aaaaaaamaaaaaaa"
/* 1 */ "aaaaaaamaaaaaaa"
/* 2 */ "aaaaaaamaaaaaaa"
/* 3 */ "aaaaaaamaaaaaaa"
/* 4 */ "aaaaaaamaaaaaaa"
/* 5 */ "aaaaaaamaaaaaaa"
/* 6 */ "aaaaaaamaaaaaaa"
/* 7 */ "aaaaaaamaaaaaaa"
/* 8 */ "aaaaaaamaaaaaaa"
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
@ -509,12 +509,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
"g: 64: 6\n" /* wooddoorblock */
"g: 64: 2\n" /* wooddoorblock */
"h: 10: 0\n" /* lava */
"i: 54: 2\n" /* chest */
"j: 61: 2\n" /* furnace */
"k:102: 0\n" /* glasspane */
"l: 64:12\n" /* wooddoorblock */
"l: 64: 8\n" /* wooddoorblock */
"m: 19: 0\n" /* sponge */
"n:139: 0\n" /* cobblestonewall */
"o:101: 0\n" /* ironbars */
@ -2544,7 +2544,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
true,
// DefaultWeight:
100,
20,
// DepthWeight:
"",
@ -2746,8 +2746,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
"g: 64: 7\n" /* wooddoorblock */
"h: 64:12\n" /* wooddoorblock */
"g: 64: 3\n" /* wooddoorblock */
"h: 64: 8\n" /* wooddoorblock */
"i:102: 0\n" /* glasspane */
"j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */
@ -3000,9 +3000,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
"g: 64: 7\n" /* wooddoorblock */
"g: 64: 3\n" /* wooddoorblock */
"h:102: 0\n" /* glasspane */
"i: 64:12\n" /* wooddoorblock */
"i: 64: 8\n" /* wooddoorblock */
"j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */
"l: 50: 3\n" /* torch */
@ -3141,31 +3141,32 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"k: 85: 0\n" /* fence */
"l: 53: 0\n" /* woodstairs */
"m: 19: 0\n" /* sponge */
"n: 64: 6\n" /* wooddoorblock */
"n: 64: 2\n" /* wooddoorblock */
"o: 64: 4\n" /* wooddoorblock */
"p:102: 0\n" /* glasspane */
"q: 72: 0\n" /* woodplate */
"r: 64:12\n" /* wooddoorblock */
"s: 53: 5\n" /* woodstairs */
"t: 53: 4\n" /* woodstairs */
"u: 50: 1\n" /* torch */
"v: 50: 2\n" /* torch */,
"r: 64: 8\n" /* wooddoorblock */
"s: 64:12\n" /* wooddoorblock */
"t: 53: 5\n" /* woodstairs */
"u: 53: 4\n" /* woodstairs */
"v: 50: 1\n" /* torch */
"w: 50: 2\n" /* torch */,
// Block data:
// Level 0
/* z\x* */
/* * 0123456789 */
/* 0 */ ".........."
/* 1 */ ".aaaaa...."
/* 2 */ ".aaaaa...."
/* 3 */ ".aaaaabbbb"
/* 0 */ "mmmmmmmmmm"
/* 1 */ "maaaaammmm"
/* 2 */ "maaaaammmm"
/* 3 */ "maaaaabbbb"
/* 4 */ "aaaaaabbbb"
/* 5 */ "aaaaaabbbb"
/* 6 */ "aaaaaabbbb"
/* 7 */ ".aaaaabbbb"
/* 8 */ ".aaaaabbbb"
/* 9 */ ".aaaaa...."
/* 10 */ ".........."
/* 7 */ "maaaaabbbb"
/* 8 */ "maaaaabbbb"
/* 9 */ "maaaaammmm"
/* 10 */ "mmmmmmmmmm"
// Level 1
/* z\x* */
@ -3205,7 +3206,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 2 */ ".p.q.pmmmm"
/* 3 */ ".p...p...."
/* 4 */ ".c...c...."
/* 5 */ ".r...r...."
/* 5 */ ".r...s...."
/* 6 */ ".c...c...."
/* 7 */ ".p...p...."
/* 8 */ ".p...p...."
@ -3215,47 +3216,47 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 4
/* z\x* */
/* * 0123456789 */
/* 0 */ "ls...tjmmm"
/* 0 */ "lt...ujmmm"
/* 1 */ "licccijmmm"
/* 2 */ "lc...cjmmm"
/* 3 */ "lc...cj..."
/* 4 */ "lcu.vcj..."
/* 4 */ "lcv.wcj..."
/* 5 */ "lc...cj..."
/* 6 */ "lcu.vcj..."
/* 6 */ "lcv.wcj..."
/* 7 */ "lc...cj..."
/* 8 */ "lc...cj..."
/* 9 */ "licccijmmm"
/* 10 */ "ls...tjmmm"
/* 10 */ "lt...ujmmm"
// Level 5
/* z\x* */
/* * 0123456789 */
/* 0 */ "mls.tjmmmm"
/* 1 */ "mlcccjmmmm"
/* 2 */ "mlc.cjmmmm"
/* 3 */ "mlc.cjm..."
/* 4 */ "mlc.cjm..."
/* 5 */ "mlc.cjm..."
/* 6 */ "mlc.cjm..."
/* 7 */ "mlc.cjm..."
/* 8 */ "mlc.cjm..."
/* 9 */ "mlcccjmmmm"
/* 10 */ "mls.tjmmmm"
/* 0 */ ".lt.uj.mmm"
/* 1 */ ".lcccj.mmm"
/* 2 */ ".lc.cj.mmm"
/* 3 */ ".lc.cj...."
/* 4 */ ".lc.cj...."
/* 5 */ ".lc.cj...."
/* 6 */ ".lc.cj...."
/* 7 */ ".lc.cj...."
/* 8 */ ".lc.cj...."
/* 9 */ ".lcccj.mmm"
/* 10 */ ".lt.uj.mmm"
// Level 6
/* z\x* */
/* * 0123456789 */
/* 0 */ "mmlcjmmmmm"
/* 1 */ "mmlcjmmmmm"
/* 2 */ "mmlcjmmmmm"
/* 3 */ "mmlcjmm..."
/* 4 */ "mmlcjmm..."
/* 5 */ "mmlcjmm..."
/* 6 */ "mmlcjmm..."
/* 7 */ "mmlcjmm..."
/* 8 */ "mmlcjmm..."
/* 9 */ "mmlcjmmmmm"
/* 10 */ "mmlcjmmmmm",
/* 0 */ "..lcj..mmm"
/* 1 */ "..lcj..mmm"
/* 2 */ "..lcj..mmm"
/* 3 */ "..lcj....."
/* 4 */ "..lcj....."
/* 5 */ "..lcj....."
/* 6 */ "..lcj....."
/* 7 */ "..lcj....."
/* 8 */ "..lcj....."
/* 9 */ "..lcj..mmm"
/* 10 */ "..lcj..mmm",
// Connectors:
"-1: 0, 1, 5: 4\n" /* Type -1, direction X- */,
@ -3626,7 +3627,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 0
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "aaabbbbaaaa"
/* 0 */ "aaaabbbaaaa"
/* 1 */ "abbbbbbbbba"
/* 2 */ "abbbbbbbbba"
/* 3 */ "abbbbbbbbba"
@ -4509,10 +4510,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".aaaaaaaaa."
/* 5 */ ".aaaaaaaaa."
/* 6 */ ".....aaaaa."
/* 7 */ ".....aaaaa."
/* 8 */ ".....aaaaa."
/* 9 */ ".....aaaaa."
/* 10 */ "..........."
/* 7 */ "mmmm.aaaaa."
/* 8 */ "mmmm.aaaaa."
/* 9 */ "mmmm.aaaaa."
/* 10 */ "mmmm......."
// Level 2
/* z\x* 1 */
@ -4524,10 +4525,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f.......f."
/* 5 */ ".efffe...f."
/* 6 */ ".....f...f."
/* 7 */ ".....f...f."
/* 8 */ ".....f...f."
/* 9 */ ".....efffe."
/* 10 */ "..........."
/* 7 */ "mmmm.f...f."
/* 8 */ "mmmm.f...f."
/* 9 */ "mmmm.efffe."
/* 10 */ "mmmm......."
// Level 3
/* z\x* 1 */
@ -4539,10 +4540,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".h.......h."
/* 5 */ ".ehhhe...f."
/* 6 */ ".....h...h."
/* 7 */ ".....h...h."
/* 8 */ ".....h...h."
/* 9 */ ".....ehhhe."
/* 10 */ "..........."
/* 7 */ "mmmm.h...h."
/* 8 */ "mmmm.h...h."
/* 9 */ "mmmm.ehhhe."
/* 10 */ "mmmm......."
// Level 4
/* z\x* 1 */
@ -4554,10 +4555,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f...o...fl"
/* 5 */ "pfffffq.rfl"
/* 6 */ "sssssf...fl"
/* 7 */ "....tf...fl"
/* 8 */ "....tf...fl"
/* 9 */ "....tfffffl"
/* 10 */ "....tu...vl"
/* 7 */ "mmmmtf...fl"
/* 8 */ "mmmmtf...fl"
/* 9 */ "mmmmtfffffl"
/* 10 */ "mmmmtu...vl"
// Level 5
/* z\x* 1 */
@ -4569,10 +4570,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "pffffff.fl."
/* 5 */ "ssssssf.fl."
/* 6 */ ".....tf.fl."
/* 7 */ ".....tf.fl."
/* 8 */ ".....tf.fl."
/* 9 */ ".....tfffl."
/* 10 */ ".....tu.vl."
/* 7 */ "mmmm.tf.fl."
/* 8 */ "mmmm.tf.fl."
/* 9 */ "mmmm.tfffl."
/* 10 */ "mmmm.tu.vl."
// Level 6
/* z\x* 1 */
@ -4584,10 +4585,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "sssssstfl.."
/* 5 */ "......tfl.."
/* 6 */ "......tfl.."
/* 7 */ "......tfl.."
/* 8 */ "......tfl.."
/* 9 */ "......tfl.."
/* 10 */ "......tfl..",
/* 7 */ "mmmm..tfl.."
/* 8 */ "mmmm..tfl.."
/* 9 */ "mmmm..tfl.."
/* 10 */ "mmmm..tfl..",
// Connectors:
"-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
@ -4837,9 +4838,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 1
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".aaaaa..."
/* 5 */ ".aaaaab.."
@ -4847,15 +4848,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".aaaaad.."
/* 8 */ ".aaaaa..."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 2
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..."
@ -4863,15 +4864,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..."
/* 8 */ ".efffe..."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 3
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".ejjje..."
/* 5 */ ".j...f..."
@ -4879,15 +4880,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...f..."
/* 8 */ ".ejjje..."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 4
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f..nf..."
@ -4895,15 +4896,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f..nf..k"
/* 8 */ ".efffe..o"
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 5
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".epppe..."
/* 5 */ ".q...q..."
@ -4911,15 +4912,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k"
/* 8 */ ".epppe..o"
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 6
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..."
@ -4927,15 +4928,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ ".efffe..o"
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 7
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".ejjje..."
/* 5 */ ".j...j..."
@ -4943,15 +4944,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...j..o"
/* 8 */ ".ejjje..."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 8
/* z\x* 012345678 */
/* 0 */ "........o"
/* 1 */ "........o"
/* 2 */ "........o"
/* 0 */ "mmmmmmm.o"
/* 1 */ "mmmmmmm.o"
/* 2 */ "mmmmmmm.o"
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..k"
@ -4959,15 +4960,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ ".efffe..."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 9
/* z\x* 012345678 */
/* 0 */ "........k"
/* 1 */ "........k"
/* 2 */ "........o"
/* 0 */ "mmmmmmm.k"
/* 1 */ "mmmmmmm.k"
/* 2 */ "mmmmmmm.o"
/* 3 */ "........o"
/* 4 */ ".epppe..o"
/* 5 */ ".q...q..k"
@ -4975,15 +4976,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k"
/* 8 */ ".epppe..k"
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 10
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........k"
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.k"
/* 3 */ "rrrrrrr.k"
/* 4 */ "sfffffs.o"
/* 5 */ ".f...f..o"
@ -4991,15 +4992,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ "tffffft.o"
/* 9 */ "uuuuuuu.k"
/* 10 */ "........k"
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.k"
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 11
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "rrrrrrr.k"
/* 5 */ "sfffffs.k"
@ -5007,15 +5008,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "tffffft.k"
/* 8 */ "uuuuuuu.o"
/* 9 */ "........o"
/* 10 */ "........o"
/* 11 */ "........k"
/* 12 */ "........k"
/* 10 */ "mmmmmmm.o"
/* 11 */ "mmmmmmm.k"
/* 12 */ "mmmmmmm.k"
// Level 12
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........."
/* 5 */ "rrrrrrr.o"
@ -5023,15 +5024,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "uuuuuuu.k"
/* 8 */ "........."
/* 9 */ "........."
/* 10 */ "........o"
/* 11 */ "........o"
/* 12 */ "........o"
/* 10 */ "mmmmmmm.o"
/* 11 */ "mmmmmmm.o"
/* 12 */ "mmmmmmm.o"
// Level 13
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........."
/* 5 */ "........o"
@ -5039,15 +5040,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 14
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........o"
@ -5055,15 +5056,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 15
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........k"
@ -5071,15 +5072,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ "........."
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm.."
// Level 16
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
/* 0 */ "mmmmmmm.."
/* 1 */ "mmmmmmm.."
/* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........k"
@ -5087,9 +5088,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
/* 10 */ "........."
/* 11 */ "........."
/* 12 */ ".........",
/* 10 */ "mmmmmmm.."
/* 11 */ "mmmmmmm.."
/* 12 */ "mmmmmmm..",
// Connectors:
"-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */,
@ -5472,13 +5473,15 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
"l: 66: 7\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 50: 2\n" /* torch */
"o: 2: 0\n" /* grass */
"p: 53: 2\n" /* woodstairs */
"q: 77: 1\n" /* stonebutton */
"r: 27: 0\n" /* poweredrail */
"s: 53: 7\n" /* woodstairs */
"t: 53: 6\n" /* woodstairs */
"u: 53: 3\n" /* woodstairs */,
"o: 4: 0\n" /* cobblestone */
"p: 2: 0\n" /* grass */
"q: 13: 0\n" /* gravel */
"r: 53: 2\n" /* woodstairs */
"s: 77: 1\n" /* stonebutton */
"t: 27: 0\n" /* poweredrail */
"u: 53: 7\n" /* woodstairs */
"v: 53: 6\n" /* woodstairs */
"w: 53: 3\n" /* woodstairs */,
// Block data:
// Level 0
@ -5783,28 +5786,28 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 30
/* z\x* 0123456 */
/* 0 */ "mmmmmmm"
/* 0 */ "mmooomm"
/* 1 */ "mmmammm"
/* 2 */ "mm...mm"
/* 3 */ "ma..aam"
/* 4 */ "mmfgamm"
/* 2 */ "om...mo"
/* 3 */ "oa..aao"
/* 4 */ "omfgamo"
/* 5 */ "mmmammm"
/* 6 */ "mmmmmmm"
/* 6 */ "mmooomm"
// Level 31
/* z\x* 0123456 */
/* 0 */ "ooomooo"
/* 1 */ "oaaaaao"
/* 2 */ "oa.aaao"
/* 3 */ "oa..iao"
/* 4 */ "oa..jao"
/* 5 */ "oaaaaao"
/* 6 */ "ooooooo"
/* 0 */ "ppqqqpp"
/* 1 */ "paaaaap"
/* 2 */ "qa.aaaq"
/* 3 */ "qa..iaq"
/* 4 */ "qa..jaq"
/* 5 */ "paaaaap"
/* 6 */ "ppqqqpp"
// Level 32
/* z\x* 0123456 */
/* 0 */ "...p..."
/* 1 */ ".aqrba."
/* 0 */ "...r..."
/* 1 */ ".astba."
/* 2 */ "...fl.."
/* 3 */ "......."
/* 4 */ "......."
@ -5833,31 +5836,31 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 35
/* z\x* 0123456 */
/* 0 */ "ppppppp"
/* 1 */ "saaaaas"
/* 0 */ "rrrrrrr"
/* 1 */ "uaaaaau"
/* 2 */ ".a...a."
/* 3 */ ".a...a."
/* 4 */ ".a...a."
/* 5 */ "taaaaat"
/* 6 */ "uuuuuuu"
/* 5 */ "vaaaaav"
/* 6 */ "wwwwwww"
// Level 36
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "ppppppp"
/* 2 */ "saaaaas"
/* 1 */ "rrrrrrr"
/* 2 */ "uaaaaau"
/* 3 */ ".aaaaa."
/* 4 */ "taaaaat"
/* 5 */ "uuuuuuu"
/* 4 */ "vaaaaav"
/* 5 */ "wwwwwww"
/* 6 */ "......."
// Level 37
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "......."
/* 2 */ "ppppppp"
/* 2 */ "rrrrrrr"
/* 3 */ "aaaaaaa"
/* 4 */ "uuuuuuu"
/* 4 */ "wwwwwww"
/* 5 */ "......."
/* 6 */ ".......",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,484 @@
// TestRailsPrefabs.cpp
// Defines the prefabs in the group TestRails
// NOTE: This file has been generated automatically by GalExport!
// Any manual changes will be overwritten by the next automatic export!
#include "Globals.h"
#include "TestRailsPrefabs.h"
const cPrefab::sDef g_TestRailsPrefabs[] =
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ActivatorRail:
// The data has been exported from the gallery Plains, area index 251, ID 746, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c:157: 0\n" /* activatorrail */
"d:157: 2\n" /* activatorrail */
"e:157: 3\n" /* activatorrail */
"f:157: 5\n" /* activatorrail */
"g: 50: 5\n" /* torch */
"h:157: 4\n" /* activatorrail */
"i:157: 1\n" /* activatorrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // ActivatorRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DetectorRail:
// The data has been exported from the gallery Plains, area index 250, ID 745, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 28: 0\n" /* detectorrail */
"d: 28: 2\n" /* detectorrail */
"e: 28: 3\n" /* detectorrail */
"f: 28: 5\n" /* detectorrail */
"g: 50: 5\n" /* torch */
"h: 28: 4\n" /* detectorrail */
"i: 28: 1\n" /* detectorrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // DetectorRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PowerRail:
// The data has been exported from the gallery Plains, area index 248, ID 743, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 27: 0\n" /* poweredrail */
"d: 27: 2\n" /* poweredrail */
"e: 27: 3\n" /* poweredrail */
"f: 27: 5\n" /* poweredrail */
"g: 50: 5\n" /* torch */
"h: 27: 4\n" /* poweredrail */
"i: 27: 1\n" /* poweredrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // PowerRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RegularRail:
// The data has been exported from the gallery Plains, area index 247, ID 742, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 66: 6\n" /* tracks */
"d: 66: 2\n" /* tracks */
"e: 66: 3\n" /* tracks */
"f: 66: 7\n" /* tracks */
"g: 66: 5\n" /* tracks */
"h: 50: 5\n" /* torch */
"i: 66: 4\n" /* tracks */
"j: 66: 9\n" /* tracks */
"k: 66: 8\n" /* tracks */
"l: 66: 1\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 66: 0\n" /* tracks */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbef."
/* 2 */ ".gh..g."
/* 3 */ ".b.h.b."
/* 4 */ ".i...i."
/* 5 */ ".jdbek."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...l..."
/* 2 */ "......."
/* 3 */ ".n...n."
/* 4 */ "......."
/* 5 */ "...l..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // RegularRail
}; // g_TestRailsPrefabs
const cPrefab::sDef g_TestRailsStartingPrefabs[] =
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CentralPiece:
// The data has been exported from the gallery Plains, area index 249, ID 744, created by Aloe_vera
{
// Size:
6, 3, 6, // SizeX = 6, SizeY = 3, SizeZ = 6
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
5, 2, 5, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 66: 6\n" /* tracks */
"d: 66: 2\n" /* tracks */
"e: 66: 3\n" /* tracks */
"f: 66: 7\n" /* tracks */
"g: 66: 5\n" /* tracks */
"h: 50: 5\n" /* torch */
"i: 66: 4\n" /* tracks */
"j: 66: 9\n" /* tracks */
"k: 66: 8\n" /* tracks */
"l: 66: 1\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 66: 0\n" /* tracks */,
// Block data:
// Level 0
/* z\x* 012345 */
/* 0 */ "aaab.."
/* 1 */ "abbbbb"
/* 2 */ "abbb.b"
/* 3 */ "bbbb.b"
/* 4 */ ".b...b"
/* 5 */ ".bbbbb"
// Level 1
/* z\x* 012345 */
/* 0 */ "......"
/* 1 */ ".cdbef"
/* 2 */ ".gh..g"
/* 3 */ ".b.h.b"
/* 4 */ ".i...i"
/* 5 */ ".jdbek"
// Level 2
/* z\x* 012345 */
/* 0 */ "......"
/* 1 */ "...l.."
/* 2 */ "......"
/* 3 */ ".n...n"
/* 4 */ "......"
/* 5 */ "...l..",
// Connectors:
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
true,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // CentralPiece
};
// The prefab counts:
const size_t g_TestRailsPrefabsCount = ARRAYCOUNT(g_TestRailsPrefabs);
const size_t g_TestRailsStartingPrefabsCount = ARRAYCOUNT(g_TestRailsStartingPrefabs);

View File

@ -0,0 +1,15 @@
// TestRailsPrefabs.h
// Declares the prefabs in the group TestRails
#include "../Prefab.h"
extern const cPrefab::sDef g_TestRailsPrefabs[];
extern const cPrefab::sDef g_TestRailsStartingPrefabs[];
extern const size_t g_TestRailsPrefabsCount;
extern const size_t g_TestRailsStartingPrefabsCount;

View File

@ -366,7 +366,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] =
true,
// DefaultWeight:
100,
200,
// DepthWeight:
"",

View File

@ -29,11 +29,12 @@ class cRainbowRoadsGen::cRainbowRoads :
public:
cRainbowRoads(
int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ,
int a_MaxDepth,
int a_MaxSize
) :
super(a_OriginX, a_OriginZ),
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
m_Noise(a_Seed),
m_MaxSize(a_MaxSize),
@ -92,8 +93,8 @@ protected:
cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100),
cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 9000),
m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize)
@ -104,10 +105,10 @@ cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, i
cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
// Create a base based on the chosen prefabs:
return cStructurePtr(new cRainbowRoads(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
return cStructurePtr(new cRainbowRoads(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
}

View File

@ -22,7 +22,7 @@ class cRainbowRoadsGen :
typedef cGridStructGen super;
public:
cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize);
cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
protected:
class cRainbowRoads; // fwd: RainbowRoadsGen.cpp
@ -39,7 +39,7 @@ protected:
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -61,7 +61,7 @@ class cStructGenRavines::cRavine :
public:
cRavine(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise);
cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise);
#ifdef _DEBUG
/// Exports itself as a SVG line definition
@ -81,7 +81,7 @@ protected:
// cStructGenRavines:
cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
super(a_Seed, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
super(a_Seed, a_Size, a_Size, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
m_Noise(a_Seed),
m_Size(a_Size)
{
@ -91,9 +91,9 @@ cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
return cStructurePtr(new cRavine(a_OriginX, a_OriginZ, m_Size, m_Noise));
return cStructurePtr(new cRavine(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_Size, m_Noise));
}
@ -104,8 +104,8 @@ cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX,
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenRavines::cRavine
cStructGenRavines::cRavine::cRavine(int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
super(a_OriginX, a_OriginZ)
cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
{
// Calculate the ravine shape-defining points:
GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise);

View File

@ -32,7 +32,7 @@ protected:
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -0,0 +1,116 @@
// TestRailsGen.cpp
// Implements the cTestRailsGen class representing the testing rails generator
#include "Globals.h"
#include "TestRailsGen.h"
#include "Prefabs/TestRailsPrefabs.h"
#include "PieceGenerator.h"
static cPrefabPiecePool g_TestRails(g_TestRailsPrefabs, g_TestRailsPrefabsCount, g_TestRailsStartingPrefabs, g_TestRailsStartingPrefabsCount);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cTestRailsGen::cTestRails:
class cTestRailsGen::cTestRails :
public cGridStructGen::cStructure
{
typedef cGridStructGen::cStructure super;
public:
cTestRails(
int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ,
int a_MaxDepth,
int a_MaxSize
) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
m_Noise(a_Seed),
m_MaxSize(a_MaxSize),
m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
{
// Generate the pieces for this test:
cBFSPieceGenerator pg(g_TestRails, a_Seed);
pg.PlacePieces(a_OriginX, 150, a_OriginZ, a_MaxDepth, m_Pieces);
if (m_Pieces.empty())
{
return;
}
}
~cTestRails()
{
cPieceGenerator::FreePieces(m_Pieces);
}
protected:
/** Seed for the random functions */
int m_Seed;
/** The noise used as a pseudo-random generator */
cNoise m_Noise;
/** Maximum size, in X/Z blocks, of the structure (radius from the origin) */
int m_MaxSize;
/** Borders of the structure - no item may reach out of this cuboid. */
cCuboid m_Borders;
/** The rails pieces, placed by the generator. */
cPlacedPieces m_Pieces;
// cGridStructGen::cStructure overrides:
virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
{
for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
{
cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
Prefab.Draw(a_Chunk, *itr);
} // for itr - m_PlacedPieces[]
}
} ;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cTestRailsGen:
cTestRailsGen::cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize)
{
}
cGridStructGen::cStructurePtr cTestRailsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
// Create a base based on the chosen prefabs:
return cStructurePtr(new cTestRails(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
}

View File

@ -0,0 +1,47 @@
// TestRailsGen.h
// Declares the cTestRailsGen class representing the testing rails generator
#pragma once
#include "GridStructGen.h"
#include "PrefabPiecePool.h"
class cTestRailsGen :
public cGridStructGen
{
typedef cGridStructGen super;
public:
cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
protected:
class cTestRails; // fwd: TestRailsGen.cpp
/** The noise used for generating random numbers */
cNoise m_Noise;
/** Maximum depth of the generator tree*/
int m_MaxDepth;
/** Maximum size, in X/Z blocks, of the base (radius from the origin) */
int m_MaxSize;
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -29,11 +29,12 @@ class cUnderwaterBaseGen::cUnderwaterBase :
public:
cUnderwaterBase(
int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ,
int a_MaxDepth,
int a_MaxSize
) :
super(a_OriginX, a_OriginZ),
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
m_Noise(a_Seed),
m_MaxSize(a_MaxSize),
@ -92,8 +93,8 @@ protected:
cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100),
cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize),
@ -105,7 +106,7 @@ cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDept
cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
// Generate the biomes for the chunk surrounding the origin:
int ChunkX, ChunkZ;
@ -134,7 +135,7 @@ cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_OriginX,
} // for i - Biomes[]
// Create a base based on the chosen prefabs:
return cStructurePtr(new cUnderwaterBase(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
return cStructurePtr(new cUnderwaterBase(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
}

View File

@ -22,7 +22,7 @@ class cUnderwaterBaseGen :
typedef cGridStructGen super;
public:
cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen);
cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen);
protected:
class cUnderwaterBase; // fwd: UnderwaterBaseGen.cpp
@ -42,7 +42,7 @@ protected:
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -110,6 +110,7 @@ class cVillageGen::cVillage :
public:
cVillage(
int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ,
int a_MaxRoadDepth,
int a_MaxSize,
@ -119,7 +120,7 @@ public:
BLOCKTYPE a_RoadBlock,
BLOCKTYPE a_WaterRoadBlock
) :
super(a_OriginX, a_OriginZ),
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
m_Noise(a_Seed),
m_MaxSize(a_MaxSize),
@ -358,8 +359,8 @@ static cVillagePiecePool * g_PlainsVillagePools[] =
cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100),
cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize),
@ -374,7 +375,7 @@ cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSi
cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_OriginZ)
cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
// Generate the biomes for the chunk surrounding the origin:
int ChunkX, ChunkZ;
@ -435,7 +436,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_
{
return cStructurePtr();
}
return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock));
return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock));
}

View File

@ -21,7 +21,7 @@ class cVillageGen :
{
typedef cGridStructGen super;
public:
cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen);
cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen);
protected:
class cVillage; // fwd: VillageGen.cpp
@ -49,7 +49,7 @@ protected:
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -30,10 +30,12 @@ cGroupManager::~cGroupManager()
for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr )
{
delete itr->second;
itr->second = NULL;
}
m_pState->Groups.clear();
delete m_pState;
m_pState = NULL;
}

View File

@ -28,6 +28,7 @@ cHTTPConnection::~cHTTPConnection()
{
// LOGD("HTTP: Connection deleting: %p", this);
delete m_CurrentRequest;
m_CurrentRequest = NULL;
}

View File

@ -28,6 +28,7 @@ cItemGrid::cItemGrid(int a_Width, int a_Height) :
cItemGrid::~cItemGrid()
{
delete[] m_Slots;
m_Slots = NULL;
}

View File

@ -69,6 +69,7 @@ public:
if (!Arrow->Initialize(*a_Player->GetWorld()))
{
delete Arrow;
Arrow = NULL;
return;
}
a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow);

View File

@ -260,6 +260,7 @@ void cItemHandler::Deinit()
for(int i = 0; i < 2267; i++)
{
delete m_ItemHandler[i];
m_ItemHandler[i] = NULL;
}
memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); // Don't leave any dangling pointers around, just in case
m_HandlerInitialized = false;

View File

@ -37,6 +37,7 @@ public:
if (!ItemFrame->Initialize(*a_World))
{
delete ItemFrame;
ItemFrame = NULL;
return false;
}

View File

@ -31,6 +31,17 @@ public:
Vector3d Pos = a_Player->GetThrowStartPos();
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
// Play sound
cFastRandom Random;
a_World->BroadcastSoundEffect(
"random.bow",
(int)std::floor(a_Player->GetPosX() * 8.0),
(int)std::floor((a_Player->GetPosY() - a_Player->GetHeight()) * 8.0),
(int)std::floor(a_Player->GetPosZ() * 8.0),
0.5F,
0.4F / (Random.NextFloat(1.0F) * 0.4F + 0.8F)
);
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
{
return false;

View File

@ -23,7 +23,8 @@ class cReader :
BLOCKTYPE * OutputRows = m_BlockTypes;
int InputIdx = 0;
int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3;
for (int y = 0; y < cChunkDef::Height; y++)
int MaxHeight = std::min(+cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest
for (int y = 0; y < MaxHeight; y++)
{
for (int z = 0; z < cChunkDef::Width; z++)
{
@ -40,6 +41,7 @@ class cReader :
virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override
{
// Copy the entire heightmap, distribute it into the 3x3 chunk blob:
typedef struct {HEIGHTTYPE m_Row[16]; } ROW;
ROW * InputRows = (ROW *)a_Heightmap;
ROW * OutputRows = (ROW *)m_HeightMap;
@ -50,13 +52,32 @@ class cReader :
OutputRows[OutputIdx] = InputRows[InputIdx++];
OutputIdx += 3;
} // for z
// Find the highest block in the entire chunk, use it as a base for m_MaxHeight:
HEIGHTTYPE MaxHeight = m_MaxHeight;
for (size_t i = 0; i < ARRAYCOUNT(*a_Heightmap); i++)
{
if ((*a_Heightmap)[i] > MaxHeight)
{
MaxHeight = (*a_Heightmap)[i];
}
}
m_MaxHeight = MaxHeight;
}
public:
int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start
int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start
HEIGHTTYPE m_MaxHeight; // Maximum value in this chunk's heightmap
BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) :
m_MaxHeight(0),
m_BlockTypes(a_BlockTypes),
m_HeightMap(a_HeightMap)
{
}
} ;
@ -224,7 +245,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
// DEBUG: Save chunk data with highlighted seeds for visual inspection:
cFile f4;
if (
f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.x, a_Item.z), cFile::fmWrite)
f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite)
)
{
for (int z = 0; z < cChunkDef::Width * 3; z++)
@ -243,6 +264,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
f4.Write(Seeds, cChunkDef::Width * 3);
}
}
f4.Close();
}
//*/
@ -252,9 +274,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
// DEBUG: Save XY slices of the chunk data and lighting for visual inspection:
cFile f1, f2, f3;
if (
f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.x, a_Item.z), cFile::fmWrite) &&
f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.x, a_Item.z), cFile::fmWrite) &&
f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.x, a_Item.z), cFile::fmWrite)
f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) &&
f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) &&
f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite)
)
{
for (int z = 0; z < cChunkDef::Width * 3; z++)
@ -273,6 +295,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
f3.Write(BlockLight, cChunkDef::Width * 3);
}
}
f1.Close();
f2.Close();
f3.Close();
}
//*/
@ -293,11 +318,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
{
cReader Reader;
Reader.m_BlockTypes = m_BlockTypes;
Reader.m_HeightMap = m_HeightMap;
cReader Reader(m_BlockTypes, m_HeightMap);
for (int z = 0; z < 3; z++)
{
@ -305,16 +328,13 @@ bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
for (int x = 0; x < 3; x++)
{
Reader.m_ReadingChunkX = x;
if (!m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader))
{
return false;
}
VERIFY(m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader));
} // for z
} // for x
memset(m_BlockLight, 0, sizeof(m_BlockLight));
memset(m_SkyLight, 0, sizeof(m_SkyLight));
return true;
m_MaxHeight = Reader.m_MaxHeight;
}
@ -405,6 +425,50 @@ void cLightingThread::PrepareBlockLight(void)
void cLightingThread::PrepareBlockLight2(void)
{
// Clear seeds:
memset(m_IsSeed1, 0, sizeof(m_IsSeed1));
memset(m_IsSeed2, 0, sizeof(m_IsSeed2));
m_NumSeeds = 0;
// Add each emissive block into the seeds:
for (int y = 0; y < m_MaxHeight; y++)
{
int BaseY = y * BlocksPerYLayer; // Partial offset into m_BlockTypes for the Y coord
for (int z = 1; z < cChunkDef::Width * 3 - 1; z++)
{
int HBaseZ = z * cChunkDef::Width * 3; // Partial offset into m_Heightmap for the Z coord
int BaseZ = BaseY + HBaseZ; // Partial offset into m_BlockTypes for the Y and Z coords
for (int x = 1; x < cChunkDef::Width * 3 - 1; x++)
{
int idx = BaseZ + x;
if (y > m_HeightMap[HBaseZ + x])
{
// We're above the heightmap, ignore the block
continue;
}
if (cBlockInfo::GetLightValue(m_BlockTypes[idx]) == 0)
{
// Not a light-emissive block
continue;
}
// Add current block as a seed:
m_IsSeed1[idx] = true;
m_SeedIdx1[m_NumSeeds++] = idx;
// Light it up:
m_BlockLight[idx] = cBlockInfo::GetLightValue(m_BlockTypes[idx]);
}
}
}
}
void cLightingThread::CalcLight(NIBBLETYPE * a_Light)
{
int NumSeeds2 = 0;

View File

@ -108,6 +108,9 @@ protected:
cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread
cEvent m_evtQueueEmpty; // Set when the queue gets empty
/** The highest block in the current 3x3 chunk data */
HEIGHTTYPE m_MaxHeight;
// Buffers for the 3x3 chunk data
// These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less
@ -136,8 +139,8 @@ protected:
/** Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk */
void LightChunk(cLightingChunkStay & a_Item);
/** Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays */
bool ReadChunks(int a_ChunkX, int a_ChunkZ);
/** Prepares m_BlockTypes and m_HeightMap data; zeroes out the light arrays */
void ReadChunks(int a_ChunkX, int a_ChunkZ);
/** Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight */
void PrepareSkyLight(void);
@ -145,6 +148,10 @@ protected:
/** Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight */
void PrepareBlockLight(void);
/** Same as PrepareBlockLight(), but uses a different traversal scheme; possibly better perf cache-wise.
To be compared in perf benchmarks. */
void PrepareBlockLight2(void);
/** Calculates light in the light array specified, using stored seeds */
void CalcLight(NIBBLETYPE * a_Light);

View File

@ -57,6 +57,7 @@ cMCLogger::~cMCLogger()
{
m_Log->Log("--- Stopped Log ---\n");
delete m_Log;
m_Log = NULL;
if (this == s_MCLogger)
{
s_MCLogger = NULL;

View File

@ -47,6 +47,7 @@ void cBlaze::Attack(float a_Dt)
if (!FireCharge->Initialize(*m_World))
{
delete FireCharge;
FireCharge = NULL;
return;
}
m_World->BroadcastSpawnEntity(*FireCharge);

View File

@ -49,6 +49,7 @@ void cGhast::Attack(float a_Dt)
if (!GhastBall->Initialize(*m_World))
{
delete GhastBall;
GhastBall = NULL;
return;
}
m_World->BroadcastSpawnEntity(*GhastBall);

View File

@ -84,6 +84,7 @@ void cSkeleton::Attack(float a_Dt)
if (!Arrow->Initialize(*m_World))
{
delete Arrow;
Arrow = NULL;
return;
}
m_World->BroadcastSpawnEntity(*Arrow);

View File

@ -47,6 +47,7 @@ cMonsterConfig::cMonsterConfig(void)
cMonsterConfig::~cMonsterConfig()
{
delete m_pState;
m_pState = NULL;
}

View File

@ -877,6 +877,7 @@ void cPerlinNoise::Generate2D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
a_Workspace = NULL;
}
}
@ -943,6 +944,7 @@ void cPerlinNoise::Generate3D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
a_Workspace = NULL;
}
}
@ -1045,6 +1047,7 @@ void cRidgedMultiNoise::Generate2D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
a_Workspace = NULL;
}
}
@ -1111,6 +1114,7 @@ void cRidgedMultiNoise::Generate3D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
a_Workspace = NULL;
}
}

View File

@ -71,6 +71,7 @@ cEvent::~cEvent()
{
sem_destroy(m_Event);
delete m_Event;
m_Event = NULL;
}
#endif
}

View File

@ -61,6 +61,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client)
// There was an error launching the thread (but it was already logged along with the reason)
LOGERROR("A new cSocketThread failed to start");
delete Thread;
Thread = NULL;
return false;
}
Thread->AddClient(a_Socket, a_Client);

View File

@ -66,11 +66,13 @@ cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_Thre
cThread::~cThread()
{
delete m_Event;
m_Event = NULL;
if( m_StopEvent )
{
m_StopEvent->Wait();
delete m_StopEvent;
m_StopEvent = NULL;
}
}

View File

@ -37,6 +37,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
cProtocolRecognizer::~cProtocolRecognizer()
{
delete m_Protocol;
m_Protocol = NULL;
}

View File

@ -326,6 +326,7 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket)
LOGERROR("Client \"%s\" cannot be handled, server probably unstable", ClientIP.c_str());
a_Socket.CloseSocket();
delete NewHandle;
NewHandle = NULL;
return;
}

View File

@ -169,7 +169,8 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
X = Pos->x;
Z = Pos->z;
}
}else if(BlockID == E_BLOCK_AIR)
}
else if(BlockID == E_BLOCK_AIR)
{
LowestPoint = 9; //This always dominates
X = Pos->x;
@ -177,6 +178,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
}
delete Pos;
Pos = NULL;
}
if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z))

View File

@ -59,19 +59,21 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
int RelZ = 0;
BLOCKTYPE Block;
NIBBLETYPE Meta;
cChunk * Chunk;
if (a_OtherChunk != NULL)
{
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
a_OtherChunk->SetIsRedstoneDirty(true);
Chunk = a_OtherChunk;
}
else
{
RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
Chunk = a_Chunk;
}
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
@ -90,7 +92,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
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);
itr = PoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true);
Chunk->SetIsRedstoneDirty(true);
continue;
}
else if (
@ -105,9 +107,25 @@ 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);
itr = PoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true);
Chunk->SetIsRedstoneDirty(true);
continue;
}
else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
{
if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ()))
{
m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ());
}
else
{
if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
{
itr = PoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true);
continue;
}
}
}
++itr;
}
@ -121,7 +139,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true);
Chunk->SetIsRedstoneDirty(true);
continue;
}
else if (
@ -135,7 +153,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true);
Chunk->SetIsRedstoneDirty(true);
continue;
}
}
@ -145,7 +163,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true);
Chunk->SetIsRedstoneDirty(true);
continue;
}
}
@ -253,6 +271,8 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
ShouldUpdateSimulateOnceBlocks = true;
}
HandleRedstoneRepeaterDelays();
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
{
if (dataitr->DataTwo)
@ -264,26 +284,6 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
switch (dataitr->Data)
{
case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
bool FoundItem = false;
for (RepeatersDelayList::iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr)
{
if (repeateritr->a_RelBlockPos == Vector3i(dataitr->x, dataitr->y, dataitr->z))
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, repeateritr);
FoundItem = true;
break;
}
}
if (!FoundItem && ShouldUpdateSimulateOnceBlocks)
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, m_RepeatersDelayList->end());
}
break;
}
case E_BLOCK_WOODEN_PRESSURE_PLATE:
case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
@ -339,6 +339,11 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
HandlePiston(dataitr->x, dataitr->y, dataitr->z);
break;
}
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
}
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON:
{
@ -493,29 +498,10 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta);
switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered()
{
case BLOCK_FACE_YP:
case BLOCK_FACE_XP:
case BLOCK_FACE_ZP:
{
Dir--;
break;
}
case BLOCK_FACE_XM:
case BLOCK_FACE_ZM:
case BLOCK_FACE_YM:
{
Dir++;
break;
}
default:
{
ASSERT(!"Unhandled lever metadata!");
return;
}
}
eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta);
Dir = ReverseBlockFace(Dir);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@ -528,8 +514,7 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl
{
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
cChunkInterface ChunkInterface(m_World.GetChunkMap());
NIBBLETYPE MetaData = ChunkInterface.GetBlockMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE MetaData = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
@ -562,27 +547,8 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta);
switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered()
{
case BLOCK_FACE_XP:
case BLOCK_FACE_ZP:
{
Dir--;
break;
}
case BLOCK_FACE_XM:
case BLOCK_FACE_ZM:
{
Dir++;
break;
}
default:
{
ASSERT(!"Unhandled button metadata!");
return;
}
}
eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta);
Dir = ReverseBlockFace(Dir);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@ -749,7 +715,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re
void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr)
void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{
/* Repeater Orientation Mini Guide:
===================================
@ -776,102 +742,79 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
bool WereItrsChanged = false;
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
{
bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta);
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
{
WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
}
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
{
WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
}
}
}
void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
{
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); itr++)
{
if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{
int RelBlockX = itr->a_RelBlockPos.x;
int RelBlockY = itr->a_RelBlockPos.y;
int RelBlockZ = itr->a_RelBlockPos.z;
NIBBLETYPE Meta = m_Chunk->GetMeta(RelBlockX, RelBlockY, RelBlockZ);
if (itr->ShouldPowerOn)
{
m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); // For performance
switch (Meta & 0x3) // We only want the direction (bottom) bits
{
case 0x0:
{
SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ);
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM);
break;
}
case 0x1:
{
SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP);
break;
}
case 0x2:
{
SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ);
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP);
break;
}
case 0x3:
{
SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM);
break;
}
}
}
else
{
m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta);
}
m_RepeatersDelayList->erase(itr);
}
else
{
return;
// Apparently, incrementing ticks only works reliably here, and not in SimChunk;
// With a world with lots of redstone, the repeaters simply do not delay
// I am confounded to say why. Perhaps optimisation failure.
LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
itr->a_ElapsedTicks++;
}
}
else
{
return;
}
if (WereItrsChanged)
{
for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr)
{
if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
// Leave a_Itr at where we found the entry
break;
}
}
}
// a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because...
// ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar...
// ...we will never get here because of the returns.
if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{
if (a_Itr->ShouldPowerOn)
{
if (!IsOn)
{
m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
}
switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
case 0x0:
{
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM);
break;
}
case 0x1:
{
SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP);
break;
}
case 0x2:
{
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP);
break;
}
case 0x3:
{
SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
break;
}
}
// Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached
// Otherwise, the power state of blocks in front won't update after we have powered on
return;
}
else
{
if (IsOn)
{
m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
}
m_RepeatersDelayList->erase(a_Itr); // We can remove off repeaters which don't need further updating
return;
}
}
else
{
// Apparently, incrementing ticks only works reliably here, and not in SimChunk;
// With a world with lots of redstone, the repeaters simply do not delay
// I am confounded to say why. Perhaps optimisation failure.
LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", a_Itr->a_RelBlockPos.x, a_Itr->a_RelBlockPos.y, a_Itr->a_RelBlockPos.z, a_Itr->a_ElapsedTicks, a_Itr->a_DelayTicks);
a_Itr->a_ElapsedTicks++;
}
}
@ -1145,6 +1088,10 @@ void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
else
{
WakeUp(BlockX, a_RelBlockY, BlockZ, m_Chunk);
}
}
}
@ -1429,8 +1376,7 @@ bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_RelBlockX, int
// IsRepeaterPowered tests if a repeater should be powered by testing for power sources behind the repeater.
// It takes the coordinates of the repeater the the meta value.
bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta)
{
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
@ -1510,19 +1456,19 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
case 0x0:
case 0x2:
{
// Check if eastern(right) neighbor is a powered on repeater who is facing us.
// Check if eastern(right) neighbor is a powered on repeater who is facing us
BLOCKTYPE Block = 0;
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater?
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3;
if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked.
if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked
}
// Check if western(left) neighbor is a powered on repeater who is facing us.
// Check if western(left) neighbor is a powered on repeater who is facing us
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3;
if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked.
if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked
}
break;
@ -1532,26 +1478,26 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
case 0x1:
case 0x3:
{
// Check if southern(down) neighbor is a powered on repeater who is facing us.
// Check if southern(down) neighbor is a powered on repeater who is facing us
BLOCKTYPE Block = 0;
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3;
if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked.
if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked
}
// Check if northern(up) neighbor is a powered on repeater who is facing us.
// Check if northern(up) neighbor is a powered on repeater who is facing us
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3;
if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked.
if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked
}
break;
}
}
return false; // None of the checks succeeded, I am not a locked repeater.
return false; // None of the checks succeeded, I am not a locked repeater
}
@ -1610,7 +1556,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
a_PowerLevel = itr->a_PowerLevel;
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list
@ -1619,10 +1565,10 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
a_PowerLevel = itr->a_PowerLevel;
}
return (a_PowerLevel != 0); // Source was in front of the piston's front face
return (a_PowerLevel != 0); // Answer the inital question: is the wire powered?
}

View File

@ -108,7 +108,9 @@ private:
/** 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, RepeatersDelayList::iterator a_Itr);
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
/** Handles delayed updates to Repeaters **/
void HandleRedstoneRepeaterDelays();
/* ====================== */
/* ====== DEVICES ====== */
@ -156,7 +158,7 @@ private:
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 */
/** 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);

View File

@ -11,7 +11,9 @@
cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) :
m_Noise(a_Seed),
m_Noise1(a_Seed + 1),
m_Noise2(a_Seed + 2),
m_Noise3(a_Seed + 3),
m_CellSize(a_CellSize)
{
}
@ -57,26 +59,25 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
int CellX = a_X / m_CellSize;
int CellZ = a_Y / m_CellSize;
UpdateCell(CellX, CellZ);
// Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
int MinDist2 = MinDist;
int res = 0; // Will be overriden
for (int x = CellX - 2; x <= CellX + 2; x++)
for (int x = 0; x < 5; x++)
{
int BaseX = x * m_CellSize;
for (int z = CellZ - 2; z < CellZ + 2; z++)
for (int z = 0; z < 5; z++)
{
int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize;
int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize;
int SeedX = BaseX + OffsetX;
int SeedZ = z * m_CellSize + OffsetZ;
int SeedX = m_SeedX[x][z];
int SeedZ = m_SeedZ[x][z];
int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y);
if (Dist < MinDist)
{
MinDist2 = MinDist;
MinDist = Dist;
res = m_Noise.IntNoise3DInt(x, x - z + 1000, z);
res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2);
}
else if (Dist < MinDist2)
{
@ -93,3 +94,33 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ)
{
// If the specified cell is currently cached, bail out:
if ((a_CellX == m_CurrentCellX) && (a_CellZ == m_CurrentCellZ))
{
return;
}
// Update the cell cache for the new cell position:
int NoiseBaseX = a_CellX - 2;
int NoiseBaseZ = a_CellZ - 2;
for (int x = 0; x < 5; x++)
{
int BaseX = (NoiseBaseX + x) * m_CellSize;
for (int z = 0; z < 5; z++)
{
int OffsetX = (m_Noise1.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
int OffsetZ = (m_Noise2.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
m_SeedX[x][z] = BaseX + OffsetX;
m_SeedZ[x][z] = (NoiseBaseZ + z) * m_CellSize + OffsetZ;
} // for z
} // for x
m_CurrentCellX = a_CellX;
m_CurrentCellZ = a_CellZ;
}

View File

@ -29,15 +29,34 @@ public:
/// Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed
int GetValueAt(int a_X, int a_Y, int & a_MinDistance);
/// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds
/// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache
int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2);
protected:
/// The noise used for generating Voronoi seeds
cNoise m_Noise;
cNoise m_Noise1;
cNoise m_Noise2;
cNoise m_Noise3;
/// Size of the Voronoi cells (avg X/Y distance between the seeds)
int m_CellSize;
/** The X coordinate of the currently cached cell neighborhood */
int m_CurrentCellX;
/** The Z coordinate of the currently cached cell neighborhood */
int m_CurrentCellZ;
/** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
int m_SeedX[5][5];
/** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
int m_SeedZ[5][5];
/** Updates the cached cell seeds to match the specified cell. Noop if cell pos already matches.
Updates m_SeedX and m_SeedZ. */
void UpdateCell(int a_CellX, int a_CellZ);
} ;

View File

@ -524,6 +524,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest &
// Delete any request data assigned to the request:
cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
delete Data;
Data = NULL;
}

View File

@ -273,12 +273,12 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
cWorld::~cWorld()
{
delete m_SimulatorManager;
delete m_SandSimulator;
delete m_WaterSimulator;
delete m_LavaSimulator;
delete m_FireSimulator;
delete m_RedstoneSimulator;
delete m_SimulatorManager; m_SimulatorManager = NULL;
delete m_SandSimulator; m_SandSimulator = NULL;
delete m_WaterSimulator; m_WaterSimulator = NULL;
delete m_LavaSimulator; m_LavaSimulator = NULL;
delete m_FireSimulator; m_FireSimulator = NULL;
delete m_RedstoneSimulator; m_RedstoneSimulator = NULL;
UnloadUnusedChunks();
@ -3036,11 +3036,13 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster))
{
delete a_Monster;
a_Monster = NULL;
return -1;
}
if (!a_Monster->Initialize(*this))
{
delete a_Monster;
a_Monster = NULL;
return -1;
}
BroadcastSpawnEntity(*a_Monster);
@ -3063,6 +3065,7 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje
if (!Projectile->Initialize(*this))
{
delete Projectile;
Projectile = NULL;
return -1;
}
return Projectile->GetUniqueID();

View File

@ -529,7 +529,7 @@ public:
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
@ -843,6 +843,7 @@ private:
virtual ~cScheduledTask()
{
delete m_Task;
m_Task = NULL;
}
};

View File

@ -609,17 +609,12 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
case cProjectileEntity::pkGhastFireball:
{
m_Writer.AddInt("ExplosionPower", 1);
// fall-through:
break;
}
case cProjectileEntity::pkFireCharge:
case cProjectileEntity::pkWitherSkull:
case cProjectileEntity::pkEnderPearl:
{
m_Writer.BeginList("Motion", TAG_Double);
m_Writer.AddDouble("", a_Projectile->GetSpeedX());
m_Writer.AddDouble("", a_Projectile->GetSpeedY());
m_Writer.AddDouble("", a_Projectile->GetSpeedZ());
m_Writer.EndList();
break;
}
default:

View File

@ -469,6 +469,9 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
a_Writer.AddByte("MCSIsLightValid", 1);
}
// Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete.
a_Writer.AddByte("TerrainPopulated", 1);
a_Writer.EndCompound(); // "Level"
return true;
}

View File

@ -473,6 +473,7 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_
{
LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell());
delete Header;
Header = NULL;
return;
}
m_ChunkHeaders.push_back(Header);

View File

@ -6,9 +6,23 @@
int main(int argc, char** argv)
{
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{
// Test first segment
cChunkData buffer;
cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
@ -35,7 +49,7 @@ int main(int argc, char** argv)
{
// test following segment
cChunkData buffer;
cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
@ -62,7 +76,7 @@ int main(int argc, char** argv)
{
// test zeros
cChunkData buffer;
cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));

View File

@ -6,8 +6,21 @@
int main(int argc, char** argv)
{
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{
cChunkData buffer;
cChunkData buffer(Pool);
// Empty chunks
buffer.SetBlock(0, 0, 0, 0xAB);
@ -105,7 +118,7 @@ int main(int argc, char** argv)
}
{
cChunkData buffer;
cChunkData buffer(Pool);
// Zero's
buffer.SetBlock(0, 0, 0, 0x0);
@ -122,9 +135,9 @@ int main(int argc, char** argv)
{
// Operator =
cChunkData buffer;
cChunkData buffer(Pool);
buffer.SetBlock(0, 0, 0, 0x42);
cChunkData copy;
cChunkData copy(Pool);
#if __cplusplus < 201103L
copy = buffer;
#else

Some files were not shown because too many files have changed in this diff Show More