Browse Source

add item bar to ingame gui and synchronize target via api

Kolja Strohm 2 năm trước cách đây
mục cha
commit
ad1b9e0f2f

+ 3 - 3
FactoryCraft/Block.cpp

@@ -119,7 +119,7 @@ void Block::setDimensionId(int id)
 	dimensionId = id;
 }
 
-void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
 	// TODO: answer api requests
 }
@@ -216,13 +216,13 @@ void Block::setHP(float hp)
 	}
 	else
 	{
-		NetworkResponse changeMsg;
+		NetworkMessage changeMsg;
 		changeMsg.adressBlock(this);
 		char msg[5];
 		msg[0] = 0; // hp changed
 		*(float*)(msg + 1) = this->hp;
 		changeMsg.setMessage(msg, 5, 0);
-		Game::INSTANCE->distributeResponse(&changeMsg);
+		Game::INSTANCE->broadcastMessage(&changeMsg);
 	}
 }
 

+ 2 - 2
FactoryCraft/Block.h

@@ -4,7 +4,7 @@
 #include "ReferenceCounter.h"
 #include "Item.h"
 #include "Inventory.h"
-#include "NetworkResponse.h"
+#include "NetworkMessage.h"
 
 #include <Trie.h>
 #include <Vec3.h>
@@ -72,7 +72,7 @@ public:
 	virtual void setNeighbourBlock(Direction dir, Block* zN);
 	virtual void setNeighbourType(Direction dir, int type);
 
-	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
 
 	bool isTickSource() const;
 	const BlockType* zBlockType() const;

+ 1 - 1
FactoryCraft/BlockType.cpp

@@ -10,8 +10,8 @@ BlockType::BlockType(int id, Block* defaultBlock,
 	: ReferenceCounter(),
 	id(id),
 	model(model),
-	needsClientInstance(needsClientInstance),
 	initialMaxHP(initialMaxHP),
+	needsClientInstance(needsClientInstance),
 	defaultBlock(defaultBlock)
 {
 	StaticRegistry<BlockType>::INSTANCE.registerT(this, id);

+ 1 - 1
FactoryCraft/Chunk.cpp

@@ -52,7 +52,7 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(Framework::Vec3<int> locati
 	return 0;
 }
 
-void Chunk::api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void Chunk::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
 	// TODO: answer api messages
 }

+ 1 - 1
FactoryCraft/Chunk.h

@@ -27,7 +27,7 @@ public:
 	Chunk(Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader);
 	~Chunk();
 
-	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
 
 	Framework::Either<Block*, int> zBlockAt(Framework::Vec3<int> cLocation) const;
 	const Block* zBlockConst(Framework::Vec3<int> location) const;

+ 1 - 1
FactoryCraft/Dimension.cpp

@@ -19,7 +19,7 @@ Dimension::~Dimension()
 	chunks->release();
 }
 
-void Dimension::api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void Dimension::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
 	// TODO: switch type chunck, block
 }

+ 2 - 2
FactoryCraft/Dimension.h

@@ -4,7 +4,7 @@
 #include <Reader.h>
 
 #include "Chunk.h"
-#include "NetworkResponse.h"
+#include "NetworkMessage.h"
 
 class Dimension : public virtual Framework::ReferenceCounter
 {
@@ -21,7 +21,7 @@ public:
 	Dimension(int id);
 	~Dimension();
 
-	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
 	void tickEntities();
 
 	Framework::Either<Block*, int> zBlock(Framework::Vec3<int> location);

+ 42 - 7
FactoryCraft/Entity.cpp

@@ -55,6 +55,39 @@ void ActionTarget::placeBlock(Entity* zActor, Item* zItem)
 	}
 }
 
+void ActionTarget::toMessage(const ActionTarget* zTarget, NetworkMessage& msg)
+{
+	if (zTarget)
+	{
+		if (zTarget->entityId >= 0)
+		{
+			char* message = new char[6];
+			message[0] = 3;
+			message[1] = 1;
+			*(int*)(message + 2) = zTarget->entityId;
+			msg.setMessage(message, 6, 1);
+		}
+		else
+		{
+			char* message = new char[18];
+			message[0] = 3;
+			message[1] = 2;
+			*(int*)(message + 2) = zTarget->blockPos.x;
+			*(int*)(message + 6) = zTarget->blockPos.y;
+			*(int*)(message + 10) = zTarget->blockPos.z;
+			*(int*)(message + 14) = zTarget->targetBlockSide;
+			msg.setMessage(message, 18, 1);
+		}
+	}
+	else
+	{
+		char* message = new char[2];
+		message[0] = 3;
+		message[1] = 0;
+		msg.setMessage(message, 2, 1);
+	}
+}
+
 void ActionTarget::save(ActionTarget* zTarget, Framework::StreamWriter* zWriter)
 {
 	if (zTarget)
@@ -115,7 +148,6 @@ Entity::Entity(const EntityType* zType, Framework::Vec3<float> location, int dim
 	currentDimensionId(dimensionId),
 	removed(0),
 	gravityMultiplier(1.f),
-	needUpdate(0),
 	id(entityId)
 {}
 
@@ -159,6 +191,9 @@ void Entity::useItem(const ItemType* zType, Item* zItem)
 	}
 }
 
+void Entity::onTargetChange()
+{}
+
 void Entity::prepareTick(const Dimension* zDimension)
 {
 	Vec3<float> headPosition = location + faceOffset;
@@ -175,7 +210,7 @@ void Entity::prepareTick(const Dimension* zDimension)
 			{
 				delete target;
 				target = new ActionTarget({ px, py, pz }, dir);
-				needUpdate = 1;
+				onTargetChange();
 			}
 			break;
 		}
@@ -250,7 +285,7 @@ void Entity::prepareTick(const Dimension* zDimension)
 		{
 			delete target;
 			target = 0;
-			needUpdate = 1;
+			onTargetChange();
 		}
 		break;
 	}
@@ -378,9 +413,9 @@ void Entity::tick(const Dimension* zDimension)
 		}
 	}
 	location += frameSpeed;
-	if (oldPos != location || needUpdate)
+	if (oldPos != location)
 	{
-		NetworkResponse changeMsg;
+		NetworkMessage changeMsg;
 		changeMsg.adressEntity(this);
 		char msg[13];
 		msg[0] = 0; // position changed
@@ -388,11 +423,11 @@ void Entity::tick(const Dimension* zDimension)
 		*(float*)(msg + 5) = this->location.y;
 		*(float*)(msg + 9) = this->location.z;
 		changeMsg.setMessage(msg, 13, 0);
-		Game::INSTANCE->distributeResponse(&changeMsg);
+		Game::INSTANCE->broadcastMessage(&changeMsg);
 	}
 }
 
-void Entity::api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void Entity::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
 	char type;
 	zRequest->lese(&type, 1);

+ 4 - 3
FactoryCraft/Entity.h

@@ -7,7 +7,7 @@
 
 #include "Effect.h"
 #include "Inventory.h"
-#include "NetworkResponse.h"
+#include "NetworkMessage.h"
 #include "ItemSkill.h"
 
 
@@ -30,6 +30,7 @@ public:
 
 	void applyItemSkillOnTarget(Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem);
 	void placeBlock(Entity* zActor, Item* zItem);
+	static void toMessage(const ActionTarget* zTarget, NetworkMessage& msg);
 	static void save(ActionTarget* zTarget, Framework::StreamWriter* zWriter);
 	static ActionTarget* load(Framework::StreamReader* zReader);
 };
@@ -55,18 +56,18 @@ protected:
 	int currentDimensionId;
 	bool removed;
 	float gravityMultiplier;
-	bool needUpdate;
 	int id;
 
 	virtual void onDeath();
 	virtual void useItem(const ItemType* zType, Item* zItem);
 	Entity(const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId);
+	virtual void onTargetChange();
 
 public:
 	void prepareTick(const Dimension* zDimension);
 	virtual void tick(const Dimension* zDimension);
 
-	virtual void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	virtual void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
 
 	virtual void onFall(float collisionSpeed);
 	void setPosition(Framework::Vec3<float> pos);

+ 2 - 2
FactoryCraft/FactoryCraft.vcxproj

@@ -124,7 +124,7 @@
     <ClInclude Include="ItemStack.h" />
     <ClInclude Include="ItemType.h" />
     <ClInclude Include="ModelInfo.h" />
-    <ClInclude Include="NetworkResponse.h" />
+    <ClInclude Include="NetworkMessage.h" />
     <ClInclude Include="Noise.h" />
     <ClInclude Include="NoBlock.h" />
     <ClInclude Include="OverworldDimension.h" />
@@ -178,7 +178,7 @@
     <ClCompile Include="ItemStack.cpp" />
     <ClCompile Include="ItemType.cpp" />
     <ClCompile Include="ModelInfo.cpp" />
-    <ClCompile Include="NetworkResponse.cpp" />
+    <ClCompile Include="NetworkMessage.cpp" />
     <ClCompile Include="NoBlock.cpp" />
     <ClCompile Include="Noise.cpp" />
     <ClCompile Include="OverworldDimension.cpp" />

+ 2 - 2
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -165,7 +165,7 @@
     <ClInclude Include="Server.h">
       <Filter>server</Filter>
     </ClInclude>
-    <ClInclude Include="NetworkResponse.h">
+    <ClInclude Include="NetworkMessage.h">
       <Filter>server\response</Filter>
     </ClInclude>
     <ClInclude Include="NoBlock.h">
@@ -326,7 +326,7 @@
     <ClCompile Include="Game.cpp">
       <Filter>game</Filter>
     </ClCompile>
-    <ClCompile Include="NetworkResponse.cpp">
+    <ClCompile Include="NetworkMessage.cpp">
       <Filter>server\response</Filter>
     </ClCompile>
     <ClCompile Include="NoBlock.cpp">

+ 16 - 6
FactoryCraft/Game.cpp

@@ -182,21 +182,19 @@ bool GameClient::isOnline() const
 	return online;
 }
 
-void GameClient::sendResponse(NetworkResponse* zResponse)
+void GameClient::sendResponse(NetworkMessage* zResponse)
 {
 	if (zResponse->isAreaAffected({ lastPos.x - (float)CHUNK_SIZE * (float)viewDistance, lastPos.y - (float)CHUNK_SIZE * (float)viewDistance, 0.f }, { lastPos.x + (float)CHUNK_SIZE * (float)viewDistance, lastPos.y + (float)CHUNK_SIZE * (float)viewDistance, (float)WORLD_HEIGHT }, zPlayer->getCurrentDimensionId()))
 	{
 		if (zResponse->isUseBackground())
 		{
 			background.lock();
-			client->zBackgroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
 			zResponse->writeTo(client->zBackgroundWriter());
 			background.unlock();
 		}
 		else
 		{
 			foreground.lock();
-			client->zForegroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
 			zResponse->writeTo(client->zForegroundWriter());
 			foreground.unlock();
 		}
@@ -354,7 +352,7 @@ void Game::api(Framework::StreamReader* zRequest, GameClient* zOrigin)
 {
 	char type;
 	zRequest->lese(&type, 1);
-	NetworkResponse response;
+	NetworkMessage response;
 	switch (type)
 	{
 	case 1: // world
@@ -394,18 +392,30 @@ void Game::api(Framework::StreamReader* zRequest, GameClient* zOrigin)
 	if (!response.isEmpty())
 	{
 		if (response.isBroadcast())
-			distributeResponse(&response);
+			broadcastMessage(&response);
 		else
 			zOrigin->sendResponse(&response);
 	}
 }
 
-void Game::distributeResponse(NetworkResponse* zResponse)
+void Game::broadcastMessage(NetworkMessage* zResponse)
 {
 	for (auto client : *clients)
 		client->sendResponse(zResponse);
 }
 
+void Game::sendMessage(NetworkMessage* zResponse, Entity* zTargetPlayer)
+{
+	for (auto client : *clients)
+	{
+		if (client->zEntity() == zTargetPlayer)
+		{
+			client->sendResponse(zResponse);
+			break;
+		}
+	}
+}
+
 bool Game::requestWorldUpdate(WorldUpdate* update)
 {
 	cs.lock();

+ 3 - 3
FactoryCraft/Game.h

@@ -45,11 +45,10 @@ public:
 	void logout();
 	void addMessage(StreamReader* reader);
 	bool isOnline() const;
-	void sendResponse(NetworkResponse* zResponse);
+	void sendResponse(NetworkMessage* zResponse);
 	Player* zEntity() const;
 	void sendTypes();
 
-private:
 	class Message
 	{
 	public:
@@ -84,7 +83,8 @@ public:
 	~Game();
 	void initialize();
 	void api(Framework::StreamReader* zRequest, GameClient* zOrigin);
-	void distributeResponse(NetworkResponse* zResponse);
+	void broadcastMessage(NetworkMessage* zResponse);
+	void sendMessage(NetworkMessage* zResponse, Entity* zTargetPlayer);
 	bool requestWorldUpdate(WorldUpdate* update);
 	GameClient* addPlayer(FCKlient* client, Framework::Text name);
 	bool doesChunkExist(int x, int y, int dimension);

+ 4 - 0
FactoryCraft/Inventory.cpp

@@ -499,7 +499,11 @@ ItemStack* Inventory::takeItemsOut(ItemSlot* zSlot, int count, Direction dir)
 	{
 		ItemStack* stack = zSlot->takeItemsOut(count, dir);
 		if (stack)
+		{
 			updateCache(zSlot, stack->zItem()->zItemType()->getId());
+			if(stack->getSize() > 0)
+				afterPullStack(zSlot, dir, stack->zItem(), stack->getSize());
+		}
 		return stack;
 	}
 	return 0;

+ 23 - 28
FactoryCraft/NetworkResponse.cpp → FactoryCraft/NetworkMessage.cpp

@@ -1,9 +1,9 @@
-#include "NetworkResponse.h"
+#include "NetworkMessage.h"
 #include "Chunk.h"
 #include "Entity.h"
 #include "Game.h"
 
-NetworkResponse::NetworkResponse()
+NetworkMessage::NetworkMessage()
 {
 	adress = 0;
 	adressLength = 0;
@@ -12,17 +12,23 @@ NetworkResponse::NetworkResponse()
 	msgDelete = 0;
 	msgLength = 0;
 	useBackground = 0;
+	minPosition.x = std::numeric_limits<float>::min();
+	minPosition.y = std::numeric_limits<float>::min();
+	minPosition.z = std::numeric_limits<float>::min();
+	maxPosition.x = std::numeric_limits<float>::max();
+	maxPosition.y = std::numeric_limits<float>::max();
+	maxPosition.z = std::numeric_limits<float>::max();
 	affectedDimension = -1;
 }
 
-NetworkResponse::~NetworkResponse()
+NetworkMessage::~NetworkMessage()
 {
 	if (msgDelete)
 		delete[] message;
 	delete[] adress;
 }
 
-void NetworkResponse::adressChunck(Chunk* zChunk)
+void NetworkMessage::adressChunck(Chunk* zChunk)
 {
 	adressLength = 10;
 	adress = new char[adressLength];
@@ -36,7 +42,7 @@ void NetworkResponse::adressChunck(Chunk* zChunk)
 	affectedDimension = zChunk->getDimensionId();
 }
 
-void NetworkResponse::adressEntity(Entity* zEntity)
+void NetworkMessage::adressEntity(Entity* zEntity)
 {
 	adressLength = 6;
 	adress = new char[adressLength];
@@ -48,7 +54,7 @@ void NetworkResponse::adressEntity(Entity* zEntity)
 	affectedDimension = zEntity->getCurrentDimensionId();
 }
 
-void NetworkResponse::adressBlock(Block* zBlock)
+void NetworkMessage::adressBlock(Block* zBlock)
 {
 	adressLength = 14;
 	adress = new char[adressLength];
@@ -63,7 +69,7 @@ void NetworkResponse::adressBlock(Block* zBlock)
 	affectedDimension = zBlock->getDimensionId();
 }
 
-void NetworkResponse::openDialog(Framework::Text dialogName)
+void NetworkMessage::openDialog(Framework::Text dialogName)
 {
 	adressLength = (char)(4 + dialogName.getLength());
 	adress = new char[adressLength];
@@ -71,15 +77,9 @@ void NetworkResponse::openDialog(Framework::Text dialogName)
 	adress[1] = 0; // open dialog
 	*(short*)(adress + 2) = (short)dialogName.getLength(); // block
 	memcpy(adress + 4, dialogName.getText(), dialogName.getLength());
-	minPosition.x = std::numeric_limits<float>::min();
-	minPosition.y = std::numeric_limits<float>::min();
-	minPosition.z = std::numeric_limits<float>::min();
-	maxPosition.x = std::numeric_limits<float>::max();
-	maxPosition.y = std::numeric_limits<float>::max();
-	maxPosition.z = std::numeric_limits<float>::max();
 }
 
-void NetworkResponse::adressGui(Framework::Text elementId)
+void NetworkMessage::adressGui(Framework::Text elementId)
 {
 	adressLength = (char)(4 + elementId.getLength());
 	adress = new char[adressLength];
@@ -87,60 +87,55 @@ void NetworkResponse::adressGui(Framework::Text elementId)
 	adress[1] = 1; // element message
 	*(short*)(adress + 2) = (short)elementId.getLength(); // block
 	memcpy(adress + 4, elementId.getText(), elementId.getLength());
-	minPosition.x = std::numeric_limits<float>::min();
-	minPosition.y = std::numeric_limits<float>::min();
-	minPosition.z = std::numeric_limits<float>::min();
-	maxPosition.x = std::numeric_limits<float>::max();
-	maxPosition.y = std::numeric_limits<float>::max();
-	maxPosition.z = std::numeric_limits<float>::max();
 }
 
-void NetworkResponse::setMessage(char* msg, int length, bool deleteMsg)
+void NetworkMessage::setMessage(char* msg, int length, bool deleteMsg)
 {
 	message = msg;
 	msgLength = length;
 	msgDelete = deleteMsg;
 }
 
-void NetworkResponse::setUseBackground()
+void NetworkMessage::setUseBackground()
 {
 	useBackground = 1;
 }
 
-void NetworkResponse::sendToAll()
+void NetworkMessage::sendToAll()
 {
 	broadcast = true;
 }
 
-bool NetworkResponse::isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max, int affectedDimension) const
+bool NetworkMessage::isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max, int affectedDimension) const
 {
 	return minPosition.x <= max.x && maxPosition.x >= min.x &&
 		minPosition.y <= max.y && maxPosition.y >= min.y &&
 		minPosition.z <= max.z && maxPosition.z >= min.z && (this->affectedDimension < 0 || this->affectedDimension == affectedDimension);
 }
 
-void NetworkResponse::writeTo(Framework::StreamWriter* zWriter) const
+void NetworkMessage::writeTo(Framework::StreamWriter* zWriter) const
 {
 	int total = msgLength + adressLength;
 	if (total)
 	{
+		zWriter->schreibe((char*)&GameClient::Message::API_MESSAGE, 1);
 		zWriter->schreibe((char*)&total, 4);
 		zWriter->schreibe(adress, adressLength);
 		zWriter->schreibe(message, msgLength);
 	}
 }
 
-bool NetworkResponse::isBroadcast() const
+bool NetworkMessage::isBroadcast() const
 {
 	return broadcast;
 }
 
-bool NetworkResponse::isEmpty() const
+bool NetworkMessage::isEmpty() const
 {
 	return msgLength + adressLength <= 0;
 }
 
-bool NetworkResponse::isUseBackground() const
+bool NetworkMessage::isUseBackground() const
 {
 	return useBackground;
 }

+ 3 - 3
FactoryCraft/NetworkResponse.h → FactoryCraft/NetworkMessage.h

@@ -7,7 +7,7 @@ class Chunk;
 class Block;
 class Entity;
 
-class NetworkResponse
+class NetworkMessage
 {
 private:
 	char* adress;
@@ -22,8 +22,8 @@ private:
 	int affectedDimension;
 
 public:
-	NetworkResponse();
-	~NetworkResponse();
+	NetworkMessage();
+	~NetworkMessage();
 
 	void adressChunck(Chunk* zChunk);
 	void adressEntity(Entity* zEntity);

+ 81 - 9
FactoryCraft/Player.cpp

@@ -39,7 +39,14 @@ void Player::afterPullStack(ItemSlot* zSlot, Direction dir, const Item* zItem, i
 	{
 		if (slot == zSlot)
 		{
-			needUpdate = 1;
+			NetworkMessage msg;
+			msg.adressGui("gui_item_bar");
+			char message[9];
+			message[0] = 1; // set count of items
+			*(int*)(message + 1) = zSlot->getId();
+			*(int*)(message + 5) = zSlot->getNumberOfItems();
+			msg.setMessage(message, 9, 0);
+			Game::INSTANCE->sendMessage(&msg, this);
 			return;
 		}
 	}
@@ -51,12 +58,46 @@ void Player::afterPushStack(ItemSlot* zSlot, Direction dir, const Item* zItem, i
 	{
 		if (slot == zSlot)
 		{
-			needUpdate = 1;
+			if (zSlot->getNumberOfItems() > count)
+			{
+				NetworkMessage msg;
+				msg.adressGui("gui_item_bar");
+				char message[9];
+				message[0] = 1; // set count of items
+				*(int*)(message + 1) = zSlot->getId();
+				*(int*)(message + 5) = zSlot->getNumberOfItems();
+				msg.setMessage(message, 9, 0);
+				Game::INSTANCE->sendMessage(&msg, this);
+			}
+			else
+			{
+				NetworkMessage msg;
+				msg.adressGui("gui_item_bar");
+				char message[29];
+				message[0] = 2; // add new stack
+				*(int*)(message + 1) = zSlot->getId();
+				*(int*)(message + 5) = zSlot->getNumberOfItems();
+				const Item* zItem = zSlot->zStack()->zItem();
+				*(float*)(message + 9) = zItem->getDamage();
+				*(float*)(message + 13) = zItem->getMaxDamage();
+				*(float*)(message + 17) = zItem->getDurability();
+				*(float*)(message + 21) = zItem->getMaxDurability();
+				*(int*)(message + 25) = zItem->zItemType()->getId();
+				msg.setMessage(message, 29, 0);
+				Game::INSTANCE->sendMessage(&msg, this);
+			}
 			return;
 		}
 	}
 }
 
+void Player::onTargetChange()
+{
+	NetworkMessage msg;
+	ActionTarget::toMessage(zTarget(), msg);
+	Game::INSTANCE->sendMessage(&msg, this);
+}
+
 Framework::Text Player::getInventoryUIML()
 {
 	Framework::Text result = "<dialog id=\"player_inventory\" title=\"Inventory\" width=\"610\" height=\"450\">";
@@ -77,6 +118,18 @@ Framework::Text Player::getInventoryUIML()
 	return result;
 }
 
+Framework::Text Player::getPlayerGUI()
+{
+	Framework::Text result = "<gui id=\"player_gui\">";
+
+	result += "<itemBar id=\"gui_item_bar\" margin-bottom=\"9\" align-bottom=\"end\" align-left=\"center\" width=\"592\" height=\"52\" rowSize=\"10\" slotNameFilter=\"ItemBar\" target=\"";
+	result += getId();
+	result += "\"/>";
+
+	result += "</gui>";
+	return result;
+}
+
 void Player::useItemSlot(ItemSlot* zSlot)
 {
 	if (zSlot->zStack())
@@ -185,7 +238,7 @@ void Player::tick(const Dimension* zDimension)
 	return Entity::tick(zDimension);
 }
 
-void Player::playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void Player::playerApi(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
 	char byte;
 	zRequest->lese(&byte, 1);
@@ -296,21 +349,40 @@ void Player::playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResp
 		zRequest->lese((char*)&faceDir.z, 4);
 		break;
 	case 3:
-		// switch item bar position
+	{ // switch item bar position
 		zRequest->lese((char*)&leftHandPosition, 4);
 		leftHandPosition = leftHandPosition % itemBar.getEintragAnzahl();
-		needUpdate = 1;
+		NetworkMessage msg;
+		msg.adressGui("gui_item_bar");
+		char message[5];
+		message[0] = 3; // set selected slot
+		*(int*)(message + 1) = leftHandPosition;
+		msg.setMessage(message, 5, 0);
+		Game::INSTANCE->sendMessage(&msg, this);
 		break;
+	}
 	case 4:
 	{
 		// open inventory
 		zResponse->openDialog("player_inventory");
 		Text uiml = getInventoryUIML();
-		int msgSize = 5 + uiml.getLength();
+		int msgSize = 4 + uiml.getLength();
+		char* msg = new char[msgSize];
+		*(int*)msg = uiml.getLength();
+		memcpy(msg + 4, uiml.getText(), uiml.getLength());
+		zResponse->setMessage(msg, msgSize, 1);
+		break;
+	}
+	case 5:
+	{
+		// request gui
+		Text uiml = getPlayerGUI();
+		int msgSize = 6 + uiml.getLength();
 		char* msg = new char[msgSize];
-		msg[0] = 0; // open dialog
-		*(int*)(msg + 1) = uiml.getLength();
-		memcpy(msg + 5, uiml.getText(), uiml.getLength());
+		msg[0] = 2; // gui message
+		msg[1] = 2; // set gui
+		*(int*)(msg + 2) = uiml.getLength();
+		memcpy(msg + 6, uiml.getText(), uiml.getLength());
 		zResponse->setMessage(msg, msgSize, 1);
 		break;
 	}

+ 3 - 1
FactoryCraft/Player.h

@@ -38,14 +38,16 @@ private:
 
 	virtual void afterPullStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int count) override;
 	virtual void afterPushStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int count) override;
+	virtual void onTargetChange() override;
 	Framework::Text getInventoryUIML();
+	Framework::Text getPlayerGUI();
 
 public:
 	void setName(Framework::Text name);
 	const char* getName() const;
 	void tick(const Dimension* zDimension) override;
 
-	void playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	void playerApi(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
 	void onFall(float collisionSpeed) override;
 
 	friend PlayerEntityType;