Browse Source

add some missing implementations

Kolja Strohm 3 years ago
parent
commit
31286b19ef

+ 20 - 0
FactoryCraft/Area.cpp

@@ -0,0 +1,20 @@
+#include "Area.h"
+
+
+Framework::Vec3<int> getDirection( Directions dir )
+{
+    Framework::Vec3<int> result( 0, 0, 0 );
+    if( ( dir | NORTH ) == dir )
+        --result.y;
+    if( ( dir | EAST ) == dir )
+        ++result.x;
+    if( ( dir | SOUTH ) == dir )
+        ++result.y;
+    if( ( dir | WEST ) == dir )
+        --result.x;
+    if( ( dir | TOP ) == dir )
+        ++result.z;
+    if( ( dir | BOTTOM ) == dir )
+        --result.z;
+    return result;
+}

+ 3 - 1
FactoryCraft/Area.h

@@ -21,4 +21,6 @@ enum Direction
     TOP = 16,
     BOTTOM = 32
 };
-typedef int Directions;
+typedef int Directions;
+
+Framework::Vec3<int> getDirection( Directions dir );

+ 33 - 0
FactoryCraft/BasicBlocks.cpp

@@ -0,0 +1,33 @@
+#include "BasicBlocks.h"
+
+
+BasicBlock::BasicBlock( ItemType *zTool, Framework::Vec3<int> pos, Framework::Textur *t )
+    : Block( zTool, pos )
+{}
+
+
+DirtBlockType::DirtBlockType()
+    : BlockType( ID )
+{}
+
+void DirtBlockType::loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader )
+{
+    BlockType::loadSuperBlock( zBlock, zReader );
+}
+
+Block *DirtBlockType::createBlock( Framework::Vec3<int> position )
+{
+    // TODO: load texture
+    return new BasicBlock( 0, position, 0 ); // TODO: add efective tool
+}
+
+
+DirtBlockItemType::DirtBlockItemType()
+    : BasicBlockItemType( ID )
+{}
+
+Item *DirtBlockItemType::createItem() const
+{
+    BasicBlockItem *item = new BasicBlockItem( (ItemType *)this, "Dirt" );
+    return item;
+}

+ 43 - 0
FactoryCraft/BasicBlocks.h

@@ -0,0 +1,43 @@
+#pragma once
+
+#include <Textur.h>
+
+#include "Block.h"
+#include "BlockType.h"
+#include "Item.h"
+
+class BlockType;
+class ItemType;
+class DirtBlockType;
+class DirtBlockItemType;
+
+class BasicBlock : public Block
+{
+public:
+    BasicBlock( ItemType *zTool, Framework::Vec3<int> pos, Framework::Textur *t );
+
+    friend DirtBlockType;
+};
+
+class DirtBlockType : public BlockType
+{
+    REGISTRABLE( DirtBlockType )
+
+protected:
+    virtual void loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader ) override;
+    virtual Block *createBlock( Framework::Vec3<int> position ) override;
+    DirtBlockType();
+};
+REGISTER( DirtBlockType, BlockType )
+
+class DirtBlockItemType : public BasicBlockItemType
+{
+    REGISTRABLE( DirtBlockItemType )
+
+protected:
+    DirtBlockItemType();
+
+public:
+    virtual Item *createItem() const override;
+};
+REGISTER( DirtBlockItemType, ItemType )

+ 83 - 0
FactoryCraft/Block.cpp

@@ -0,0 +1,83 @@
+#include "Block.h"
+#include "Inventory.h"
+#include "Globals.h"
+
+
+Block::Block( ItemType *zTool, Framework::Vec3<int> pos )
+    : Inventory( pos )
+{
+    visible = false;
+    transparent = false;
+    passable = false;
+    hp = 1;
+    maxHP = 1;
+    hardness = 1;
+    this->zTool = zTool;
+    speedModifier = 1;
+}
+
+Block::~Block()
+{}
+
+bool Block::updateVisibility()
+{
+    bool v = 0;
+    for( int d = 0; d < 6; d++ )
+    {
+        if( IS_BLOCK( zNeighbours[ d ] ) )
+            v |= zNeighbours[ d ]->isVisible() && ( zNeighbours[ d ]->transparent || zNeighbours[ d ]->passable );
+        else if( zNeighbours[ d ] )
+            v = 1;
+    }
+    if( v != visible )
+    {
+        visible = v;
+        currentGame->setVisibility( this, visible );
+        return true;
+    }
+    return false;
+}
+
+void Block::setNeighbour( Direction dir, Block *zN )
+{
+    zNeighbours[ dir ] = zN;
+}
+
+bool Block::isVisible() const
+{
+    return visible;
+}
+
+
+BasicBlockItem::BasicBlockItem( const ItemType *zType, const char *name )
+    : Item( zType, name )
+{
+    placeable = 1;
+    transparent = 0;
+    passable = 0;
+    hp = 0;
+    maxHP = 0;
+    hardness = 0;
+    toolId = 0;
+    speedModifier = 0;
+}
+
+
+BasicBlockItemType::BasicBlockItemType( int id )
+    : ItemType( id )
+{}
+
+void BasicBlockItemType::loadSuperItem( Item *zItem, Framework::StreamReader *zReader ) const
+{
+    ItemType::loadSuperItem( zItem, zReader );
+    BasicBlockItem *item = dynamic_cast<BasicBlockItem *>( zItem );
+    if( !item )
+        throw "BasicBlockItemType::loadSuperItem was called with an invalid item";
+    zReader->lese( (char *)&item->transparent, 1 );
+    zReader->lese( (char *)&item->passable, 1 );
+    zReader->lese( (char *)&item->hp, 4 );
+    zReader->lese( (char *)&item->maxHP, 4 );
+    zReader->lese( (char *)&item->hardness, 4 );
+    zReader->lese( (char *)&item->toolId, 4 );
+    zReader->lese( (char *)&item->speedModifier, 4 );
+}

+ 38 - 2
FactoryCraft/Block.h

@@ -4,9 +4,15 @@
 
 #include "Inventory.h"
 #include "Chunk.h"
+#include "BlockType.h"
 
 using namespace Framework;
 
+class BasicBlockItemType;
+
+#define AIR_BLOCK -1
+#define IS_BLOCK(b) b > 0
+
 class Block : public Model3D, public Inventory
 {
 private:
@@ -18,11 +24,41 @@ private:
     float hardness;
     float speedModifier;
     ItemType *zTool;
+    Block *zNeighbours[ 6 ];
 
 public:
-    Block( Vec3<int> position );
-    ~Block();
+    Block( ItemType *zTool, Vec3<int> position );
+    virtual ~Block();
+
+    bool updateVisibility();
+    virtual void setNeighbour( Direction dir, Block *zN );
 
+    bool isVisible() const;
     friend Chunk;
     friend BlockType;
+};
+
+class BasicBlockItem : public Item
+{
+protected:
+    bool transparent;
+    bool passable;
+    float hp;
+    float maxHP;
+    float hardness;
+    int toolId;
+    float speedModifier;
+
+public:
+    BasicBlockItem( const ItemType *zType, const char *name );
+
+    friend BasicBlockItemType;
+    friend BlockType;
+};
+
+class BasicBlockItemType : public ItemType
+{
+protected:
+    BasicBlockItemType( int id );
+    virtual void loadSuperItem( Item *zItem, Framework::StreamReader *zReader ) const override;
 };

+ 2 - 2
FactoryCraft/BlockType.cpp

@@ -24,9 +24,9 @@ void BlockType::loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader
     zBlock->zTool = StaticRegistry<ItemType>::INSTANCE.zElement( effectiveToolId );
 }
 
-Block *BlockType::loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::StreamReader *zReader )
+Block *BlockType::loadBlock( Framework::Vec3<int> position, Framework::StreamReader *zReader )
 {
-    Block *result = createBlock( position, zTarget );
+    Block *result = createBlock( position );
     loadSuperBlock( result, zReader );
     return result;
 }

+ 2 - 3
FactoryCraft/BlockType.h

@@ -6,7 +6,6 @@
 
 #include "StaticRegistry.h"
 
-class Game;
 class Block;
 
 class BlockType : public virtual Framework::ReferenceCounter
@@ -18,10 +17,10 @@ protected:
     BlockType( int id );
 
     virtual void loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader );
-    virtual Block *createBlock( Framework::Vec3<int> position, Game *zTarget ) = 0;
+    virtual Block *createBlock( Framework::Vec3<int> position ) = 0;
 
 public:
-    virtual Block *loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::StreamReader *zReader );
+    virtual Block *loadBlock( Framework::Vec3<int> position, Framework::StreamReader *zReader );
 
     int getId() const;
 };

+ 170 - 0
FactoryCraft/Chunk.cpp

@@ -0,0 +1,170 @@
+#include "Chunk.h"
+#include "Constants.h"
+#include "Block.h"
+#include "Globals.h"
+
+
+Chunk::Chunk( Framework::Punkt location, int dimensionId )
+    : ReferenceCounter(),
+    dimensionId( dimensionId ),
+    location( location )
+{
+    blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
+    memset( blocks, AIR_BLOCK, sizeof( Block * ) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT );
+    zNeighbours[ 0 ] = 0;
+    zNeighbours[ 1 ] = 0;
+    zNeighbours[ 2 ] = 0;
+    zNeighbours[ 3 ] = 0;
+}
+
+Chunk::Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader *zReader )
+    : Chunk( location, dimensionId )
+{
+    load( zReader );
+}
+
+Chunk::~Chunk()
+{
+    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
+    {
+        if( IS_BLOCK( blocks[ i ] ) )
+            blocks[ i ]->release();
+    }
+    delete[] blocks;
+}
+
+bool Chunk::updateVisibility()
+{
+    bool update = false;
+    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
+    {
+        if( IS_BLOCK( blocks[ i ] ) )
+            update |= blocks[ i ]->updateVisibility();
+    }
+    return update;
+}
+
+Block *Chunk::getBlockAt( Framework::Vec3<int> location ) const
+{
+    location.x += CHUNK_SIZE / 2;
+    location.y += CHUNK_SIZE / 2;
+    Block *result = dynamic_cast<Block *>( blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ]->getThis() );
+    return result;
+}
+
+Block *Chunk::zBlockAt( Framework::Vec3<int> location ) const
+{
+    location.x += CHUNK_SIZE / 2;
+    location.y += CHUNK_SIZE / 2;
+    return blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ];
+}
+
+void Chunk::putBlockAt( Framework::Vec3<int> location, Block *block )
+{
+    location.x -= this->location.x - CHUNK_SIZE / 2;
+    location.y -= this->location.x - CHUNK_SIZE / 2;
+    int index = ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z;
+    Block *old = blocks[ index ];
+    blocks[ index ] = block;
+    Block *neighbor = currentGame->zBlockAt( location + getDirection( NORTH ), dimensionId );
+    if( IS_BLOCK( neighbor ) )
+        neighbor->setNeighbour( SOUTH, block );
+    block->setNeighbour( NORTH, neighbor );
+    neighbor = currentGame->zBlockAt( location + getDirection( EAST ), dimensionId );
+    if( IS_BLOCK( neighbor ) )
+        neighbor->setNeighbour( WEST, block );
+    block->setNeighbour( EAST, neighbor );
+    neighbor = currentGame->zBlockAt( location + getDirection( SOUTH ), dimensionId );
+    if( IS_BLOCK( neighbor ) ) {}
+    neighbor->setNeighbour( NORTH, block );
+    block->setNeighbour( SOUTH, neighbor );
+    neighbor = currentGame->zBlockAt( location + getDirection( WEST ), dimensionId );
+    if( IS_BLOCK( neighbor ) )
+        neighbor->setNeighbour( EAST, block );
+    block->setNeighbour( WEST, neighbor );
+    neighbor = currentGame->zBlockAt( location + getDirection( TOP ), dimensionId );
+    if( IS_BLOCK( neighbor ) )
+        neighbor->setNeighbour( BOTTOM, block );
+    block->setNeighbour( TOP, neighbor );
+    neighbor = currentGame->zBlockAt( location + getDirection( BOTTOM ), dimensionId );
+    if( IS_BLOCK( neighbor ) )
+        neighbor->setNeighbour( TOP, block );
+    block->setNeighbour( BOTTOM, neighbor );
+    if( IS_BLOCK( old ) )
+        old->release();
+}
+
+void Chunk::setNeighbor( Direction dir, Chunk *zChunk )
+{
+    zNeighbours[ dir ] = zChunk;
+    for( int i = 0; i < CHUNK_SIZE; i++ )
+    {
+        for( int z = 0; z < WORLD_HEIGHT; z++ )
+        {
+            if( dir == NORTH )
+            {
+                int index = i * CHUNK_SIZE * CHUNK_SIZE + z;
+                if( blocks[ index ] )
+                    blocks[ index ]->setNeighbour( NORTH, zChunk->blocks[ ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z ] );
+            }
+            else if( dir == EAST )
+            {
+                int index = ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z;
+                if( blocks[ index ] )
+                    blocks[ index ]->setNeighbour( EAST, zChunk->blocks[ i * CHUNK_SIZE + z ] );
+            }
+            else if( dir == SOUTH )
+            {
+                int index = ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z;
+                if( blocks[ index ] )
+                    blocks[ index ]->setNeighbour( SOUTH, zChunk->blocks[ i * CHUNK_SIZE * CHUNK_SIZE + z ] );
+            }
+            else if( dir == WEST )
+            {
+                int index = i * CHUNK_SIZE + z;
+                if( blocks[ index ] )
+                    blocks[ index ]->setNeighbour( WEST, zChunk->blocks[ ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z ] );
+            }
+        }
+    }
+}
+
+void Chunk::load( Framework::StreamReader *zReader )
+{
+    for( int x = 0; x < CHUNK_SIZE; x++ )
+    {
+        for( int y = 0; y < CHUNK_SIZE; y++ )
+        {
+            for( int z = 0; z < WORLD_HEIGHT; z++ )
+            {
+                int blockType;
+                zReader->lese( (char *)&blockType, 4 );
+                if( blockType >= 0 )
+                {
+                    Block *block = StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3<int>( x, y, z ), zReader );
+                    putBlockAt( { x, y, z }, block );
+                }
+            }
+        }
+    }
+}
+
+int Chunk::getDimensionId() const
+{
+    return dimensionId;
+}
+
+Framework::Punkt Chunk::getCenter() const
+{
+    return location;
+}
+
+Framework::Vec3<int> Chunk::getMin() const
+{
+    return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
+}
+
+Framework::Vec3<int> Chunk::getMax() const
+{
+    return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
+}

+ 5 - 1
FactoryCraft/Chunk.h

@@ -1,6 +1,8 @@
 #pragma once
 
 #include <Punkt.h>
+#include <ReferenceCounter.h>
+#include <Reader.h>
 
 #include "Area.h"
 
@@ -18,6 +20,7 @@ public:
     Chunk( Framework::Punkt location, int dimensionId );
     Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader *zReader );
     ~Chunk();
+    bool updateVisibility();
     Block *getBlockAt( Framework::Vec3<int> cLocation ) const;
     Block *zBlockAt( Framework::Vec3<int> cLocation ) const;
     void putBlockAt( Framework::Vec3<int> location, Block *block );
@@ -25,5 +28,6 @@ public:
     void load( Framework::StreamReader *zReader );
     int getDimensionId() const;
     Framework::Punkt getCenter() const;
-
+    Framework::Vec3<int> getMin() const;
+    Framework::Vec3<int> getMax() const;
 };

+ 4 - 0
FactoryCraft/Constants.h

@@ -0,0 +1,4 @@
+#pragma once
+
+#define CHUNK_SIZE 16
+#define WORLD_HEIGHT 500

+ 111 - 0
FactoryCraft/Dimension.cpp

@@ -0,0 +1,111 @@
+#include "Dimension.h"
+#include "Constants.h"
+#include "Datei.h"
+#include "Game.h"
+
+using namespace Framework;
+
+
+Dimension::Dimension( int id )
+    : dimensionId( id ),
+    chunks( new Trie<Chunk>() ),
+    entities( new RCArray<Entity>() )
+{}
+
+Dimension::~Dimension()
+{
+    entities->release();
+    chunks->release();
+}
+
+void Dimension::updateVisibility()
+{
+    bool changed = true;
+    while( changed )
+    {
+        changed = false;
+        for( auto chunk = chunks->getIterator(); chunk; chunk++ )
+            changed |= chunk->updateVisibility();
+    }
+}
+
+void Dimension::getAddrOf( Punkt cPos, char *addr ) const
+{
+    *(int *)addr = cPos.x;
+    *( (int *)addr + 1 ) = cPos.y;
+    addr[ 8 ] = 0;
+}
+
+void Dimension::getAddrOfWorld( Punkt wPos, char *addr ) const
+{
+    wPos.x = (int)floor( ( (float)wPos.x + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
+    wPos.y = (int)floor( ( (float)wPos.y + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
+    getAddrOf( wPos, addr );
+}
+
+Chunk *Dimension::zChunk( Punkt wPos ) const
+{
+    char addr[ 9 ];
+    getAddrOfWorld( wPos, addr );
+    return chunks->z( addr );
+}
+
+Block *Dimension::zBlock( Vec3<int> location )
+{
+    return zChunk( Punkt( location.x, location.y ) )->zBlockAt( Vec3<int>( ( location.x + CHUNK_SIZE / 2 ) % CHUNK_SIZE, ( location.y + CHUNK_SIZE / 2 ) % CHUNK_SIZE, location.z ) );
+}
+
+void Dimension::addEntity( Entity *entity )
+{
+    entities->add( entity );
+}
+
+void Dimension::addChunk( Chunk *chunk )
+{
+    char addr[ 9 ];
+    getAddrOf( chunk->getCenter(), addr );
+    if( !chunks->z( addr ) )
+    {
+        chunks->set( addr, chunk );
+        getAddrOf( chunk->getCenter() + Punkt( CHUNK_SIZE, 0 ), addr );
+        Chunk *zChunk = chunks->z( addr );
+        if( zChunk )
+        {
+            zChunk->setNeighbor( WEST, chunk );
+            chunk->setNeighbor( EAST, chunk );
+        }
+        getAddrOf( chunk->getCenter() + Punkt( -CHUNK_SIZE, 0 ), addr );
+        zChunk = chunks->z( addr );
+        if( zChunk )
+        {
+            zChunk->setNeighbor( EAST, chunk );
+            chunk->setNeighbor( WEST, chunk );
+        }
+        getAddrOf( chunk->getCenter() + Punkt( 0, CHUNK_SIZE ), addr );
+        zChunk = chunks->z( addr );
+        if( zChunk )
+        {
+            zChunk->setNeighbor( NORTH, chunk );
+            chunk->setNeighbor( SOUTH, chunk );
+        }
+        getAddrOf( chunk->getCenter() + Punkt( 0, -CHUNK_SIZE ), addr );
+        zChunk = chunks->z( addr );
+        if( zChunk )
+        {
+            zChunk->setNeighbor( SOUTH, chunk ); // TODO: correct this in setBlock
+            chunk->setNeighbor( NORTH, chunk );
+        }
+    }
+    else
+        chunk->release();
+}
+
+int Dimension::getDimensionId() const
+{
+    return dimensionId;
+}
+
+bool Dimension::hasChunck( int x, int y ) const
+{
+    return zChunk( Punkt( x, y ) );
+}

+ 9 - 1
FactoryCraft/Dimension.h

@@ -14,8 +14,16 @@ private:
     Framework::RCArray<Entity> *entities;
     void getAddrOf( Framework::Punkt cPos, char *addr ) const;
     void getAddrOfWorld( Framework::Punkt wPos, char *addr ) const;
-    Chunk *zChunk( Framework::Punkt wPos ) const;
+
 public:
+    Dimension( int id );
+    ~Dimension();
 
     void updateVisibility();
+    Block *zBlock( Framework::Vec3<int> location );
+    void addEntity( Entity *entity );
+    void addChunk( Chunk *chunk );
+    int getDimensionId() const;
+    bool hasChunck( int x, int y ) const;
+    Chunk *zChunk( Framework::Punkt wPos ) const;
 };

+ 7 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -169,7 +169,12 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Debug\Network.dll" "network.dll"</Com
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="AddChunkUpdate.cpp" />
+    <ClCompile Include="Area.cpp" />
+    <ClCompile Include="BasicBlocks.cpp" />
+    <ClCompile Include="Block.cpp" />
     <ClCompile Include="BlockType.cpp" />
+    <ClCompile Include="Chunk.cpp" />
+    <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="DirectConnect.cpp" />
     <ClCompile Include="FactoryClient.cpp" />
     <ClCompile Include="Game.cpp" />
@@ -189,9 +194,11 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Debug\Network.dll" "network.dll"</Com
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Area.h" />
+    <ClInclude Include="BasicBlocks.h" />
     <ClInclude Include="Block.h" />
     <ClInclude Include="BlockType.h" />
     <ClInclude Include="Chunk.h" />
+    <ClInclude Include="Constants.h" />
     <ClInclude Include="CurrentPlayer.h" />
     <ClInclude Include="Dimension.h" />
     <ClInclude Include="DirectConnect.h" />

+ 24 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -25,6 +25,9 @@
     <Filter Include="inventory">
       <UniqueIdentifier>{dcbc509e-a646-43ea-9b60-9c5e96e3ea34}</UniqueIdentifier>
     </Filter>
+    <Filter Include="world\blocks">
+      <UniqueIdentifier>{3a74980a-cc13-4580-9921-d32b06389e35}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Main.cpp">
@@ -81,6 +84,21 @@
     <ClCompile Include="ItemType.cpp">
       <Filter>inventory</Filter>
     </ClCompile>
+    <ClCompile Include="BasicBlocks.cpp">
+      <Filter>world\blocks</Filter>
+    </ClCompile>
+    <ClCompile Include="Block.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="Chunk.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="Area.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="Dimension.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Menu.h">
@@ -158,5 +176,11 @@
     <ClInclude Include="ItemType.h">
       <Filter>inventory</Filter>
     </ClInclude>
+    <ClInclude Include="BasicBlocks.h">
+      <Filter>world\blocks</Filter>
+    </ClInclude>
+    <ClInclude Include="Constants.h">
+      <Filter>static</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 4 - 0
FactoryCraft/World.h

@@ -17,4 +17,8 @@ public:
     ~World();
     void update();
     void setChunk( Chunk *chunk );
+
+    Block *zBlockAt( Framework::Vec3<int> location, int dimension ) const;
+    Dimension *zDimension( int id ) const;
+    void setVisibility( Framework::Model3D *zModel, bool visible );
 };