瀏覽代碼

add ingame gui and synchronize target via api

Kolja Strohm 2 年之前
父節點
當前提交
2039e907ce

+ 1 - 0
FactoryCraft/DirectConnect.cpp

@@ -25,6 +25,7 @@ DirectConnect::DirectConnect(Bildschirm* zScreen)
 					currentGame = new World(dynamic_cast<Bildschirm3D*>(zScreen));
 					hide();
 					menuRegister->get("game")->show();
+					network->zFactoryClient()->sendPlayerAction("\5", 1);
 				}
 				address->addStyle(TextFeld::Style::Erlaubt);
 				port->addStyle(TextFeld::Style::Erlaubt);

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -190,6 +190,7 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClCompile Include="Globals.cpp" />
     <ClCompile Include="Initialisierung.cpp" />
     <ClCompile Include="InventoryView.cpp" />
+    <ClCompile Include="ItemBar.cpp" />
     <ClCompile Include="ItemType.cpp" />
     <ClCompile Include="Load.cpp" />
     <ClCompile Include="Login.cpp" />
@@ -225,6 +226,7 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClInclude Include="AddChunkUpdate.h" />
     <ClInclude Include="Initialisierung.h" />
     <ClInclude Include="InventoryView.h" />
+    <ClInclude Include="ItemBar.h" />
     <ClInclude Include="ItemType.h" />
     <ClInclude Include="Load.h" />
     <ClInclude Include="Login.h" />

+ 9 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -35,6 +35,9 @@
     <Filter Include="Entity">
       <UniqueIdentifier>{2a45d30e-df5b-4886-8ae7-d42ff2b3a13e}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Menu\uiml\playerGUI">
+      <UniqueIdentifier>{bc1fa16a-bbbf-4627-873b-f6689d2e756b}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Main.cpp">
@@ -133,6 +136,9 @@
     <ClCompile Include="ModelInfo.cpp">
       <Filter>static</Filter>
     </ClCompile>
+    <ClCompile Include="ItemBar.cpp">
+      <Filter>Menu\uiml\playerGUI</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Area.h">
@@ -234,5 +240,8 @@
     <ClInclude Include="StaticRegistry.h">
       <Filter>static</Filter>
     </ClInclude>
+    <ClInclude Include="ItemBar.h">
+      <Filter>Menu\uiml\playerGUI</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 26 - 2
FactoryCraft/Game.cpp

@@ -1,6 +1,7 @@
 #include "Game.h"
 #include "Initialisierung.h"
 #include "Globals.h"
+#include "ItemBar.h"
 
 #include <AsynchronCall.h>
 #include <Bildschirm.h>
@@ -33,6 +34,11 @@ Game::Game(Bildschirm* zScreen)
 	elements.add(logout);
 	debug = initTextFeld(10, 40, 500, 40, TextFeld::Style::Text | TextFeld::Style::Mehrzeilig, "");
 	elements.add(debug);
+	guiView = new UIMLView("<v/>", uiFactory);
+	guiView->addKnownElement(new ItemBarElement());
+	guiView->setStyle(UIMLView::Style::Sichtbar);
+	guiView->setSize(window->zBildschirm()->getBackBufferSize());
+	elements.add(guiView);
 }
 
 Game::~Game()
@@ -83,9 +89,9 @@ void Game::api(char* data)
 		delete[] dialogName;
 		if (!exists)
 		{
-			int uimlLen = *(int*)(data + 4 + len);
+			int uimlLen = *(int*)(data + 3 + len);
 			char* uiml = new char[uimlLen + 1];
-			memcpy(uiml, data + 8 + len, uimlLen);
+			memcpy(uiml, data + 7 + len, uimlLen);
 			uiml[uimlLen] = 0;
 			UIMLDialog* dialog = new UIMLDialog(uiml, [this](UIMLDialog* dialog)
 				{
@@ -116,7 +122,25 @@ void Game::api(char* data)
 		{
 			dialog->api(data + 1);
 		}
+		short idLen = *(short*)(data + 1);
+		char* id = new char[idLen + 1];
+		memcpy(id, data + 3, idLen);
+		id[idLen] = 0;
+		NetworkAPIProcessor* processor = dynamic_cast<NetworkAPIProcessor*>(guiView->zZeichnungById(id));
+		if (processor)
+			processor->api(data + 3 + idLen);
+		delete[] id;
 		break;
 	}
+	case 2:
+	{ // set gui
+		int uimlLen = *(int*)(data + 1);
+		char* uiml = new char[uimlLen + 1];
+		memcpy(uiml, data + 5, uimlLen);
+		uiml[uimlLen] = 0;
+		guiView->setUIML(uiml);
+		guiView->layout();
+		delete[] uiml;
+	}
 	}
 }

+ 1 - 0
FactoryCraft/Game.h

@@ -14,6 +14,7 @@ private:
 	Framework::Knopf* logout;
 	Framework::TextFeld* debug;
 	Framework::Array<UIMLDialog*> dialogs;
+	Framework::UIMLView* guiView;
 
 public:
 	// Konstruktor

+ 4 - 3
FactoryCraft/InventoryView.cpp

@@ -42,12 +42,12 @@ void InventoryElement::layout(Framework::XML::Element& element, Framework::Zeich
 }
 
 
-void SlotInfo::render(int x, int y, Framework::Bild& rObj)
+void SlotInfo::render(int x, int y, Framework::Bild& rObj, bool selected)
 {
 	TextRenderer tr;
 	tr.setSchriftZ(dynamic_cast<Schrift*>(uiFactory.initParam.schrift->getThis()));
 	tr.setSchriftSize(12);
-	rObj.fillRegion(x, y, 52, 52, 0xFF52525E);
+	rObj.fillRegion(x, y, 52, 52, selected ? 0xFFFFFFFF : 0xFF52525E);
 	rObj.fillRegion(x + 1, y + 1, 50, 50, 0xFF222222);
 	if (itemCount > 0)
 	{
@@ -131,6 +131,7 @@ void InventoryView::api(char* message)
 					this->slots->release();
 				this->slots = slots;
 			});
+		break;
 	}
 	}
 }
@@ -152,7 +153,7 @@ void InventoryView::render(Bild& rObj)
 		int rowCount = 0;
 		for (SlotInfo info : *slots)
 		{
-			info.render(x, y, rObj);
+			info.render(x, y, rObj, 0);
 			x += 60;
 			if (++rowCount >= rowSize)
 			{

+ 1 - 1
FactoryCraft/InventoryView.h

@@ -27,7 +27,7 @@ struct SlotInfo
 	float maxDurability;
 	Framework::Bild* zItem;
 
-	void render(int x, int y, Framework::Bild& rObj);
+	void render(int x, int y, Framework::Bild& rObj, bool selected);
 };
 
 class InventoryView : public Framework::ZeichnungHintergrund, public NetworkAPIProcessor

+ 158 - 0
FactoryCraft/ItemBar.cpp

@@ -0,0 +1,158 @@
+#include <XML.h>
+#include <Bild.h>
+
+#include "ItemBar.h"
+#include "Globals.h"
+
+using namespace Framework;
+
+ItemBarElement::ItemBarElement()
+	: UIMLElement()
+{}
+
+//! prüft, ob dieses UIML Element für ein bestimmtes xml Element zuständig ist
+bool ItemBarElement::isApplicableFor(Framework::XML::Element& element)
+{
+	return element.getName().istGleich("itemBar");
+}
+
+//! erstellt eine neue Zeichnung zu einem gegebenen xml Element
+Framework::Zeichnung* ItemBarElement::parseElement(Framework::XML::Element& element, Framework::UIMLContainer& generalFactory)
+{
+	return new ItemBarView(element.getAttributeValue("id"), (int)element.getAttributeValue("rowSize"), (int)element.getAttributeValue("target"), element.getAttributeValue("slotNameFilter"));
+}
+
+//! wendet die layout parameter zu einer Zeichnung an
+void ItemBarElement::layout(Framework::XML::Element& element, Framework::Zeichnung& z, int pWidth, int pHeight, Framework::UIMLContainer& generalLayouter)
+{
+	UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
+}
+
+
+ItemBarView::ItemBarView(Framework::Text id, int rowSize, int targetEntity, Framework::Text slotNameFilter)
+	: ZeichnungHintergrund(),
+	id(id),
+	rowSize(rowSize),
+	targetEntity(targetEntity),
+	slotNameFilter(slotNameFilter),
+	slots(0),
+	leftHandPos(0)
+{
+	char* msg = new char[id.getLength() + slotNameFilter.getLength() + 3];
+	msg[0] = 100;
+	msg[1] = (char)id.getLength();
+	memcpy(msg + 2, id.getText(), id.getLength());
+	msg[2 + id.getLength()] = (char)slotNameFilter.getLength();
+	memcpy(msg + 3 + id.getLength(), slotNameFilter.getText(), slotNameFilter.getLength());
+	network->zFactoryClient()->entityAPIRequest(targetEntity, msg, id.getLength() + slotNameFilter.getLength() + 3);
+	delete[] msg;
+}
+
+ItemBarView::~ItemBarView()
+{
+	if (slots)
+		slots->release();
+}
+
+void ItemBarView::api(char* message)
+{
+	switch (message[0])
+	{
+	case 0:
+		// send inventory content
+	{
+		Array<SlotInfo>* slots = new Array<SlotInfo>();
+		int count = *(int*)(++message);
+		for (int i = 0; i < count; i++)
+		{
+			SlotInfo info;
+			info.id = *(int*)(message += 4);
+			info.itemCount = *(int*)(message += 4);
+			if (info.itemCount > 0)
+			{
+				info.damage = *(float*)(message += 4);
+				info.maxDamage = *(float*)(message += 4);
+				info.durability = *(float*)(message += 4);
+				info.maxDurability = *(float*)(message += 4);
+				info.zItem = itemIcons->z(*(int*)(message += 4));
+			}
+			slots->add(info);
+		}
+		postAction([this, slots]()
+			{
+				if (this->slots)
+					this->slots->release();
+				this->slots = slots;
+			});
+		break;
+	}
+	case 1: // set count of items
+	{
+		int id = *(int*)(message + 1);
+		int count = *(int*)(message + 5);
+		for (int i = 0; i < slots->getEintragAnzahl(); i++)
+		{
+			if (slots->get(i).id == id)
+			{
+				SlotInfo info = slots->get(i);
+				info.itemCount = count;
+				slots->set(info, i);
+				break;
+			}
+		}
+		break;
+	}
+	case 2: // add new stack
+	{
+		int id = *(int*)(message + 1);
+		for (int i = 0; i < slots->getEintragAnzahl(); i++)
+		{
+			if (slots->get(i).id == id)
+			{
+				SlotInfo info = slots->get(i);
+				info.itemCount = *(int*)(message + 5);
+				info.damage = *(float*)(message + 9);
+				info.maxDamage = *(float*)(message + 13);
+				info.durability = *(float*)(message + 17);
+				info.maxDurability = *(float*)(message + 21);
+				info.zItem = itemIcons->z(*(int*)(message + 25));
+				slots->set(info, i);
+				break;
+			}
+		}
+		break;
+	}
+	case 3: // set selected slot
+	{
+		leftHandPos = *(int*)(message + 1);
+		break;
+	}
+	}
+}
+
+void ItemBarView::render(Bild& rObj)
+{
+	ZeichnungHintergrund::render(rObj);
+	if (!rObj.setDrawOptions(pos.x, pos.y, gr.x, gr.y))
+		return;
+	if (slots)
+	{
+		int x = 0;
+		int y = 0;
+		int rowCount = 0;
+		int index = 0;
+		for (SlotInfo info : *slots)
+		{
+			info.render(x, y, rObj, index == leftHandPos);
+			x += 60;
+			if (++rowCount >= rowSize)
+			{
+				y += 60;
+				x = 0;
+				rowCount = 0;
+			}
+			index++;
+		}
+	}
+	rObj.releaseDrawOptions();
+}

+ 37 - 0
FactoryCraft/ItemBar.h

@@ -0,0 +1,37 @@
+#pragma once
+
+#include <UIMLView.h>
+#include <Either.h>
+
+#include "NetworkAPIProcessor.h"
+#include "InventoryView.h"
+
+
+class ItemBarElement : public Framework::UIMLElement
+{
+public:
+	ItemBarElement();
+	//! prüft, ob dieses UIML Element für ein bestimmtes xml Element zuständig ist
+	bool isApplicableFor(Framework::XML::Element& element) override;
+	//! erstellt eine neue Zeichnung zu einem gegebenen xml Element
+	Framework::Zeichnung* parseElement(Framework::XML::Element& element, Framework::UIMLContainer& generalFactory) override;
+	//! wendet die layout parameter zu einer Zeichnung an
+	void layout(Framework::XML::Element& element, Framework::Zeichnung& z, int pWidth, int pHeight, Framework::UIMLContainer& generalLayouter) override;
+};
+
+class ItemBarView : public Framework::ZeichnungHintergrund, public NetworkAPIProcessor
+{
+private:
+	Framework::Text id;
+	int rowSize;
+	int targetEntity;
+	Framework::Text slotNameFilter;
+	Framework::Array<SlotInfo>* slots;
+	int leftHandPos;
+
+public:
+	ItemBarView(Framework::Text id, int rowSize, int targetEntity, Framework::Text slotNameFilter);
+	~ItemBarView();
+	void api(char* message) override;
+	void render(Framework::Bild& rObj) override;
+};

+ 16 - 0
FactoryCraft/World.cpp

@@ -69,6 +69,22 @@ void World::update(bool background)
 			case 2: // gui message
 				((Game*)(Menu*)menuRegister->get("game"))->api(data + 1);
 				break;
+			case 3: // set target
+			{
+				switch (data[1])
+				{
+				case 0:
+					setTarget(0);
+					break;
+				case 1:
+					setTarget(zEntity(*(int*)(data + 2)));
+					break;
+				case 2:
+					setTarget(zBlockAt(Vec3<int>(*(int*)(data + 2), *(int*)(data + 6), *(int*)(data + 10))));
+					break;
+				}
+				break;
+			}
 			}
 			delete[] data;
 			// TODO: process messages