Pārlūkot izejas kodu

add stone tool and crafting recipie loader

Kolja Strohm 2 gadi atpakaļ
vecāks
revīzija
90beff9325

+ 110 - 110
FactoryCraft/BasicBlock.cpp

@@ -1,276 +1,276 @@
 #include "BasicBlocks.h"
 
 
-BasicBlock::BasicBlock( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos )
-    : Block( zType, zTool, pos, false )
+BasicBlock::BasicBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos)
+	: Block(zType, zTool, pos, false)
 {}
 
-bool BasicBlock::onTick( TickQueue* zQueue, int numTicks, bool& blocked )
+bool BasicBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 {
-    return 0;
+	return 0;
 }
 
 void BasicBlock::onPostTick()
 {}
 
 
-BasicBlockType::BasicBlockType( int typeId, int itemTypeId )
-    : BlockType( typeId, 0 ),
-    itemType( itemTypeId ),
-    transparent( 0 ),
-    passable( 0 ),
-    maxHp( 100.f ),
-    hardness( 1.f ),
-    zTool( 0 ),
-    speedModifier( 1.f ),
-    interactable( 1 )
+BasicBlockType::BasicBlockType(int typeId, int itemTypeId)
+	: BlockType(typeId, 0),
+	itemType(itemTypeId),
+	transparent(0),
+	passable(0),
+	maxHp(100.f),
+	hardness(1.f),
+	zTool(0),
+	speedModifier(1.f),
+	interactable(1)
 {}
 
-void BasicBlockType::createSuperBlock( Block* zBlock, Item* zItem ) const
+void BasicBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
-    if( zItem )
-        BlockType::createSuperBlock( zBlock, zItem );
-    else
-    {
-        BasicBlock* block = dynamic_cast<BasicBlock*>(zBlock);
-        if( !block )
-            throw "DirtBlockType::createSuperBlock was called with a block witch is not an instance of BasicBlock";
-        block->transparent = transparent;
-        block->passable = passable;
-        block->hp = maxHp;
-        block->maxHP = maxHp;
-        block->hardness = hardness;
-        block->zTool = zTool;
-        block->speedModifier = speedModifier;
-        block->interactable = interactable;
-    }
+	if (zItem)
+		BlockType::createSuperBlock(zBlock, zItem);
+	else
+	{
+		BasicBlock* block = dynamic_cast<BasicBlock*>(zBlock);
+		if (!block)
+			throw "DirtBlockType::createSuperBlock was called with a block witch is not an instance of BasicBlock";
+		block->transparent = transparent;
+		block->passable = passable;
+		block->hp = maxHp;
+		block->maxHP = maxHp;
+		block->hardness = hardness;
+		block->zTool = zTool;
+		block->speedModifier = speedModifier;
+		block->interactable = interactable;
+	}
 }
 
-Block* BasicBlockType::createBlock( Framework::Vec3<int> position ) const
+Block* BasicBlockType::createBlock(Framework::Vec3<int> position) const
 {
-    return new BasicBlock( this, 0, position );
+	return new BasicBlock(this, 0, position);
 }
 
 Item* BasicBlockType::createItem() const
 {
-    return StaticRegistry<ItemType>::INSTANCE.zElement( itemType )->createItem();
+	return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
 }
 
 // Dirt
 DirtBlockType::DirtBlockType()
-    : BasicBlockType( ID, DirtBlockItemType::ID )
+	: BasicBlockType(ID, DirtBlockItemType::ID)
 {
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 DirtBlockItemType::DirtBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Dirt", 0, 0)
 {}
 
 Item* DirtBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, DirtBlockType::INSTANCE, "Dirt" );
-    initializeItem( item, 0, 0, 100, 100, 1, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, DirtBlockType::INSTANCE, "Dirt");
+	initializeItem(item, 0, 0, 100, 100, 1, 0, 1);
+	return item;
 }
 
 // Stone
 StoneBlockType::StoneBlockType()
-    : BasicBlockType( ID, StoneBlockItemType::ID )
+	: BasicBlockType(ID, StoneBlockItemType::ID)
 {
-    hardness = 2.f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 2.f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 StoneBlockItemType::StoneBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Stone", 0, 0)
 {}
 
 Item* StoneBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, StoneBlockType::INSTANCE, "Stone" );
-    initializeItem( item, 0, 0, 100, 100, 2, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, StoneBlockType::INSTANCE, "Stone");
+	initializeItem(item, 0, 0, 100, 100, 2, 0, 1);
+	return item;
 }
 
 // Sand
 SandBlockType::SandBlockType()
-    : BasicBlockType( ID, SandBlockItemType::ID )
+	: BasicBlockType(ID, SandBlockItemType::ID)
 {
-    hardness = 0.5f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 0.5f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 SandBlockItemType::SandBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Sand", 0, 0)
 {}
 
 Item* SandBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, SandBlockType::INSTANCE, "Sand" );
-    initializeItem( item, 0, 0, 100, 100, 0.5f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, SandBlockType::INSTANCE, "Sand");
+	initializeItem(item, 0, 0, 100, 100, 0.5f, 0, 1);
+	return item;
 }
 
 // Oak Wood
 OakBlockType::OakBlockType()
-    : BasicBlockType( ID, OakBlockItemType::ID )
+	: BasicBlockType(ID, OakBlockItemType::ID)
 {
-    hardness = 1.5f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 1.5f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 OakBlockItemType::OakBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Oak", 0, 0)
 {}
 
 Item* OakBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, OakBlockType::INSTANCE, "Oak" );
-    initializeItem( item, 0, 0, 100, 100, 1.5f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, OakBlockType::INSTANCE, "Oak");
+	initializeItem(item, 0, 0, 100, 100, 1.5f, 0, 1);
+	return item;
 }
 
 // Leaves Wood
 LeavesBlockType::LeavesBlockType()
-    : BasicBlockType( ID, LeavesBlockItemType::ID )
+	: BasicBlockType(ID, LeavesBlockItemType::ID)
 {
-    hardness = 0.1f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 0.1f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 LeavesBlockItemType::LeavesBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Leaves", 0, 0)
 {}
 
 Item* LeavesBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, LeavesBlockType::INSTANCE, "Leaves" );
-    initializeItem( item, 0, 0, 100, 100, 0.1f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, LeavesBlockType::INSTANCE, "Leaves");
+	initializeItem(item, 0, 0, 100, 100, 0.1f, 0, 1);
+	return item;
 }
 
 // Gravel
 GravelBlockType::GravelBlockType()
-    : BasicBlockType( ID, GravelBlockItemType::ID )
+	: BasicBlockType(ID, GravelBlockItemType::ID)
 {
-    hardness = 0.75f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 0.75f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 GravelBlockItemType::GravelBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Gravel", 0, 0)
 {}
 
 Item* GravelBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, GravelBlockType::INSTANCE, "Gravel" );
-    initializeItem( item, 0, 0, 100, 100, 0.75f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, GravelBlockType::INSTANCE, "Gravel");
+	initializeItem(item, 0, 0, 100, 100, 0.75f, 0, 1);
+	return item;
 }
 
 // Granite
 GraniteBlockType::GraniteBlockType()
-    : BasicBlockType( ID, GraniteBlockItemType::ID )
+	: BasicBlockType(ID, GraniteBlockItemType::ID)
 {
-    hardness = 3.f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 3.f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 GraniteBlockItemType::GraniteBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Granite", 0, 0)
 {}
 
 Item* GraniteBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, GraniteBlockType::INSTANCE, "Granite" );
-    initializeItem( item, 0, 0, 100, 100, 3.f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, GraniteBlockType::INSTANCE, "Granite");
+	initializeItem(item, 0, 0, 100, 100, 3.f, 0, 1);
+	return item;
 }
 
 // Cobble
 CobbleBlockType::CobbleBlockType()
-    : BasicBlockType( ID, CobbleBlockItemType::ID )
+	: BasicBlockType(ID, CobbleBlockItemType::ID)
 {
-    hardness = 1.f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 1.f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 CobbleBlockItemType::CobbleBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Cobble", 0, 0)
 {}
 
 Item* CobbleBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, CobbleBlockType::INSTANCE, "Cobble" );
-    initializeItem( item, 0, 0, 100, 100, 1.f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, CobbleBlockType::INSTANCE, "Cobble");
+	initializeItem(item, 0, 0, 100, 100, 1.f, 0, 1);
+	return item;
 }
 
 // Birch Wood
 BirchBlockType::BirchBlockType()
-    : BasicBlockType( ID, BirchBlockItemType::ID )
+	: BasicBlockType(ID, BirchBlockItemType::ID)
 {
-    hardness = 1.5f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 1.5f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 BirchBlockItemType::BirchBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Birch", 0, 0)
 {}
 
 Item* BirchBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, BirchBlockType::INSTANCE, "Birch" );
-    initializeItem( item, 0, 0, 100, 100, 1.5f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, BirchBlockType::INSTANCE, "Birch");
+	initializeItem(item, 0, 0, 100, 100, 1.5f, 0, 1);
+	return item;
 }
 
 // Beech Wood
 BeechBlockType::BeechBlockType()
-    : BasicBlockType( ID, BeechBlockItemType::ID )
+	: BasicBlockType(ID, BeechBlockItemType::ID)
 {
-    hardness = 1.5f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 1.5f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 BeechBlockItemType::BeechBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Beech", 0, 0)
 {}
 
 Item* BeechBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, BeechBlockType::INSTANCE, "Beech" );
-    initializeItem( item, 0, 0, 100, 100, 1.5f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, BeechBlockType::INSTANCE, "Beech");
+	initializeItem(item, 0, 0, 100, 100, 1.5f, 0, 1);
+	return item;
 }
 
 // Basalt
 BasaltBlockType::BasaltBlockType()
-    : BasicBlockType( ID, BasaltBlockItemType::ID )
+	: BasicBlockType(ID, BasaltBlockItemType::ID)
 {
-    hardness = 2.f;
-    defaultBlock = createBlockAt( { 0, 0, 0 }, 0 );
+	hardness = 2.f;
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 BasaltBlockItemType::BasaltBlockItemType()
-    : BasicBlockItemType( ID, 0, 0 )
+	: BasicBlockItemType(ID, "Basalt", 0, 0)
 {}
 
 Item* BasaltBlockItemType::createItem() const
 {
-    BasicBlockItem* item = new BasicBlockItem( this, BasaltBlockType::INSTANCE, "Basalt" );
-    initializeItem( item, 0, 0, 100, 100, 2.f, 0, 1 );
-    return item;
+	BasicBlockItem* item = new BasicBlockItem(this, BasaltBlockType::INSTANCE, "Basalt");
+	initializeItem(item, 0, 0, 100, 100, 2.f, 0, 1);
+	return item;
 }

+ 184 - 184
FactoryCraft/Block.cpp

@@ -9,28 +9,28 @@
 #include "AddEntityUpdate.h"
 
 
-Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory )
-    : Inventory( pos, hasInventory )
+Block::Block(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory)
+	: Inventory(pos, hasInventory)
 {
-    transparent = false;
-    passable = false;
-    hp = 1;
-    maxHP = 1;
-    hardness = 1;
-    this->zType = zType;
-    this->zTool = zTool;
-    speedModifier = 1;
-    ticksLeftCounter = 0;
-    wasTicked = 0;
-    onTickCalled = 0;
-    minTickTimeout = -1;
-    maxTickTimeout = -1;
-    tickSource = 0;
-    currentTickTimeout = 0;
-    dimensionId = 0;
-    interactable = 0;
-    deadAndRemoved = 0;
-    memset( zNeighbours, 0, sizeof( Block* ) * 6 );
+	transparent = false;
+	passable = false;
+	hp = 1;
+	maxHP = 1;
+	hardness = 1;
+	this->zType = zType;
+	this->zTool = zTool;
+	speedModifier = 1;
+	ticksLeftCounter = 0;
+	wasTicked = 0;
+	onTickCalled = 0;
+	minTickTimeout = -1;
+	maxTickTimeout = -1;
+	tickSource = 0;
+	currentTickTimeout = 0;
+	dimensionId = 0;
+	interactable = 0;
+	deadAndRemoved = 0;
+	memset(zNeighbours, 0, sizeof(Block*) * 6);
 }
 
 Block::~Block()
@@ -38,275 +38,275 @@ Block::~Block()
 
 void Block::onDestroy()
 {
-    if( !deadAndRemoved )
-    {
-        Item* blockItem = zType->getItemFromBlock( this );
-        if( blockItem )
-        {
-            ItemEntity* itemEntity = (ItemEntity*)ItemEntityType::INSTANCE->createEntity( location + Framework::Vec3<float>( 0.5f, 0.5f, 0.5f ), dimensionId, Game::INSTANCE->getNextEntityId() );
-            ItemStack* stack = new ItemStack( blockItem, 1, blockItem->getMaxStackSize() );
-            itemEntity->unsaveAddItem( stack, NO_DIRECTION );
-            stack->release();
-            Game::INSTANCE->requestWorldUpdate( new AddEntityUpdate( itemEntity, dimensionId ) );
-            deadAndRemoved = 1;
-        }
-    }
+	if (!deadAndRemoved)
+	{
+		Item* blockItem = zType->getItemFromBlock(this);
+		if (blockItem)
+		{
+			ItemEntity* itemEntity = (ItemEntity*)ItemEntityType::INSTANCE->createEntity(location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f), dimensionId, Game::INSTANCE->getNextEntityId());
+			ItemStack* stack = new ItemStack(blockItem, 1, blockItem->getMaxStackSize());
+			itemEntity->unsaveAddItem(stack, NO_DIRECTION);
+			stack->release();
+			Game::INSTANCE->requestWorldUpdate(new AddEntityUpdate(itemEntity, dimensionId));
+			deadAndRemoved = 1;
+		}
+	}
 }
 
-void Block::tick( TickQueue* zQueue )
+void Block::tick(TickQueue* zQueue)
 {
-    if( wasTicked )
-        return;
-    wasTicked = 1;
-    ticksLeftCounter++;
-    if( minTickTimeout >= 0 )
-    {
-        if( currentTickTimeout < ticksLeftCounter )
-        {
-            onTickCalled = 1;
-            bool blocked = 0;
-            bool result = onTick( zQueue, ticksLeftCounter, blocked );
-            if( blocked )
-            {
-                wasTicked = 0;
-                ticksLeftCounter--;
-                onTickCalled = 0;
-                return;
-            }
-            if( result )
-                currentTickTimeout = MAX( MIN( currentTickTimeout - 1, maxTickTimeout ), MAX( minTickTimeout, 0 ) );
-            else
-                currentTickTimeout = MAX( MIN( currentTickTimeout + 1, maxTickTimeout ), MAX( minTickTimeout, 0 ) );
-            ticksLeftCounter = 0;
-        }
-    }
+	if (wasTicked)
+		return;
+	wasTicked = 1;
+	ticksLeftCounter++;
+	if (minTickTimeout >= 0)
+	{
+		if (currentTickTimeout < ticksLeftCounter)
+		{
+			onTickCalled = 1;
+			bool blocked = 0;
+			bool result = onTick(zQueue, ticksLeftCounter, blocked);
+			if (blocked)
+			{
+				wasTicked = 0;
+				ticksLeftCounter--;
+				onTickCalled = 0;
+				return;
+			}
+			if (result)
+				currentTickTimeout = MAX(MIN(currentTickTimeout - 1, maxTickTimeout), MAX(minTickTimeout, 0));
+			else
+				currentTickTimeout = MAX(MIN(currentTickTimeout + 1, maxTickTimeout), MAX(minTickTimeout, 0));
+			ticksLeftCounter = 0;
+		}
+	}
 }
 
 void Block::postTick()
 {
-    wasTicked = 0;
-    if( onTickCalled )
-    {
-        onPostTick();
-        onTickCalled = 0;
-    }
+	wasTicked = 0;
+	if (onTickCalled)
+	{
+		onPostTick();
+		onTickCalled = 0;
+	}
 }
 
-void Block::setNeighbour( Direction dir, Framework::Either<Block*, int> neighbour )
+void Block::setNeighbour(Direction dir, Framework::Either<Block*, int> neighbour)
 {
-    if( neighbour.isA() )
-        setNeighbourBlock( dir, neighbour );
-    else
-    {
-        setNeighbourBlock( dir, 0 );
-        setNeighbourType( dir, neighbour );
-    }
+	if (neighbour.isA())
+		setNeighbourBlock(dir, neighbour);
+	else
+	{
+		setNeighbourBlock(dir, 0);
+		setNeighbourType(dir, neighbour);
+	}
 }
 
-void Block::setNeighbourBlock( Direction dir, Block* zN )
+void Block::setNeighbourBlock(Direction dir, Block* zN)
 {
-    if( zN )
-        setNeighbourType( dir, zN->zBlockType()->getId() );
-    zNeighbours[ getDirectionIndex( dir ) ] = zN;
+	if (zN)
+		setNeighbourType(dir, zN->zBlockType()->getId());
+	zNeighbours[getDirectionIndex(dir)] = zN;
 }
 
-void Block::setNeighbourType( Direction dir, int type )
+void Block::setNeighbourType(Direction dir, int type)
 {
-    neighbourTypes[ getDirectionIndex( dir ) ] = type;
+	neighbourTypes[getDirectionIndex(dir)] = type;
 }
 
-void Block::setDimensionId( int id )
+void Block::setDimensionId(int id)
 {
-    dimensionId = id;
+	dimensionId = id;
 }
 
-void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
+void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
 {
-    // TODO: answer api requests
+	// TODO: answer api requests
 }
 
 bool Block::isTickSource() const
 {
-    return tickSource;
+	return tickSource;
 }
 
 const BlockType* Block::zBlockType() const
 {
-    return zType;
+	return zType;
 }
 
 bool Block::isTransparent() const
 {
-    return transparent;
+	return transparent;
 }
 
 bool Block::isPassable() const
 {
-    return passable;
+	return passable;
 }
 
 bool Block::isInteractable() const
 {
-    return interactable;
+	return interactable;
 }
 
 float Block::getHP() const
 {
-    return hp;
+	return hp;
 }
 
 float Block::getMaxHP() const
 {
-    return maxHP;
+	return maxHP;
 }
 
 float Block::getHardness() const
 {
-    return hardness;
+	return hardness;
 }
 
 ItemType* Block::zEffectiveTool() const
 {
-    return zTool;
+	return zTool;
 }
 
 float Block::getSpeedModifier() const
 {
-    return speedModifier;
+	return speedModifier;
 }
 
 const Framework::Vec3<int> Block::getPos() const
 {
-    return (Framework::Vec3<int>)location;
+	return (Framework::Vec3<int>)location;
 }
 
 int Block::getDimensionId() const
 {
-    return dimensionId;
+	return dimensionId;
 }
 
 bool Block::isVisible() const
 {
-    if( passable || transparent )
-        return 1;
-    for( int i = 0; i < 6; i++ )
-    {
-        const Block* neighbour = CONST_BLOCK( zNeighbours[ i ], neighbourTypes[ i ] );
-        if( neighbour->isPassable() || neighbour->isTransparent() )
-            return 1;
-    }
-    return 0;
+	if (passable || transparent)
+		return 1;
+	for (int i = 0; i < 6; i++)
+	{
+		const Block* neighbour = CONST_BLOCK(zNeighbours[i], neighbourTypes[i]);
+		if (neighbour->isPassable() || neighbour->isTransparent())
+			return 1;
+	}
+	return 0;
 }
 
-void Block::setHP( float hp )
+void Block::setHP(float hp)
 {
-    bool isDead = this->hp == 0.f;
-    this->hp = MAX( 0.f, hp );
-    if( !isDead && this->hp == 0.f )
-    {
-        for( int i = 0; i < 6; i++ )
-        {
-            if( neighbourTypes[ i ] == NoBlockBlockType::ID )
-            {
-                Framework::Vec3<int> pos = getPos() + getDirection( getDirectionFromIndex( i ) );
-                Game::INSTANCE->requestWorldUpdate( new PlaceBlockUpdate( Game::INSTANCE->zGenerator()->generateSingleBlock( pos, dimensionId ), pos, dimensionId ) );
-            }
-        }
-        Game::INSTANCE->requestWorldUpdate( new BlockRemovedUpdate( getPos(), dimensionId ) );
-        onDestroy();
-    }
-    else
-        requestTransmission();
+	bool isDead = this->hp == 0.f;
+	this->hp = MAX(0.f, hp);
+	if (!isDead && this->hp == 0.f)
+	{
+		for (int i = 0; i < 6; i++)
+		{
+			if (neighbourTypes[i] == NoBlockBlockType::ID)
+			{
+				Framework::Vec3<int> pos = getPos() + getDirection(getDirectionFromIndex(i));
+				Game::INSTANCE->requestWorldUpdate(new PlaceBlockUpdate(Game::INSTANCE->zGenerator()->generateSingleBlock(pos, dimensionId), pos, dimensionId));
+			}
+		}
+		Game::INSTANCE->requestWorldUpdate(new BlockRemovedUpdate(getPos(), dimensionId));
+		onDestroy();
+	}
+	else
+		requestTransmission();
 }
 
 void Block::onAfterTransmission()
 {
-    transmissionRequested = 0;
+	transmissionRequested = 0;
 }
 
 void Block::requestTransmission()
 {
-    if( !transmissionRequested )
-    {
-        transmissionRequested = 1;
-        Game::INSTANCE->requestWorldUpdate( new BlockChangedUpdate( getPos(), getDimensionId() ) );
-    }
+	if (!transmissionRequested)
+	{
+		transmissionRequested = 1;
+		Game::INSTANCE->requestWorldUpdate(new BlockChangedUpdate(getPos(), getDimensionId()));
+	}
 }
 
 bool Block::isDeadAndRemoved() const
 {
-    return deadAndRemoved;
+	return deadAndRemoved;
 }
 
 
-BasicBlockItem::BasicBlockItem( const ItemType* zType, const BlockType* zPlacedBlockType, const char* name )
-    : Item( zType, name )
+BasicBlockItem::BasicBlockItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name)
+	: Item(zType, name)
 {
-    placeable = 1;
-    zBlockType = zPlacedBlockType;
+	placeable = 1;
+	zBlockType = zPlacedBlockType;
 }
 
-bool BasicBlockItem::canBeStackedWith( Item* zItem ) const
+bool BasicBlockItem::canBeStackedWith(Item* zItem) const
 {
-    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
-    if( item )
-    {
-        return Item::canBeStackedWith( zItem ) &&
-            transparent == item->transparent &&
-            passable == item->passable &&
-            hp == item->hp &&
-            maxHP == item->maxHP &&
-            hardness == item->hardness &&
-            toolId == item->toolId &&
-            speedModifier == item->speedModifier && interactable == item->interactable;
-    }
-    return 0;
+	BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
+	if (item)
+	{
+		return Item::canBeStackedWith(zItem) &&
+			transparent == item->transparent &&
+			passable == item->passable &&
+			hp == item->hp &&
+			maxHP == item->maxHP &&
+			hardness == item->hardness &&
+			toolId == item->toolId &&
+			speedModifier == item->speedModifier && interactable == item->interactable;
+	}
+	return 0;
 }
 
 
-BasicBlockItemType::BasicBlockItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType )
-    : ItemType( id, levelUpRule, zBrokenType )
+BasicBlockItemType::BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType)
+	: ItemType(id, name, levelUpRule, zBrokenType)
 {}
 
-void BasicBlockItemType::loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const
+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 );
-    zReader->lese( (char*)&item->interactable, 1 );
+	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);
+	zReader->lese((char*)&item->interactable, 1);
 }
 
-void BasicBlockItemType::saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
+void BasicBlockItemType::saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const
 {
-    ItemType::saveSuperItem( zItem, zWriter );
-    const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
-    if( !item )
-        throw "BasicBlockItemType::saveSuperItem was called with an invalid item";
-    zWriter->schreibe( (char*)&item->transparent, 1 );
-    zWriter->schreibe( (char*)&item->passable, 1 );
-    zWriter->schreibe( (char*)&item->hp, 4 );
-    zWriter->schreibe( (char*)&item->maxHP, 4 );
-    zWriter->schreibe( (char*)&item->hardness, 4 );
-    zWriter->schreibe( (char*)&item->toolId, 4 );
-    zWriter->schreibe( (char*)&item->speedModifier, 4 );
-    zWriter->schreibe( (char*)&item->interactable, 1 );
+	ItemType::saveSuperItem(zItem, zWriter);
+	const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
+	if (!item)
+		throw "BasicBlockItemType::saveSuperItem was called with an invalid item";
+	zWriter->schreibe((char*)&item->transparent, 1);
+	zWriter->schreibe((char*)&item->passable, 1);
+	zWriter->schreibe((char*)&item->hp, 4);
+	zWriter->schreibe((char*)&item->maxHP, 4);
+	zWriter->schreibe((char*)&item->hardness, 4);
+	zWriter->schreibe((char*)&item->toolId, 4);
+	zWriter->schreibe((char*)&item->speedModifier, 4);
+	zWriter->schreibe((char*)&item->interactable, 1);
 }
 
-void BasicBlockItemType::initializeItem( BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier ) const
+void BasicBlockItemType::initializeItem(BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier) const
 {
-    zItem->transparent = transparent;
-    zItem->passable = passable;
-    zItem->hp = hp;
-    zItem->maxHP = maxHP;
-    zItem->hardness = hardness;
-    zItem->toolId = toolId;
-    zItem->speedModifier = speedModifier;
+	zItem->transparent = transparent;
+	zItem->passable = passable;
+	zItem->hp = hp;
+	zItem->maxHP = maxHP;
+	zItem->hardness = hardness;
+	zItem->toolId = toolId;
+	zItem->speedModifier = speedModifier;
 }

+ 84 - 84
FactoryCraft/Block.h

@@ -21,105 +21,105 @@ class TickQueue;
 class Block : public Inventory
 {
 private:
-    int ticksLeftCounter;
-    int currentTickTimeout;
-    bool wasTicked;
-    bool onTickCalled;
-    int dimensionId;
+	int ticksLeftCounter;
+	int currentTickTimeout;
+	bool wasTicked;
+	bool onTickCalled;
+	int dimensionId;
 
 protected:
-    bool transparent;
-    bool passable;
-    float hp;
-    float maxHP;
-    float hardness;
-    const BlockType* zType;
-    ItemType* zTool;
-    float speedModifier;
-    Block* zNeighbours[ 6 ];
-    int neighbourTypes[ 6 ];
-
-    int minTickTimeout;
-    int maxTickTimeout;
-    bool tickSource;
-    bool interactable;
-    bool transmissionRequested;
-    bool deadAndRemoved;
-
-    /// <summary>
-    /// executes block specific things
-    /// </summary>
-    /// <param name="zqueue">a queue to add neighbor blocks that should be ticked after this block</param>
-    /// <param name="numTicks">the number of ticks passed since the last call (only for tickSources)</param>
-    /// <param name="blocked">can be set to one to tell that this block needs to be tickt again later in the queue of this tick</param>
-    /// <returns>true, iff the block needs to be ticked more often</returns>
-    virtual bool onTick( TickQueue* zQueue, int numTicks, bool& blocked ) = 0;
-    /// <summary>
-    /// gets called after each block was tickt.
-    /// the order of blocks called will be exactly the same as onTick
-    /// </summary>
-    virtual void onPostTick() = 0;
-    virtual void onDestroy();
+	bool transparent;
+	bool passable;
+	float hp;
+	float maxHP;
+	float hardness;
+	const BlockType* zType;
+	ItemType* zTool;
+	float speedModifier;
+	Block* zNeighbours[6];
+	int neighbourTypes[6];
+
+	int minTickTimeout;
+	int maxTickTimeout;
+	bool tickSource;
+	bool interactable;
+	bool transmissionRequested;
+	bool deadAndRemoved;
+
+	/// <summary>
+	/// executes block specific things
+	/// </summary>
+	/// <param name="zqueue">a queue to add neighbor blocks that should be ticked after this block</param>
+	/// <param name="numTicks">the number of ticks passed since the last call (only for tickSources)</param>
+	/// <param name="blocked">can be set to one to tell that this block needs to be tickt again later in the queue of this tick</param>
+	/// <returns>true, iff the block needs to be ticked more often</returns>
+	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) = 0;
+	/// <summary>
+	/// gets called after each block was tickt.
+	/// the order of blocks called will be exactly the same as onTick
+	/// </summary>
+	virtual void onPostTick() = 0;
+	virtual void onDestroy();
 
 public:
-    Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory );
-    virtual ~Block();
-
-    void tick( TickQueue* zQueue );
-    void postTick();
-    void setDimensionId( int id );
-    virtual void setNeighbour( Direction dir, Framework::Either<Block*, int> neighbor );
-    virtual void setNeighbourBlock( Direction dir, Block* zN );
-    virtual void setNeighbourType( Direction dir, int type );
-
-    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
-
-    bool isTickSource() const;
-    const BlockType* zBlockType() const;
-    bool isTransparent() const;
-    bool isPassable() const;
-    bool isInteractable() const;
-    float getHP() const;
-    float getMaxHP() const;
-    float getHardness() const;
-    ItemType* zEffectiveTool() const;
-    float getSpeedModifier() const;
-    const Framework::Vec3<int> getPos() const;
-    int getDimensionId() const;
-    bool isVisible() const;
-    void setHP( float hp );
-    void onAfterTransmission();
-    void requestTransmission();
-    bool isDeadAndRemoved() const;
-
-    friend BlockType;
+	Block(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory);
+	virtual ~Block();
+
+	void tick(TickQueue* zQueue);
+	void postTick();
+	void setDimensionId(int id);
+	virtual void setNeighbour(Direction dir, Framework::Either<Block*, int> neighbor);
+	virtual void setNeighbourBlock(Direction dir, Block* zN);
+	virtual void setNeighbourType(Direction dir, int type);
+
+	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+
+	bool isTickSource() const;
+	const BlockType* zBlockType() const;
+	bool isTransparent() const;
+	bool isPassable() const;
+	bool isInteractable() const;
+	float getHP() const;
+	float getMaxHP() const;
+	float getHardness() const;
+	ItemType* zEffectiveTool() const;
+	float getSpeedModifier() const;
+	const Framework::Vec3<int> getPos() const;
+	int getDimensionId() const;
+	bool isVisible() const;
+	void setHP(float hp);
+	void onAfterTransmission();
+	void requestTransmission();
+	bool isDeadAndRemoved() const;
+
+	friend BlockType;
 };
 
 class BasicBlockItem : public Item
 {
 protected:
-    bool transparent;
-    bool passable;
-    float hp;
-    float maxHP;
-    float hardness;
-    int toolId;
-    float speedModifier;
-    bool interactable;
+	bool transparent;
+	bool passable;
+	float hp;
+	float maxHP;
+	float hardness;
+	int toolId;
+	float speedModifier;
+	bool interactable;
 
 public:
-    BasicBlockItem( const ItemType* zType, const BlockType* zPlacedBlockType, const char* name );
-    virtual bool canBeStackedWith( Item* zItem ) const override;
+	BasicBlockItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name);
+	virtual bool canBeStackedWith(Item* zItem) const override;
 
-    friend BasicBlockItemType;
-    friend BlockType;
+	friend BasicBlockItemType;
+	friend BlockType;
 };
 
 class BasicBlockItemType : public ItemType
 {
 protected:
-    BasicBlockItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType );
-    virtual void loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const override;
-    virtual void saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const override;
-    void initializeItem( BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier ) const;
+	BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType);
+	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const override;
+	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const override;
+	void initializeItem(BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier) const;
 };

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -141,6 +141,7 @@
     <ClInclude Include="Server.h" />
     <ClInclude Include="Dimension.h" />
     <ClInclude Include="StaticRegistry.h" />
+    <ClInclude Include="StoneTool.h" />
     <ClInclude Include="TickOrganizer.h" />
     <ClInclude Include="TickQueue.h" />
     <ClInclude Include="TickWorker.h" />
@@ -195,6 +196,7 @@
     <ClCompile Include="Server.cpp" />
     <ClCompile Include="Start.cpp" />
     <ClCompile Include="StaticInitializerOrder.cpp" />
+    <ClCompile Include="StoneTool.cpp" />
     <ClCompile Include="TickOrganizer.cpp" />
     <ClCompile Include="TickQueue.cpp" />
     <ClCompile Include="TickWorker.cpp" />

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -234,6 +234,9 @@
     <ClInclude Include="RecipieLoader.h">
       <Filter>inventory\recipies</Filter>
     </ClInclude>
+    <ClInclude Include="StoneTool.h">
+      <Filter>inventory\items</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -392,5 +395,8 @@
     <ClCompile Include="CraftingStorage.cpp">
       <Filter>inventory\recipies</Filter>
     </ClCompile>
+    <ClCompile Include="StoneTool.cpp">
+      <Filter>inventory\items</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 36 - 35
FactoryCraft/Item.h

@@ -5,48 +5,49 @@
 
 class ItemType;
 class BlockType;
+class StoneToolItemType;
 
 class Item : public virtual Framework::ReferenceCounter
 {
 protected:
-    const ItemType* zType;
-    const BlockType* zBlockType;
-    float damage;
-    float maxDamage;
-    float durability;
-    float maxDurability;
-    bool eatable;
-    bool placeable;
-    bool equippable;
-    bool solid;
-    bool usable;
-    int maxStackSize;
-    Framework::Text name;
-    Item( const ItemType* zType, const char* name );
+	const ItemType* zType;
+	const BlockType* zBlockType;
+	float damage;
+	float maxDamage;
+	float durability;
+	float maxDurability;
+	bool eatable;
+	bool placeable;
+	bool equippable;
+	bool solid;
+	bool usable;
+	int maxStackSize;
+	Framework::Text name;
+	Item(const ItemType* zType, const char* name);
 
 public:
-    virtual void tick();
+	virtual void tick();
 
-    const ItemType* zItemType() const;
-    const BlockType* zPlacedBlockType() const;
-    float getDamage() const;
-    float getDurability() const;
-    bool isUsable() const;
-    bool isEatable() const;
-    bool isPlaceable() const;
-    bool isEquippable() const;
-    bool isSolid() const;
-    float getMaxDurability() const;
-    int getMaxStackSize() const;
-    float getMaxDamage() const;
-    virtual bool canBeStackedWith( Item* zItem ) const;
-    virtual void onPlaced();
+	const ItemType* zItemType() const;
+	const BlockType* zPlacedBlockType() const;
+	float getDamage() const;
+	float getDurability() const;
+	bool isUsable() const;
+	bool isEatable() const;
+	bool isPlaceable() const;
+	bool isEquippable() const;
+	bool isSolid() const;
+	float getMaxDurability() const;
+	int getMaxStackSize() const;
+	float getMaxDamage() const;
+	virtual bool canBeStackedWith(Item* zItem) const;
+	virtual void onPlaced();
 
-    virtual void applyInventoryEffects( Entity* zTarget );
-    virtual void removeInventoryEffects( Entity* zTarget );
-    virtual void applyEquippedEffects( Entity* zTarget );
-    virtual void removeEquippedEffects( Entity* zTarget );
-    virtual void applyFoodEffects( Entity* zTarget );
+	virtual void applyInventoryEffects(Entity* zTarget);
+	virtual void removeInventoryEffects(Entity* zTarget);
+	virtual void applyEquippedEffects(Entity* zTarget);
+	virtual void removeEquippedEffects(Entity* zTarget);
+	virtual void applyFoodEffects(Entity* zTarget);
 
-    friend ItemType;
+	friend ItemType;
 };

+ 89 - 67
FactoryCraft/ItemType.cpp

@@ -5,126 +5,148 @@
 #include "ItemSkill.h"
 #include "ItemStack.h"
 
-ItemType::ItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType )
-    : ReferenceCounter(),
-    id( id ),
-    levelUpRule( levelUpRule ),
-    zBrokenType( zBrokenType )
+ItemType::ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType)
+	: ReferenceCounter(),
+	id(id),
+	name(name),
+	levelUpRule(levelUpRule),
+	zBrokenType(zBrokenType)
 {
-    StaticRegistry<ItemType>::INSTANCE.registerT( this, id );
+	StaticRegistry<ItemType>::INSTANCE.registerT(this, id);
 }
 
 ItemType::~ItemType()
 {
-    if( levelUpRule )
-        levelUpRule->release();
+	if (levelUpRule)
+		levelUpRule->release();
 }
 
-void ItemType::loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const
+void ItemType::loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const
 {
-    zReader->lese( (char*)&zItem->damage, 4 );
-    zReader->lese( (char*)&zItem->maxDamage, 4 );
-    zReader->lese( (char*)&zItem->durability, 4 );
-    zReader->lese( (char*)&zItem->maxDurability, 4 );
-    unsigned char flags = 0;
-    zReader->lese( (char*)&flags, 1 );
-    zItem->eatable = (flags | 1) == flags;
-    zItem->placeable = (flags | 2) == flags;
-    zItem->equippable = (flags | 4) == flags;
-    zItem->solid = (flags | 8) == flags;
-    zItem->usable = (flags | 16) == flags;
-    zReader->lese( (char*)&zItem->maxStackSize, 1 );
-    unsigned char len = 0;
-    zReader->lese( (char*)&len, 1 );
-    zItem->name.fillText( ' ', len );
-    zReader->lese( zItem->name, len );
+	zReader->lese((char*)&zItem->damage, 4);
+	zReader->lese((char*)&zItem->maxDamage, 4);
+	zReader->lese((char*)&zItem->durability, 4);
+	zReader->lese((char*)&zItem->maxDurability, 4);
+	unsigned char flags = 0;
+	zReader->lese((char*)&flags, 1);
+	zItem->eatable = (flags | 1) == flags;
+	zItem->placeable = (flags | 2) == flags;
+	zItem->equippable = (flags | 4) == flags;
+	zItem->solid = (flags | 8) == flags;
+	zItem->usable = (flags | 16) == flags;
+	zReader->lese((char*)&zItem->maxStackSize, 1);
+	unsigned char len = 0;
+	zReader->lese((char*)&len, 1);
+	zItem->name.fillText(' ', len);
+	zReader->lese(zItem->name, len);
 }
 
-void ItemType::saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
+void ItemType::saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const
 {
-    zWriter->schreibe( (char*)&zItem->damage, 4 );
-    zWriter->schreibe( (char*)&zItem->maxDamage, 4 );
-    zWriter->schreibe( (char*)&zItem->durability, 4 );
-    zWriter->schreibe( (char*)&zItem->maxDurability, 4 );
-    unsigned char flags = (unsigned char)(((((zItem->usable << 1) | zItem->solid << 1) | zItem->equippable << 1) | zItem->placeable << 1) | zItem->eatable);
-    zWriter->schreibe( (char*)&flags, 1 );
-    zWriter->schreibe( (char*)&zItem->maxStackSize, 1 );
-    unsigned char len = (unsigned char)zItem->name.getLength();
-    zWriter->schreibe( (char*)&len, 1 );
-    zWriter->schreibe( zItem->name, len );
+	zWriter->schreibe((char*)&zItem->damage, 4);
+	zWriter->schreibe((char*)&zItem->maxDamage, 4);
+	zWriter->schreibe((char*)&zItem->durability, 4);
+	zWriter->schreibe((char*)&zItem->maxDurability, 4);
+	unsigned char flags = (unsigned char)(((((zItem->usable << 1) | zItem->solid << 1) | zItem->equippable << 1) | zItem->placeable << 1) | zItem->eatable);
+	zWriter->schreibe((char*)&flags, 1);
+	zWriter->schreibe((char*)&zItem->maxStackSize, 1);
+	unsigned char len = (unsigned char)zItem->name.getLength();
+	zWriter->schreibe((char*)&len, 1);
+	zWriter->schreibe(zItem->name, len);
 }
 
-void ItemType::loadSuperItemSkill( ItemSkill* zSkill, Framework::StreamReader* zReader ) const
+void ItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
 {
 
 }
 
-void ItemType::saveSuperItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const
+void ItemType::saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
 
 }
 
+Item* ItemType::createBasicItem(const char* name, float damage, float maxDamage, float durability, float maxDurability, bool eatable, bool placeable, bool equippable, bool solid, bool usable, int maxStackSize) const
+{
+	Item* item = new Item(this, name);
+	item->damage = damage;
+	item->maxDamage = maxDamage;
+	item->durability = durability;
+	item->maxDurability = maxDurability;
+	item->eatable = eatable;
+	item->placeable = placeable;
+	item->equippable = equippable;
+	item->solid = solid;
+	item->usable = usable;
+	item->maxStackSize = maxStackSize;
+	return item;
+}
+
 int ItemType::getId() const
 {
-    return id;
+	return id;
+}
+
+const Framework::Text& ItemType::getName() const
+{
+	return name;
 }
 
 const ItemType* ItemType::zBrokenItemType() const
 {
-    return zBrokenType;
+	return zBrokenType;
 }
 
-ItemStack* ItemType::createItemStack( int size ) const
+ItemStack* ItemType::createItemStack(int size) const
 {
-    Item* item = createItem();
-    if( !item )
-        return 0;
-    return new ItemStack( item, MIN( size, item->getMaxStackSize() ) );
+	Item* item = createItem();
+	if (!item)
+		return 0;
+	return new ItemStack(item, MIN(size, item->getMaxStackSize()));
 }
 
 ItemSkill* ItemType::createDefaultItemSkill() const
 {
-    return 0;
+	return 0;
 }
 
-void ItemType::levelUpItemSkill( ItemSkill* zSkill ) const
+void ItemType::levelUpItemSkill(ItemSkill* zSkill) const
 {
-    if( levelUpRule )
-        levelUpRule->applyOn( zSkill );
+	if (levelUpRule)
+		levelUpRule->applyOn(zSkill);
 }
 
-Item* ItemType::loadItem( Framework::StreamReader* zReader ) const
+Item* ItemType::loadItem(Framework::StreamReader* zReader) const
 {
-    Item* item = createItem();
-    loadSuperItem( item, zReader );
-    return item;
+	Item* item = createItem();
+	loadSuperItem(item, zReader);
+	return item;
 }
 
-void ItemType::saveItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
+void ItemType::saveItem(const Item* zItem, Framework::StreamWriter* zWriter) const
 {
-    saveSuperItem( zItem, zWriter );
+	saveSuperItem(zItem, zWriter);
 }
 
-Item* ItemType::cloneItem( Item* zItem ) const
+Item* ItemType::cloneItem(Item* zItem) const
 {
-    Framework::InMemoryBuffer buffer;
-    saveItem( zItem, &buffer );
-    return loadItem( &buffer );
+	Framework::InMemoryBuffer buffer;
+	saveItem(zItem, &buffer);
+	return loadItem(&buffer);
 }
 
-ItemSkill* ItemType::loadItemSkill( Framework::StreamReader* zReader ) const
+ItemSkill* ItemType::loadItemSkill(Framework::StreamReader* zReader) const
 {
-    ItemSkill* skill = createDefaultItemSkill();
-    loadSuperItemSkill( skill, zReader );
-    return skill;
+	ItemSkill* skill = createDefaultItemSkill();
+	loadSuperItemSkill(skill, zReader);
+	return skill;
 }
 
-void ItemType::saveItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const
+void ItemType::saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
-    saveSuperItemSkill( zSkill, zWriter );
+	saveSuperItemSkill(zSkill, zWriter);
 }
 
-Item* ItemType::breakItem( Item* zItem ) const
+Item* ItemType::breakItem(Item* zItem) const
 {
-    return 0;
+	return 0;
 }

+ 25 - 22
FactoryCraft/ItemType.h

@@ -16,30 +16,33 @@ class ItemSkillLevelUpRule;
 class ItemType : public virtual Framework::ReferenceCounter
 {
 protected:
-    const int id;
-    ItemSkillLevelUpRule* levelUpRule;
-    const ItemType* zBrokenType;
+	const int id;
+	const Framework::Text name;
+	ItemSkillLevelUpRule* levelUpRule;
+	const ItemType* zBrokenType;
 
-    ItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType );
+	ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType);
 
-    virtual void loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const;
-    virtual void saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const;
-    virtual void loadSuperItemSkill( ItemSkill* zSkill, Framework::StreamReader* zReader ) const;
-    virtual void saveSuperItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const;
+	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const;
+	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const;
+	virtual void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const;
+	virtual void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
+	Item* createBasicItem(const char* name, float damage, float maxDamage, float durability, float maxDurability, bool eatable, bool placeable, bool equippable, bool solid, bool usable, int maxStackSize) const;
 
 public:
-    ~ItemType();
-
-    int getId() const;
-    const ItemType* zBrokenItemType() const;
-    virtual Item* createItem() const = 0;
-    virtual ItemStack* createItemStack( int size ) const;
-    virtual ItemSkill* createDefaultItemSkill() const;
-    virtual void levelUpItemSkill( ItemSkill* zSkill ) const;
-    virtual Item* loadItem( Framework::StreamReader* zReader ) const;
-    virtual void saveItem( const Item* zItem, Framework::StreamWriter* zWriter ) const;
-    virtual ItemSkill* loadItemSkill( Framework::StreamReader* zReader ) const;
-    virtual void saveItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const;
-    virtual Item* cloneItem( Item* zItem ) const;
-    virtual Item* breakItem( Item* zItem ) const;
+	~ItemType();
+
+	int getId() const;
+	const Framework::Text& getName() const;
+	const ItemType* zBrokenItemType() const;
+	virtual Item* createItem() const = 0;
+	virtual ItemStack* createItemStack(int size) const;
+	virtual ItemSkill* createDefaultItemSkill() const;
+	virtual void levelUpItemSkill(ItemSkill* zSkill) const;
+	virtual Item* loadItem(Framework::StreamReader* zReader) const;
+	virtual void saveItem(const Item* zItem, Framework::StreamWriter* zWriter) const;
+	virtual ItemSkill* loadItemSkill(Framework::StreamReader* zReader) const;
+	virtual void saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
+	virtual Item* cloneItem(Item* zItem) const;
+	virtual Item* breakItem(Item* zItem) const;
 };

+ 18 - 19
FactoryCraft/PlayerHand.cpp

@@ -3,54 +3,53 @@
 
 
 PlayerHandItemType::PlayerHandItemType()
-    : ItemType( ID, new PlayerHandLevelUpRule(), 0 )
+	: ItemType(ID, "PlayerHand", new PlayerHandLevelUpRule(), 0)
 {}
 
-void PlayerHandItemType::loadSuperItemSkill( ItemSkill* zSkill, Framework::StreamReader* zReader ) const
+void PlayerHandItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
 {
-    // TODO: load skill data
+	// TODO: load skill data
 }
 
-void PlayerHandItemType::saveSuperItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const
+void PlayerHandItemType::saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
-    // TODO: store skill data
+	// TODO: store skill data
 }
 
 Item* PlayerHandItemType::createItem() const
 {
-    return 0; // there is no player hand item
+	return 0; // there is no player hand item
 }
 
 ItemSkill* PlayerHandItemType::createDefaultItemSkill() const
 {
-    return new PlayerHandSkill();
+	return new PlayerHandSkill();
 }
 
 
 PlayerHandLevelUpRule::PlayerHandLevelUpRule()
-    : ItemSkillLevelUpRule()
+	: ItemSkillLevelUpRule()
 {}
 
-void PlayerHandLevelUpRule::applyOn( ItemSkill* zSkill )
+void PlayerHandLevelUpRule::applyOn(ItemSkill* zSkill)
 {
-    // TODO: level up the skill
+	// TODO: level up the skill
 }
 
 
 PlayerHandSkill::PlayerHandSkill()
-    : ItemSkill( PlayerHandItemType::INSTANCE )
+	: ItemSkill(PlayerHandItemType::INSTANCE)
 {}
 
-void PlayerHandSkill::use( Entity* zActor, Item* zUsedItem, Block* zTarget )
+void PlayerHandSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
 {
-    if( zTarget && zTarget->getHardness() <= 1 )
-    {
-        zTarget->setHP( zTarget->getHP() - 1 / (zTarget->getHardness() + 1) );
-    }
-    // TODO: make damage on the block
+	if (zTarget && zTarget->getHardness() <= 1)
+	{
+		zTarget->setHP(zTarget->getHP() - 1 / (zTarget->getHardness() + 1));
+	}
 }
 
-void PlayerHandSkill::use( Entity* zActor, Item* zUsedItem, Entity* zTarget )
+void PlayerHandSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
 {
-    // TODO: make damage on the entity
+	// TODO: make damage on the entity
 }

+ 191 - 45
FactoryCraft/RecipieLoader.cpp

@@ -3,66 +3,212 @@
 #include <iostream>
 #include "RecipieLoader.h"
 
+using namespace Framework::JSON;
+using namespace Validator;
 
 RecipieLoader::RecipieLoader()
-    : Framework::ReferenceCounter()
+	: Framework::ReferenceCounter(),
+	validator(0)
 {}
 
-void RecipieLoader::loadRecipies( const char* path )
+RecipieLoader::~RecipieLoader()
 {
-    std::cout << "loading recipies from '" << path << "'" << std::endl;
-    Framework::Datei d;
-    d.setDatei( path );
-    if( d.istOrdner() )
-    {
-        Framework::RCArray<Framework::Text>* files = d.getDateiListe();
-        for( Framework::Text* f : *files )
-            loadRecipies( Framework::Text( path ) + "/" + *f );
-        files->release();
-    }
-    else
-    {
-        Framework::JSON::JSONValue* json = Framework::JSON::loadJSONFromFile( path );
-        if( json->getType() == Framework::JSON::JSONType::ARRAY )
-        {
-            // TODO: parse the json recipies
-        }
-        else
-            std::cout << "could not load recipie file '" << path << "' because it does not contain a valid json array of recipies" << std::endl;
-        json->release();
-    }
+	if (validator)
+		validator->release();
 }
 
-RecipieList* RecipieLoader::zRecipieList( const char* name )
+void RecipieLoader::loadRecipies(const char* path)
 {
-    for( RecipieList* l : lists )
-    {
-        if( l->getName().istGleich( name ) )
-            return l;
-    }
-    return 0;
+	shapedLists.leeren();
+	lists.leeren();
+	std::cout << "loading recipies from '" << path << "'" << std::endl;
+	Framework::Datei d;
+	d.setDatei(path);
+	if (d.istOrdner())
+	{
+		Framework::RCArray<Framework::Text>* files = d.getDateiListe();
+		for (Framework::Text* f : *files)
+			loadRecipies(Framework::Text(path) + "/" + *f);
+		files->release();
+	}
+	else
+	{
+		JSONValue* json = loadJSONFromFile(path);
+		JSONValidator* validator = zRecipieValidator();
+		JSONValue* valid = validator->getValidParts(json);
+		json->release();
+		if (valid)
+		{
+			for (JSONValue* recipie : *valid->asArray())
+				loadRecipie(recipie->asObject());
+			valid->release();
+		}
+	}
 }
 
-ShapedRecipieList* RecipieLoader::zShapedRecipieList( const char* name )
+void RecipieLoader::loadRecipie(JSONObject* zRecipie)
 {
-    for( ShapedRecipieList* l : shapedLists )
-    {
-        if( l->getName().istGleich( name ) )
-            return l;
-    }
-    return 0;
+	Framework::Text group = zRecipie->zValue("group")->asString()->getString();
+	if (zRecipie->zValue("type")->asString()->getString().istGleich("shaped"))
+	{
+		int width = (int)zRecipie->zValue("width")->asNumber()->getNumber();
+		int height = (int)zRecipie->zValue("height")->asNumber()->getNumber();
+		ShapedRecipie* recipie = new ShapedRecipie(width, height);
+		for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
+		{
+			int x = (int)input->asObject()->zValue("x")->asNumber()->getNumber();
+			int y = (int)input->asObject()->zValue("y")->asNumber()->getNumber();
+			ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject());
+			recipie->setIngredient(x, y, filter);
+		}
+		int outputCount = (int)zRecipie->asObject()->zValue("outputCount")->asNumber()->getNumber();
+		Framework::Text outputType = zRecipie->asObject()->zValue("output")->asObject()->zValue("itemType")->asString()->getString();
+		Item* item = 0;
+		for (ItemType& t : StaticRegistry<ItemType>::INSTANCE)
+		{
+			if (t.getName().istGleich(outputType))
+			{
+				item = t.createItem();
+				break;
+			}
+		}
+		recipie->setOutput(item, outputCount);
+		if (!zShapedRecipieList(group))
+			registerShapedRecipieList(group);
+		zShapedRecipieList(group)->addRecipie(recipie);
+	}
+	else if (zRecipie->zValue("type")->asString()->getString().istGleich("unordered"))
+	{
+		Recipie* recipie = new Recipie();
+		for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
+		{
+			int count = (int)input->asObject()->zValue("count")->asNumber()->getNumber();
+			ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject());
+			recipie->addIngredient(filter, count);
+		}
+		for (JSONValue* output : *zRecipie->zValue("outputs")->asArray())
+		{
+			int count = (int)output->asObject()->zValue("count")->asNumber()->getNumber();
+			Framework::Text outputType = output->asObject()->zValue("item")->asObject()->zValue("itemType")->asString()->getString();
+			Item* item = 0;
+			for (ItemType& t : StaticRegistry<ItemType>::INSTANCE)
+			{
+				if (t.getName().istGleich(outputType))
+				{
+					item = t.createItem();
+					break;
+				}
+			}
+			recipie->addOutput(item, count);
+		}
+		if (!zRecipieList(group))
+			registerRecipieList(group);
+		zRecipieList(group)->addRecipie(recipie);
+	}
 }
 
-void RecipieLoader::registerRecipieList( const char* name )
+ItemFilter* RecipieLoader::loadFilter(JSONObject* zFilter)
 {
-    if( zRecipieList( name ) )
-        throw new std::invalid_argument( "the recipie list already exists" );
-    lists.add( new RecipieList( name ) );
+	Framework::Text type = zFilter->zValue("itemType")->asString()->getString();
+	for (const ItemType& t : StaticRegistry<ItemType>::INSTANCE)
+	{
+		if (t.getName().istGleich(type))
+			return new TypeItemFilter(&t);
+	}
+	return 0;
 }
 
-void RecipieLoader::registerShapedRecipieList( const char* name )
+RecipieList* RecipieLoader::zRecipieList(const char* name)
 {
-    if( zShapedRecipieList( name ) )
-        throw new std::invalid_argument( "the recipie list already exists" );
-    shapedLists.add( new ShapedRecipieList( name ) );
+	for (RecipieList* l : lists)
+	{
+		if (l->getName().istGleich(name))
+			return l;
+	}
+	return 0;
+}
+
+ShapedRecipieList* RecipieLoader::zShapedRecipieList(const char* name)
+{
+	for (ShapedRecipieList* l : shapedLists)
+	{
+		if (l->getName().istGleich(name))
+			return l;
+	}
+	return 0;
+}
+
+void RecipieLoader::registerRecipieList(const char* name)
+{
+	if (zRecipieList(name))
+		throw new std::invalid_argument("the recipie list already exists");
+	lists.add(new RecipieList(name));
+}
+
+void RecipieLoader::registerShapedRecipieList(const char* name)
+{
+	if (zShapedRecipieList(name))
+		throw new std::invalid_argument("the recipie list already exists");
+	shapedLists.add(new ShapedRecipieList(name));
+}
+
+JSONValidator* RecipieLoader::zRecipieValidator()
+{
+	if (validator)
+		return validator;
+	Framework::RCArray<Framework::Text> itemTypes;
+	for (ItemType& t : StaticRegistry<ItemType>::INSTANCE)
+		itemTypes.add(new Framework::Text(t.getName().getText()));
+	JSONValidator* filterValidator = JSONValidator::buildForObject()
+		->withRequiredString("itemType")->whichIsOneOf(itemTypes)->finishString()
+		->finishObject();
+	JSONValidator* outputValidator = JSONValidator::buildForObject()
+		->withRequiredString("itemType")->whichIsOneOf(itemTypes)->finishString()
+		->finishObject();
+	validator = JSONValidator::buildForArray()
+		->typeSpecifiedByAttribute("type")
+		->removeInvalidEntries()
+		->addAcceptedTypeInArray(
+			JSONValidator::buildForObject()
+			->withRequiredString("type")->withExactMatch("shaped")->finishString()
+			->withRequiredString("group")->finishString()
+			->withRequiredNumber("width")->whichIsGreaterThen(0)->finishNumber()
+			->withRequiredNumber("height")->whichIsGreaterThen(0)->finishNumber()
+			->withRequiredAttribute("inputs",
+				JSONValidator::buildForArray()
+				->withDefault(new JSONArray())
+				->addAcceptedTypeInArray(JSONValidator::buildForObject()
+					->withRequiredNumber("x")->whichIsGreaterOrEqual(0)->finishNumber()
+					->withRequiredNumber("y")->whichIsGreaterOrEqual(0)->finishNumber()
+					->withRequiredAttribute("filter", dynamic_cast<JSONValidator*>(filterValidator->getThis()))
+					->finishObject())
+				->finishArray())
+			->withRequiredAttribute("output", dynamic_cast<JSONValidator*>(outputValidator->getThis()))
+			->withRequiredNumber("outputCount")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
+			->finishObject())
+		->addAcceptedTypeInArray(
+			JSONValidator::buildForObject()
+			->withRequiredString("type")->withExactMatch("unordered")->finishString()
+			->withRequiredString("group")->finishString()
+			->withRequiredAttribute("inputs",
+				JSONValidator::buildForArray()
+				->withDefault(new JSONArray())
+				->addAcceptedTypeInArray(
+					JSONValidator::buildForObject()
+					->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
+					->withRequiredAttribute("filter", dynamic_cast<JSONValidator*>(filterValidator->getThis()))
+					->finishObject())
+				->finishArray())
+			->withRequiredAttribute("output",
+				JSONValidator::buildForArray()
+				->addAcceptedTypeInArray(JSONValidator::buildForObject()
+					->withRequiredAttribute("item", dynamic_cast<JSONValidator*>(outputValidator->getThis()))
+					->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
+					->finishObject())
+				->finishArray())
+			->finishObject())
+		->finishArray();
+	filterValidator->release();
+	outputValidator->release();
+	return validator;
 }

+ 15 - 8
FactoryCraft/RecipieLoader.h

@@ -5,14 +5,21 @@
 class RecipieLoader : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<RecipieList> lists;
-    Framework::RCArray<ShapedRecipieList> shapedLists;
+	Framework::RCArray<RecipieList> lists;
+	Framework::RCArray<ShapedRecipieList> shapedLists;
+	Framework::JSON::Validator::JSONValidator* validator;
 
 public:
-    RecipieLoader();
-    void loadRecipies( const char* path );
-    RecipieList* zRecipieList( const char* name );
-    ShapedRecipieList* zShapedRecipieList( const char* name );
-    void registerRecipieList( const char* name );
-    void registerShapedRecipieList( const char* name );
+	RecipieLoader();
+	~RecipieLoader();
+	void loadRecipies(const char* path);
+	RecipieList* zRecipieList(const char* name);
+	ShapedRecipieList* zShapedRecipieList(const char* name);
+	void registerRecipieList(const char* name);
+	void registerShapedRecipieList(const char* name);
+
+private:
+	void loadRecipie(Framework::JSON::JSONObject* zRecipie);
+	ItemFilter* loadFilter(Framework::JSON::JSONObject* zFilter);
+	Framework::JSON::Validator::JSONValidator* zRecipieValidator();
 };

+ 6 - 4
FactoryCraft/StaticInitializerOrder.cpp

@@ -9,12 +9,13 @@ int count_WorldUpdateType = 0;
 int count_EntityType = 0;
 
 #undef REGISTER
-#define REGISTER(c, typ)               \
-const int c::ID = count_##typ++;       \
-const c *c::INSTANCE = new c(); 
+#define REGISTER(c, typ)																\
+const int c::ID = count_##typ++;														\
+int registry_initializer_##c##_##typ = StaticRegistry<typ>::INSTANCE.getCount();        \
+const c *c::INSTANCE = new c();															\
+bool initialized_##c##_##typ = StaticRegistry<typ>::INSTANCE.info(c::ID);
 
 // order of includes determines the ids
-
 // block types
 #include "NoBlock.h" // must be first
 #include "BasicBlocks.h"
@@ -25,6 +26,7 @@ const c *c::INSTANCE = new c();
 #include "ItemEntity.h"
 // item skills
 #include "PlayerHand.h"
+#include "StoneTool.h"
 // world updates
 #include "AddChunkUpdate.h"
 #include "PlaceBlockUpdate.h"

+ 70 - 52
FactoryCraft/StaticRegistry.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <iostream>
+
 #define REGISTRABLE( c )          \
 public:                           \
     static const c *INSTANCE;     \
@@ -14,60 +16,76 @@ template<typename T>
 class StaticRegistry
 {
 public:
-    static StaticRegistry<T> INSTANCE;
+	static StaticRegistry<T> INSTANCE;
 
 private:
-    T** registry;
-    int count;
-
-    StaticRegistry()
-    {
-        count = 100;
-        registry = new T * [ count ];
-        memset( registry, 0, sizeof( T* ) * count );
-    }
-
-    ~StaticRegistry()
-    {
-        for( int index = 0; index < count; index++ )
-        {
-            if( registry[ index ] )
-            {
-                registry[ index ]->release();
-                registry[ index ] = 0;
-            }
-        }
-        delete[]registry;
-    }
-
-    void registerT( T* type, int id )
-    {
-        if( id >= count )
-        {
-            T** temp = new T * [ id + 1 ];
-            memcpy( temp, registry, sizeof( T* ) * count );
-            memset( temp + count, 0, sizeof( T* ) * (id + 1 - count) );
-            delete[]registry;
-            registry = temp;
-            count = id + 1;
-        }
-        registry[ id ] = type;
-    }
+	T** registry;
+	int count;
+
+	StaticRegistry()
+	{
+		count = 0;
+		registry = new T * [count];
+		memset(registry, 0, sizeof(T*) * count);
+	}
+
+	~StaticRegistry()
+	{
+		for (int index = 0; index < count; index++)
+		{
+			if (registry[index])
+			{
+				registry[index]->release();
+				registry[index] = 0;
+			}
+		}
+		delete[]registry;
+	}
+
+	void registerT(T* type, int id)
+	{
+		if (id >= count)
+		{
+			T** temp = new T * [id + 1];
+			memcpy(temp, registry, sizeof(T*) * count);
+			memset(temp + count, 0, sizeof(T*) * (id + 1 - count));
+			delete[]registry;
+			registry = temp;
+			count = id + 1;
+		}
+		registry[id] = type;
+	}
 
 public:
-    T* zElement( int id )
-    {
-        if( id < 0 || id >= count )
-            return 0;
-        return registry[ id ];
-    }
-
-    int getCount() const
-    {
-        return count;
-    }
-
-    friend T;
+	T* zElement(int id)
+	{
+		if (id < 0 || id >= count)
+			return 0;
+		return registry[id];
+	}
+
+	int getCount() const
+	{
+		return count;
+	}
+
+	bool info(int id)
+	{
+		std::cout << typeid(*registry[id]).name() << " was registered as " << typeid(T).name() << " with id " << id << std::endl;
+		return 1;
+	}
+
+	T* begin() const
+	{
+		return *registry;
+	}
+
+	T* end() const
+	{
+		return *(registry + count);
+	}
+
+	friend T;
 };
 
 template <typename T>
@@ -76,6 +94,6 @@ StaticRegistry<T> StaticRegistry<T>::INSTANCE;
 
 enum class StreamTarget
 {
-    FULL,
-    CLIENT
+	FULL,
+	CLIENT
 };

+ 89 - 0
FactoryCraft/StoneTool.cpp

@@ -0,0 +1,89 @@
+#include "StoneTool.h"
+#include "Block.h"
+
+
+BrokenStoneToolItemType::BrokenStoneToolItemType()
+	: ItemType(ID, "BrokenStoneTool", 0, 0)
+{}
+
+Item* BrokenStoneToolItemType::createItem() const
+{
+	return createBasicItem("Stone Tool", 0.f, 0.f, 0.f, 0.f, 0, 0, 0, 1, 0, 10);
+}
+
+
+StoneToolItemType::StoneToolItemType()
+	: ItemType(ID, "StoneTool", new StoneToolLevelUpRule(), BrokenStoneToolItemType::INSTANCE)
+{}
+
+void StoneToolItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
+{
+	StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
+	if (!skill)
+		throw "StoneToolItemType::loadSuperItemSkill was called with an invalid skill";
+	zReader->lese((char*)&skill->level, 4);
+	zReader->lese((char*)&skill->xp, 4);
+	zReader->lese((char*)&skill->maxXP, 4);
+}
+
+void StoneToolItemType::saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
+{
+	const StoneToolSkill* skill = dynamic_cast<const StoneToolSkill*>(zSkill);
+	if (!skill)
+		throw "StoneToolItemType::saveSuperItemSkill was called with an invalid skill";
+	zWriter->schreibe((char*)&skill->level, 4);
+	zWriter->schreibe((char*)&skill->xp, 4);
+	zWriter->schreibe((char*)&skill->maxXP, 4);
+}
+
+Item* StoneToolItemType::createItem() const
+{
+	return createBasicItem("Stone Tool", 0.f, 0.f, 10.f, 10.f, 0, 0, 0, 1, 1, 1);
+}
+
+ItemSkill* StoneToolItemType::createDefaultItemSkill() const
+{
+	return new StoneToolSkill();
+}
+
+
+StoneToolLevelUpRule::StoneToolLevelUpRule()
+	: ItemSkillLevelUpRule()
+{}
+
+void StoneToolLevelUpRule::applyOn(ItemSkill* zSkill)
+{
+	StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
+	if (!skill)
+		throw "StoneToolLevelUpRule::applyOn was called with an invalid skill";
+	if (skill->xp >= skill->maxXP)
+	{
+		skill->level++;
+		skill->xp = 0;
+		skill->maxXP = skill->maxXP * 1.5f;
+	}
+}
+
+
+StoneToolSkill::StoneToolSkill()
+	: ItemSkill(StoneToolItemType::INSTANCE)
+{
+	level = 1;
+	xp = 0;
+	maxXP = 10;
+}
+
+void StoneToolSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
+{
+	if (zTarget && zTarget->getHardness() <= 2)
+	{
+		float damage = (1 + ((float)level / 10.f)) / (zTarget->getHardness() + 1);
+		zTarget->setHP(zTarget->getHP() - damage);
+		xp += damage / 20;
+	}
+}
+
+void StoneToolSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
+{
+	// TODO
+}

+ 54 - 0
FactoryCraft/StoneTool.h

@@ -0,0 +1,54 @@
+#pragma once
+
+#include "ItemType.h"
+#include "ItemSkill.h"
+
+class BrokenStoneToolItemType : public ItemType
+{
+	REGISTRABLE(BrokenStoneToolItemType)
+
+protected:
+	BrokenStoneToolItemType();
+
+public:
+	Item* createItem() const override;
+};
+REGISTER(BrokenStoneToolItemType, ItemType)
+
+class StoneToolItemType : public ItemType
+{
+	REGISTRABLE(StoneToolItemType)
+
+protected:
+	StoneToolItemType();
+	void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
+	void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const override;
+
+public:
+	Item* createItem() const override;
+	ItemSkill* createDefaultItemSkill() const override;
+};
+REGISTER(StoneToolItemType, ItemType)
+
+class StoneToolLevelUpRule : public ItemSkillLevelUpRule
+{
+public:
+	StoneToolLevelUpRule();
+	void applyOn(ItemSkill* zSkill) override;
+};
+
+class StoneToolSkill : public ItemSkill
+{
+private:
+	int level;
+	float xp;
+	float maxXP;
+
+public:
+	StoneToolSkill();
+	void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
+	void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+
+	friend StoneToolItemType;
+	friend StoneToolLevelUpRule;
+};