Explorar el Código

bedder way to add and remove chunks from the world

Kolja Strohm hace 3 años
padre
commit
59ebc70eec

+ 23 - 6
FactoryCraft/BasicBlocks.cpp

@@ -11,15 +11,14 @@ BasicBlock::BasicBlock( const BlockType* zType, const char* texture, ItemType* z
     : Block( zType, zTool, pos, false )
 {
     Model3DData* data = 0;
-    if( Framework::zM3DRegister()->hatModel( "cube" ) )
-        data = Framework::zM3DRegister()->getModel( "cube" );
+    if( window->zBildschirm()->zGraphicsApi()->hasModel( "cube" ) )
+        data = window->zBildschirm()->zGraphicsApi()->getModel( "cube" );
     else
     {
-        data = new Model3DData();
+        data = window->zBildschirm()->zGraphicsApi()->createModel( "cube" );
         data->setAmbientFactor( 0.8f );
         data->setDiffusFactor( 0.1f );
         data->setSpecularFactor( 0.1f );
-        Framework::zM3DRegister()->addModel( dynamic_cast<Model3DData*>(data->getThis()), "cube" );
         float size = 1;
         float left, right, top, bottom;
         // Calculate the screen coordinates of the left side of the bitmap.
@@ -144,7 +143,6 @@ BasicBlock::BasicBlock( const BlockType* zType, const char* texture, ItemType* z
         p->indexList[ 4 ] = 7;
         p->indexList[ 5 ] = 5;
         data->addPolygon( p );
-        data->calculateNormals();
         // front side
         p = new Polygon3D();
         p->indexAnz = 6;
@@ -156,6 +154,7 @@ BasicBlock::BasicBlock( const BlockType* zType, const char* texture, ItemType* z
         p->indexList[ 4 ] = 1;
         p->indexList[ 5 ] = 3;
         data->addPolygon( p );
+        data->calculateNormals();
     }
     setModelDaten( data );
     Bild* b = new Bild();
@@ -173,11 +172,29 @@ BasicBlock::BasicBlock( const BlockType* zType, const char* texture, ItemType* z
     textur->setPolygonTextur( 4, dynamic_cast<Textur*>(tex->getThis()) );
     textur->setPolygonTextur( 5, tex );
     setModelTextur( textur );
+    breakTextur = currentGame->zScreen()->zGraphicsApi()->createOrGetTextur( "blocks.ltdb/crack", 0 );
+}
+
+BasicBlock::~BasicBlock()
+{
+    breakTextur->release();
 }
 
 bool BasicBlock::needRenderPolygon( int index )
 {
-    return CONST_BLOCK( zNeighbours[ index ], neighbourTypes[ index ] )->isTransparent();
+    return 1;
+}
+
+Textur* BasicBlock::zEffectTextur()
+{
+    if( hp < maxHP )
+        return breakTextur;
+    return 0;
+}
+
+float BasicBlock::getEffectPercentage()
+{
+    return 1 - hp / maxHP;
 }
 
 

+ 4 - 0
FactoryCraft/BasicBlocks.h

@@ -13,9 +13,13 @@ class DirtBlockItemType;
 
 class BasicBlock : public Block
 {
+    Framework::Textur* breakTextur;
 public:
     BasicBlock( const BlockType* zType, const char* texture, ItemType* zTool, Framework::Vec3<int> pos, Framework::Textur* t );
+    ~BasicBlock();
     bool needRenderPolygon( int index ) override;
+    virtual Textur* zEffectTextur() override;
+    virtual float getEffectPercentage() override;
 
     friend DirtBlockType;
 };

+ 0 - 54
FactoryCraft/Block.cpp

@@ -8,7 +8,6 @@ Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos,
     Model3D(),
     zType( zType )
 {
-    visible = false;
     transparent = false;
     passable = false;
     hp = 1;
@@ -16,70 +15,17 @@ Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos,
     hardness = 1;
     this->zTool = zTool;
     speedModifier = 1;
-    memset( zNeighbours, 0, sizeof( Block* ) * 6 );
-    memset( neighbourTypes, 0, sizeof( int ) * 6 );
     Model3D::setPosition( (Framework::Vec3<float>)pos + Framework::Vec3<float>{0.5f, 0.5f, 0.5f} );
 }
 
 Block::~Block()
 {}
 
-bool Block::updateVisibility()
-{
-    bool v = 1;
-    for( int d = 0; d < 6; d++ )
-        v |= CONST_BLOCK( zNeighbours[ d ], neighbourTypes[ d ] )->isVisible() && (CONST_BLOCK( zNeighbours[ d ], neighbourTypes[ d ] )->transparent || CONST_BLOCK( zNeighbours[ d ], neighbourTypes[ d ] )->passable);
-    if( v != visible )
-    {
-        visible = v;
-        currentGame->setVisibility( this, visible );
-        return true;
-    }
-    return false;
-}
-
-void Block::setNeighbour( Direction dir, Framework::Either<Block*, int> neighbour )
-{
-    if( neighbour.isA() )
-        setNeighbourBlock( dir, neighbour );
-    else
-    {
-        setNeighbourBlock( dir, 0 );
-        setNeighbourType( dir, neighbour );
-    }
-}
-
-void Block::setNeighbourBlock( Direction dir, Block* zN )
-{
-    if( zN )
-        setNeighbourType( dir, zN->zBlockType()->getId() );
-    zNeighbours[ getDirectionIndex( dir ) ] = zN;
-}
-
-void Block::setNeighbourType( Direction dir, int type )
-{
-    neighbourTypes[ getDirectionIndex( dir ) ] = type;
-}
-
 bool Block::isTransparent() const
 {
     return transparent;
 }
 
-void Block::remove()
-{
-    if( visible )
-    {
-        visible = 0;
-        currentGame->setVisibility( this, visible );
-    }
-}
-
-bool Block::isVisible() const
-{
-    return visible;
-}
-
 const BlockType* Block::zBlockType() const
 {
     return zType;

+ 1 - 10
FactoryCraft/Block.h

@@ -4,7 +4,6 @@
 #include <Either.h>
 
 #include "Inventory.h"
-#include "Chunk.h"
 #include "BlockType.h"
 #include "Registries.h"
 
@@ -13,11 +12,11 @@ using namespace Framework;
 #define CONST_BLOCK(maybeBlock, type) (maybeBlock ? maybeBlock : STATIC_REGISTRY( BlockType ).zElement((int)type)->zDefault())
 
 class BasicBlockItemType;
+class Chunk;
 
 class Block : public Model3D, public Inventory
 {
 protected:
-    bool visible;
     bool transparent;
     bool passable;
     float hp;
@@ -26,21 +25,13 @@ protected:
     float speedModifier;
     const BlockType* zType;
     ItemType* zTool;
-    Block* zNeighbours[ 6 ];
-    int neighbourTypes[ 6 ];
 
 public:
     Block( const BlockType* zType, ItemType* zTool, Vec3<int> position, bool hasInventory );
     virtual ~Block();
 
-    bool updateVisibility();
-    virtual void setNeighbour( Direction dir, Framework::Either<Block*, int> neighbour );
-    virtual void setNeighbourBlock( Direction dir, Block* zN );
-    virtual void setNeighbourType( Direction dir, int type );
     bool isTransparent() const;
 
-    void remove();
-    bool isVisible() const;
     const BlockType* zBlockType() const;
     friend Chunk;
     friend BlockType;

+ 34 - 232
FactoryCraft/Chunk.cpp

@@ -1,6 +1,5 @@
 #include "Chunk.h"
 #include "Constants.h"
-#include "Block.h"
 #include "Globals.h"
 
 #include "Registries.h"
@@ -9,18 +8,8 @@
 Chunk::Chunk( Framework::Punkt location, int dimensionId )
     : ReferenceCounter(),
     dimensionId( dimensionId ),
-    location( location ),
-    added( 0 )
-{
-    blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
-    blockIds = new unsigned short[ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
-    memset( blocks, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( Block* ) );
-    memset( blockIds, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( unsigned short ) );
-    zNeighbours[ 0 ] = 0;
-    zNeighbours[ 1 ] = 0;
-    zNeighbours[ 2 ] = 0;
-    zNeighbours[ 3 ] = 0;
-}
+    location( location )
+{}
 
 Chunk::Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader )
     : Chunk( location, dimensionId )
@@ -29,224 +18,54 @@ Chunk::Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReade
 }
 
 Chunk::~Chunk()
-{
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
-    {
-        if( blocks[ i ] )
-            blocks[ i ]->release();
-    }
-    delete[] blocks;
-    delete[] blockIds;
-}
+{}
 
-Framework::Either<Block*, int> Chunk::zBlockNeighbor( Framework::Vec3<int> location )
+Block* Chunk::zBlockAt( Framework::Vec3<int> location ) const
 {
-    if( location.x >= 0 && location.x < CHUNK_SIZE && location.y >= 0 && location.y < CHUNK_SIZE && location.z >= 0 && location.z < WORLD_HEIGHT )
+    for( Block* b : blocks )
     {
-        int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-        if( blocks[ index ] )
-            return blocks[ index ];
-        else
-            return (int)blockIds[ index ];
+        if( (Framework::Vec3<int>)b->getPos() == location )
+            return b;
     }
-    if( added && location.z >= 0 && location.z < WORLD_HEIGHT )
-        return currentGame->zBlockAt( { location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, dimensionId );
     return 0;
 }
 
-bool Chunk::updateVisibility()
+void Chunk::setBlock( Block* block )
 {
-    bool update = false;
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
+    Framework::Vec3<int> pos = (Framework::Vec3<int>)block->getPos();
+    for( Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++ )
     {
-        if( blocks[ i ] )
-            update |= blocks[ i ]->updateVisibility();
-    }
-    return update;
-}
-
-Framework::Either<Block*, int> Chunk::zBlockAt( Framework::Vec3<int> location ) const
-{
-    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
-    if( blocks[ index ] )
-        return blocks[ index ];
-    else
-        return (int)blockIds[ index ];
-}
-
-const Block* Chunk::zBlockConst( Framework::Vec3<int> location ) const
-{
-    Block* b = zBlockAt( location );
-    if( b )
-        return b;
-    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-    if( blockIds[ index ] )
-        return STATIC_REGISTRY( BlockType ).zElement( blockIds[ index ] )->zDefault();
-    return 0;
-}
-
-void Chunk::putBlockAt( Framework::Vec3<int> location, Block* block )
-{
-    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
-    Block* old = blocks[ index ];
-    if( block )
-        blockIds[ index ] = (unsigned short)block->zBlockType()->getId();
-    blocks[ index ] = block;
-    Either<Block*, int> neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( SOUTH, block );
-    if( block )
-        block->setNeighbour( NORTH, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( EAST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( WEST, block );
-    if( block )
-        block->setNeighbour( EAST, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( NORTH, block );
-    if( block )
-        block->setNeighbour( SOUTH, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( WEST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( EAST, block );
-    if( block )
-        block->setNeighbour( WEST, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( TOP ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( BOTTOM, block );
-    if( block )
-        block->setNeighbour( TOP, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( TOP, block );
-    if( block )
-        block->setNeighbour( BOTTOM, neighbor );
-    if( old )
-        old->release();
-}
-
-void Chunk::putBlockTypeAt( Framework::Vec3<int> location, int type )
-{
-    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
-    blockIds[ index ] = (unsigned short)type;
-    Either<Block*, int> neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( SOUTH, type );
-    neighbor = zBlockNeighbor( location + getDirection( EAST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( WEST, type );
-    neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( NORTH, type );
-    neighbor = zBlockNeighbor( location + getDirection( WEST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( EAST, type );
-    neighbor = zBlockNeighbor( location + getDirection( TOP ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( BOTTOM, type );
-    neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( TOP, type );
-}
-
-void Chunk::setNeighbor( Direction dir, Chunk* zChunk )
-{
-    zNeighbours[ getDirectionIndex( dir ) ] = zChunk;
-    for( int i = 0; i < CHUNK_SIZE; i++ )
-    {
-        for( int z = 0; z < WORLD_HEIGHT; z++ )
+        if( pos == (Framework::Vec3<int>)iterator->getPos() )
         {
-            if( dir == NORTH )
-            {
-                int index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( NORTH, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( NORTH, 0 );
-                        blocks[ index ]->setNeighbourType( NORTH, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == EAST )
-            {
-                int index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = i * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( EAST, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( EAST, 0 );
-                        blocks[ index ]->setNeighbourType( EAST, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == SOUTH )
-            {
-                int index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( SOUTH, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( SOUTH, 0 );
-                        blocks[ index ]->setNeighbourType( SOUTH, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == WEST )
-            {
-                int index = i * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( WEST, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( WEST, 0 );
-                        blocks[ index ]->setNeighbourType( WEST, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
+            iterator->release();
+            iterator.set( block );
+            return;
         }
     }
+    blocks.add( block );
 }
 
 void Chunk::load( Framework::StreamReader* zReader )
 {
-    zReader->lese( (char*)blockIds, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( unsigned short ) );
-    for( int x = 0; x < CHUNK_SIZE; x++ )
+    Framework::Vec3<int> pos = { 0, 0, 0 };
+    unsigned short id;
+    zReader->lese( (char*)&id, 2 );
+    while( id )
     {
-        for( int y = 0; y < CHUNK_SIZE; y++ )
+        zReader->lese( (char*)&pos.x, 4 );
+        zReader->lese( (char*)&pos.y, 4 );
+        zReader->lese( (char*)&pos.z, 4 );
+        bool d;
+        zReader->lese( (char*)&d, 1 );
+        if( d )
         {
-            for( int z = 0; z < WORLD_HEIGHT; z++ )
-            {
-                unsigned short blockType;
-                zReader->lese( (char*)&blockType, 2 );
-                Block* block = STATIC_REGISTRY( BlockType ).zElement( blockType )->loadBlock( Framework::Vec3<int>( x + location.x - CHUNK_SIZE / 2, y + location.y - CHUNK_SIZE / 2, z ), zReader );
-                if( block )
-                    putBlockAt( { x, y, z }, block );
-                else
-                {
-                    if( STATIC_REGISTRY( BlockType ).zElement( blockIds[ (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z ] )->needsInstance() )
-                        putBlockAt( { x, y, z }, STATIC_REGISTRY( BlockType ).zElement( blockIds[ (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z ] )->createBlock( { x + location.x - CHUNK_SIZE / 2, y + location.y - CHUNK_SIZE / 2, z } ) );
-                    else
-                        putBlockTypeAt( { x, y, z }, blockIds[ (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z ] );
-                }
-            }
+            Block* block = STATIC_REGISTRY( BlockType ).zElement( id )->loadBlock( { pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z }, zReader );
+            if( block )
+                setBlock( block );
         }
+        else if( STATIC_REGISTRY( BlockType ).zElement( id )->needsInstance() )
+            setBlock( STATIC_REGISTRY( BlockType ).zElement( id )->createBlock( { pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z } ) );
+        zReader->lese( (char*)&id, 2 );
     }
 }
 
@@ -270,25 +89,8 @@ Framework::Vec3<int> Chunk::getMax() const
     return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
 }
 
-void Chunk::prepareRemove()
-{
-    added = 0;
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
-    {
-        if( blocks[ i ] )
-            blocks[ i ]->remove();
-    }
-    for( int i = 0; i < 4; i++ )
-    {
-        if( zNeighbours[ i ] )
-        {
-            zNeighbours[ i ]->setNeighbor( getOppositeDirection( getDirectionFromIndex( i ) ), 0 );
-            zNeighbours[ i ] = 0;
-        }
-    }
-}
-
-void Chunk::setAdded()
+void Chunk::forAll( std::function<void( Model3D* )> f )
 {
-    added = 1;
+    for( Block* b : blocks )
+        f( b );
 }

+ 9 - 17
FactoryCraft/Chunk.h

@@ -1,40 +1,32 @@
 #pragma once
 
 #include <Punkt.h>
-#include <ReferenceCounter.h>
+#include <Model3DCollection.h>
 #include <Reader.h>
 #include <Either.h>
+#include <Model3D.h>
+#include <Array.h>
 
+#include "Block.h"
 #include "Area.h"
 
-class Block;
-
-class Chunk : public virtual Framework::ReferenceCounter
+class Chunk : public Framework::Model3DCollection
 {
 private:
     int dimensionId;
     Framework::Punkt location;
-    Block** blocks;
-    unsigned short* blockIds;
-    Chunk* zNeighbours[ 4 ];
-    Framework::Either<Block*, int> zBlockNeighbor( Framework::Vec3<int> location );
-    bool added;
+    Framework::RCArray<Block> blocks;
 
 public:
     Chunk( Framework::Punkt location, int dimensionId );
     Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader );
     ~Chunk();
-    bool updateVisibility();
-    Framework::Either<Block*, int> zBlockAt( Framework::Vec3<int> cLocation ) const;
-    const Block* zBlockConst( Framework::Vec3<int> location ) const;
-    void putBlockAt( Framework::Vec3<int> location, Block* block );
-    void putBlockTypeAt( Framework::Vec3<int> location, int type );
-    void setNeighbor( Direction dir, Chunk* zChunk );
+    Block* zBlockAt( Framework::Vec3<int> cLocation ) const;
+    void setBlock( Block* block );
     void load( Framework::StreamReader* zReader );
     int getDimensionId() const;
     Framework::Punkt getCenter() const;
     Framework::Vec3<int> getMin() const;
     Framework::Vec3<int> getMax() const;
-    void prepareRemove();
-    void setAdded();
+    void forAll( std::function<void( Model3D* )> f ) override;
 };

+ 16 - 64
FactoryCraft/Dimension.cpp

@@ -3,6 +3,7 @@
 #include "Datei.h"
 #include "Game.h"
 #include "Globals.h"
+#include "World.h"
 
 using namespace Framework;
 
@@ -20,28 +21,6 @@ Dimension::~Dimension()
     chunks->release();
 }
 
-void Dimension::updateVisibility()
-{
-    bool changed = true;
-    while( changed )
-    {
-        changed = false;
-        cs.lock();
-        for( auto chunk : chunkList )
-        {
-            if( chunk )
-            {
-                chunk->getThis();
-                cs.unlock();
-                changed |= chunk->updateVisibility();
-                chunk->release();
-                cs.lock();
-            }
-        }
-        cs.unlock();
-    }
-}
-
 void Dimension::getAddrOf( Punkt cPos, char* addr ) const
 {
     *(int*)addr = cPos.x;
@@ -86,7 +65,7 @@ void Dimension::addEntity( Entity* entity )
     entities->add( entity );
 }
 
-void Dimension::setChunk( Chunk* chunk, Punkt center )
+void Dimension::setChunk( Chunk* chunk, Punkt center, World* zWorld )
 {
     char addr[ 8 ];
     getAddrOfWorld( center, addr );
@@ -94,54 +73,27 @@ void Dimension::setChunk( Chunk* chunk, Punkt center )
     cs.lock();
     if( old )
     {
-        for( int i = 0; i < chunkList.getEintragAnzahl(); i++ )
+        int index = 0;
+        for( auto iterator = chunkList.begin(); iterator; ++iterator, ++index )
         {
-            if( chunkList.get( i ) == old )
+            if( (Chunk*)iterator == old )
             {
-                chunkList.remove( i );
+                if( chunk )
+                    iterator.set( chunk );
+                else
+                    chunkList.remove( index );
                 break;
             }
         }
     }
+    else if( chunk )
+        chunkList.add( chunk );
     chunks->set( addr, 8, chunk );
-    cs.unlock();
     if( chunk )
     {
-        chunkList.add( chunk );
-        chunk->setAdded();
-    }
-    getAddrOfWorld( center + Punkt( CHUNK_SIZE, 0 ), addr );
-    Chunk* zChunk = chunks->z( addr, 8 );
-    if( zChunk )
-    {
-        zChunk->setNeighbor( WEST, chunk );
-        if( chunk )
-            chunk->setNeighbor( EAST, zChunk );
-    }
-    getAddrOfWorld( center + Punkt( -CHUNK_SIZE, 0 ), addr );
-    zChunk = chunks->z( addr, 8 );
-    if( zChunk )
-    {
-        zChunk->setNeighbor( EAST, chunk );
-        if( chunk )
-            chunk->setNeighbor( WEST, zChunk );
-    }
-    getAddrOfWorld( center + Punkt( 0, CHUNK_SIZE ), addr );
-    zChunk = chunks->z( addr, 8 );
-    if( zChunk )
-    {
-        zChunk->setNeighbor( NORTH, chunk );
-        if( chunk )
-            chunk->setNeighbor( SOUTH, zChunk );
-    }
-    getAddrOfWorld( center + Punkt( 0, -CHUNK_SIZE ), addr );
-    zChunk = chunks->z( addr, 8 );
-    if( zChunk )
-    {
-        zChunk->setNeighbor( SOUTH, chunk );
-        if( chunk )
-            chunk->setNeighbor( NORTH, zChunk );
+        zWorld->setVisibility( chunk, 1 );
     }
+    cs.unlock();
 }
 
 int Dimension::getDimensionId() const
@@ -154,7 +106,7 @@ bool Dimension::hasChunck( int x, int y ) const
     return zChunk( Punkt( x, y ) );
 }
 
-void Dimension::removeDistantChunks( Punkt wPos )
+void Dimension::removeDistantChunks( Punkt wPos, World* zWorld )
 {
     Array<int> removed;
     int index = 0;
@@ -167,7 +119,7 @@ void Dimension::removeDistantChunks( Punkt wPos )
     for( int i : removed )
     {
         Chunk* chunk = chunkList.get( i );
-        chunk->prepareRemove();
-        setChunk( 0, chunk->getCenter() );
+        zWorld->setVisibility( chunk, 0 );
+        setChunk( 0, chunk->getCenter(), zWorld );
     }
 }

+ 4 - 3
FactoryCraft/Dimension.h

@@ -7,6 +7,8 @@
 #include "Chunk.h"
 #include "Entity.h"
 
+class World;
+
 class Dimension : public virtual Framework::ReferenceCounter
 {
 private:
@@ -22,12 +24,11 @@ public:
     Dimension( int id );
     ~Dimension();
 
-    void updateVisibility();
     Framework::Either<Block*, int> zBlock( Framework::Vec3<int> location );
     void addEntity( Entity* entity );
-    void setChunk( Chunk* chunk, Framework::Punkt center );
+    void setChunk( Chunk* chunk, Framework::Punkt center, World* zWorld );
     int getDimensionId() const;
     bool hasChunck( int x, int y ) const;
     Chunk* zChunk( Framework::Punkt wPos ) const;
-    void removeDistantChunks( Framework::Punkt wPos );
+    void removeDistantChunks( Framework::Punkt wPos, World* zWorld );
 };

+ 1 - 2
FactoryCraft/Main.cpp

@@ -36,7 +36,7 @@ int KSGStart Framework::Start( Framework::Startparam p )
     WNDCLASS wc = Framework::F_Normal( p.hinst );
     wc.lpszClassName = "Factory Craft";
     window.erstellen( WS_POPUPWINDOW, wc );
-    Monitor m = Framework::getMonitor( 1 );
+    Monitor m = Framework::getMonitor( 0 );
     window.setBounds( Punkt( m.x, m.y ), Punkt( m.breite, m.height ) );
     window.setAnzeigeModus( SW_SHOWNORMAL );
     window.setVSchließAktion( [&window]( void* p, void* f ) {
@@ -47,7 +47,6 @@ int KSGStart Framework::Start( Framework::Startparam p )
     Bildschirm3D screen( dynamic_cast<WFenster*>(window.getThis()), GraphicApiType::DIRECTX11 );
     window.setBildschirm( dynamic_cast<Bildschirm*>(screen.getThis()) );
     screen.setFillFarbe( 0 );
-    screen.update();
 
     uiFactory = Framework::defaultUI( fontRegister->get( "normal" ), &screen );
     initMenus();

+ 9 - 10
FactoryCraft/World.cpp

@@ -74,7 +74,7 @@ void World::update( bool background )
             }
             ((Game*)(Menu*)menuRegister->get( "game" ))->updatePosition( pos );
             for( Dimension* dim : *dimensions )
-                dim->removeDistantChunks( { (int)pos.x, (int)pos.y } );
+                dim->removeDistantChunks( { (int)pos.x, (int)pos.y }, this );
             char b = 0;
             serverMessageReader->lese( &b, 1 );
             if( hasTarget && dimensions->hat( 0 ) )
@@ -82,8 +82,8 @@ void World::update( bool background )
                 if( entityTarget == -1 )
                 {
                     auto block = zBlockAt( target, dimensions->z( 0 )->getDimensionId() );
-                    if( block.isA() )
-                        block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() - 0.2 );
+                    if( block.isA() && block.getA() )
+                        block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() - 0.2f );
                 }
             }
             if( b == 1 )
@@ -107,8 +107,8 @@ void World::update( bool background )
                 if( entityTarget == -1 )
                 {
                     auto block = zBlockAt( target, dimensions->z( 0 )->getDimensionId() );
-                    if( block.isA() )
-                        block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() + 0.2 );
+                    if( block.isA() && block.getA() )
+                        block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() + 0.2f );
                 }
             }
         }
@@ -126,9 +126,8 @@ void World::setChunk( Chunk* chunk, int dimensionId )
         zDim = new Dimension( dimensionId );
         dimensions->add( zDim );
     }
-    zDim->setChunk( chunk, chunk->getCenter() );
+    zDim->setChunk( chunk, chunk->getCenter(), this );
     zScreenPtr->unlock();
-    zDim->updateVisibility();
 }
 
 void World::thread()
@@ -179,13 +178,13 @@ Dimension* World::zDimension( int id ) const
     return 0;
 }
 
-void World::setVisibility( Framework::Model3D* zModel, bool visible )
+void World::setVisibility( Chunk* zChunk, bool visible )
 {
     renderedWorld->lock();
     if( visible )
-        renderedWorld->addZeichnung( dynamic_cast<Framework::Model3D*>(zModel->getThis()) );
+        renderedWorld->addCollection( dynamic_cast<Framework::Model3DCollection*>(zChunk->getThis()) );
     else
-        renderedWorld->removeZeichnung( zModel );
+        renderedWorld->removeCollection( zChunk );
     renderedWorld->unlock();
 }
 

+ 1 - 1
FactoryCraft/World.h

@@ -31,7 +31,7 @@ public:
 
     Framework::Either<Block*, int> zBlockAt( Framework::Vec3<int> location, int dimension ) const;
     Dimension* zDimension( int id ) const;
-    void setVisibility( Framework::Model3D* zModel, bool visible );
+    void setVisibility( Chunk* zChunk, bool visible );
     Framework::Bildschirm3D* zScreen() const;
     Framework::Punkt getChunkCenter( int x, int y ) const;
 };