Browse Source

add ingame chat

Kolja Strohm 2 years ago
parent
commit
f0a81be569

+ 141 - 0
FactoryCraft/Chat.cpp

@@ -0,0 +1,141 @@
+#include "Chat.h"
+
+#include <DateiSystem.h>
+
+#include "Game.h"
+#include "Globals.h"
+#include "ChatMessage.h"
+#include <AsynchronCall.h>
+
+Chat::Chat()
+    : Fenster()
+{
+    setStyle(
+        Fenster::Style::Erlaubt
+        | Fenster::Style::Rahmen | Fenster::Style::BodyHAlpha
+        | Fenster::Style::Titel
+        | Fenster::Style::TitelHAlpha | Fenster::Style::Closable
+        | Fenster::Style::ClosingHAlpha | Fenster::Style::ClosingKlickBuffer
+        | Fenster::Style::TitelHintergrund | Fenster::Style::BodyHintergrund
+        | Fenster::Style::ClosingHintergrund | Fenster::Style::MEIgnoreInside | Fenster::Style::HeightChangeable | Fenster::Style::BreiteChangeable | Fenster::Style::BodyMinBr | Fenster::Style::BodyMinHi | Fenster::Style::LeftPositionFixed | Fenster::Style::BottomPositionFixed);
+    removeStyle(Fenster::Style::Sichtbar);
+    setTitel("Chat");
+    setClosingMe([this](void* p, void* o, Framework::MausEreignis me) {
+        if (me.id == Framework::ME_RLinks)
+        {
+            removeStyle(Fenster::Style::Sichtbar);
+            ((Game*)(Menu*)menuRegister->get("game"))->makeChatButtonVisible();
+        }
+        return 1;
+    });
+    setSize(500, 300);
+    setPosition(5, uiFactory.initParam.bildschirm->getBackBufferSize().y - 305);
+    setMausEreignis(Framework::_ret1ME);
+    setTastaturEreignis(Framework::_ret1TE);
+    setRBreite(1);
+    setRFarbe(0xFF52525E);
+    setKBgFarbe(0xA0000000);
+    setTBgFarbe(0xA0000000);
+    setSBgFarbe(0xA0000000);
+    setTSchriftZ(
+        dynamic_cast<Schrift*>(uiFactory.initParam.schrift->getThis()));
+    zTTextFeld()->setSize(0, 20);
+    zTTextFeld()->addStyle(TextFeld::Style::Center);
+    setKMin(200, 100);
+
+    history = new ChatHistory();
+    history->setSize(getInnenBreite(), getInnenHeight() - 20);
+    addMember(history);
+
+    commandLine = uiFactory.createTextFeld(uiFactory.initParam);
+    commandLine->setText("");
+    commandLine->setSize(getInnenBreite() - 40, 20);
+    commandLine->setPosition(20, getInnenHeight() - 20);
+    commandLine->setStyle(Framework::TextFeld::Style::TextFeld);
+    commandLine->setTastaturEreignis(
+        [this](void* p, void* o, Framework::TastaturEreignis te) {
+            if (te.id == Framework::TE_Release
+                && te.virtualKey == Framework::T_Enter)
+            {
+                if (commandLine->zText()->getLength() > 0)
+                {
+                    Text* msg = new Text(*commandLine->zText());
+                    commandLine->setText("");
+                    new AsynchronCall([msg]() {
+                        World::INSTANCE->zClient()->sendChatMessage(*msg);
+                        msg->release();
+                    });
+                }
+            }
+            return 1;
+        });
+    addMember(commandLine);
+
+    LTDBDatei iconsDat;
+    iconsDat.setDatei(new Text("data/bilder/gui_icons.ltdb"));
+    iconsDat.leseDaten(0);
+
+    sendButton = uiFactory.createKnopf(uiFactory.initParam);
+    sendButton->setAlphaFeldFarbe(0x5F337AB7);
+    sendButton->setToolTipText(
+        "Send", uiFactory.initParam.bildschirm, uiFactory.initParam.schrift);
+    sendButton->setSize(20, 20);
+    sendButton->setPosition(getInnenBreite() - 20, getInnenHeight() - 20);
+    sendButton->addStyle(Framework::Knopf::Style::HBild
+                         | Framework::Knopf::Style::HAlpha
+                         | Framework::Knopf::Style::Hintergrund);
+    sendButton->setHintergrundBildZ(iconsDat.laden(0, new Text("send.png")));
+    sendButton->setMausEreignis(
+        [this](void* p, void* o, Framework::MausEreignis me) {
+            if (me.id == ME_RLinks)
+            {
+                if (commandLine->zText()->getLength() > 0)
+                {
+                    Text* msg = new Text(*commandLine->zText());
+                    commandLine->setText("");
+                    new AsynchronCall([msg]() {
+                        World::INSTANCE->zClient()->sendChatMessage(*msg);
+                        msg->release();
+                    });
+                }
+            }
+            return 1;
+        });
+    addMember(sendButton);
+
+    optionsButton = uiFactory.createKnopf(uiFactory.initParam);
+    optionsButton->setAlphaFeldFarbe(0x5F337AB7);
+    optionsButton->setToolTipText(
+        "Options", uiFactory.initParam.bildschirm, uiFactory.initParam.schrift);
+    optionsButton->setSize(20, 20);
+    optionsButton->setPosition(0, getInnenHeight() - 20);
+    optionsButton->addStyle(Framework::Knopf::Style::HBild
+                            | Framework::Knopf::Style::HAlpha
+                            | Framework::Knopf::Style::Hintergrund);
+    optionsButton->setHintergrundBildZ(
+        iconsDat.laden(0, new Text("options.png")));
+    optionsButton->setMausEreignis(
+        [this](void* p, void* o, Framework::MausEreignis me) {
+            if (me.id == ME_RLinks)
+            {
+                // TODO: open Options
+            }
+            return 1;
+        });
+    addMember(optionsButton);
+}
+
+void Chat::addMessage(char* data)
+{
+    history->addMessage(new ChatMessage(data));
+}
+
+bool Chat::tick(double time)
+{
+    history->setSize(getInnenBreite(), getInnenHeight() - 20);
+    commandLine->setSize(getInnenBreite() - 40, 20);
+    commandLine->setPosition(20, getInnenHeight() - 20);
+    sendButton->setPosition(getInnenBreite() - 20, getInnenHeight() - 20);
+    optionsButton->setPosition(0, getInnenHeight() - 20);
+    return Fenster::tick(time);
+}

+ 22 - 0
FactoryCraft/Chat.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Knopf.h>
+
+#include "ChatHistory.h"
+
+class Chat : public Framework::Fenster
+{
+private:
+    ChatHistory* history;
+    Framework::TextFeld* commandLine;
+    Framework::Knopf* sendButton;
+    Framework::Knopf* optionsButton;
+    
+public:
+    Chat();
+
+    void addMessage(char* data);
+    bool tick(double time) override;
+};

+ 49 - 0
FactoryCraft/ChatHistory.cpp

@@ -0,0 +1,49 @@
+#include "ChatHistory.h"
+
+#include <Bild.h>
+#include <Scroll.h>
+
+ChatHistory::ChatHistory()
+    : Framework::ZeichnungHintergrund()
+{
+    setStyle(Style::Sichtbar | Style::Erlaubt | Style::VScroll);
+    setVertikalScrollPos(0);
+    setMausEreignis(Framework::_ret1ME);
+}
+
+void ChatHistory::addMessage(ChatMessage* message)
+{
+    messages.add(message);
+    scrollToBottom = 1;
+}
+
+void ChatHistory::render(Framework::Bild& rObj)
+{
+    ZeichnungHintergrund::render(rObj);
+    if (!rObj.setDrawOptions(innenPosition, innenSize)) return;
+    rObj.addScrollOffset(
+        horizontalScrollBar ? horizontalScrollBar->getScroll() : 0,
+        vertikalScrollBar ? vertikalScrollBar->getScroll() : 0);
+    for (ChatMessage* msg : messages)
+        msg->render(rObj);
+    rObj.releaseDrawOptions();
+}
+
+bool ChatHistory::tick(double tickVal)
+{
+    int y = 0;
+    for (ChatMessage* msg : messages)
+    {
+        msg->setPosition(0, y);
+        msg->setWidth(innenSize.x);
+        rend |= msg->tick(tickVal);
+        y += msg->getHeight();
+    }
+    vertikalScrollBar->update(y, innenSize.y);
+    if (scrollToBottom)
+    {
+        setVertikalScrollPos(y);
+        scrollToBottom = 0;
+    }
+    return ZeichnungHintergrund::tick(tickVal);
+}

+ 20 - 0
FactoryCraft/ChatHistory.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <Zeichnung.h>
+#include <Array.h>
+
+#include "ChatMessage.h"
+
+class ChatHistory : public Framework::ZeichnungHintergrund
+{
+private:
+    Framework::RCArray<ChatMessage> messages;
+    bool scrollToBottom;
+
+public:
+    ChatHistory();
+
+    void addMessage(ChatMessage* message);
+    void render(Framework::Bild& rObj) override;
+    bool tick(double tickVal) override;
+};

+ 60 - 0
FactoryCraft/ChatMessage.cpp

@@ -0,0 +1,60 @@
+#include "ChatMessage.h"
+#include "Globals.h"
+
+ChatMessage::ChatMessage(char* data)
+    : TextFeld()
+{
+    setStyle(Style::VCenter | Style::Sichtbar | Style::Mehrzeilig | Style::AutoLineBreak);
+    setSchriftZ(dynamic_cast<Schrift*>(uiFactory.initParam.schrift->getThis()));
+    setSchriftSize(12);
+    setAutoLineBreakSpacing("    ");
+    
+    __int64 time = *(__int64*)data;
+    short mLen = *(short*)(data + 8);
+    char* message = new char[mLen + 1];
+    memcpy(message, data + 10, mLen);
+    message[mLen] = 0;
+    char channelLen = *(data + 10 + mLen);
+    char* channel = new char[channelLen + 1];
+    memcpy(channel, data + 11 + mLen, channelLen);
+    channel[channelLen] = 0;
+    Framework::Text channelT = channel;
+    delete[] channel;
+
+    Zeit converter(time);
+    Text* timeT = converter.getZeit("d.m.y h:i:s");
+    
+    setSchriftFarbe(0xFFFFFFFF);
+    if (channelT.istGleich("system:INFO"))
+    {
+        setSchriftFarbe(0xFFA0A0A0);
+        channelT = "[INFO]";
+    }
+    else if (channelT.istGleich("system:WARNING"))
+    {
+        setSchriftFarbe(0xFFFF7700);
+        channelT = "[WARNING]";
+    }
+    else if (channelT.istGleich("system:ERROR"))
+    {
+        setSchriftFarbe(0xFFFF0000);
+        channelT = "[ERROR]";
+    }
+    else if (channelT.hatAt(0, "player:"))
+    {
+        Text* tmp = channelT.getTeilText(7);
+        channelT = *tmp;
+        tmp->release();
+    }
+    Text tmp = *timeT + " " + channelT + " " + message;
+    tmp.ersetzen("\n", "\n    ");
+    setText(tmp);
+    timeT->release();
+    delete[] message;
+}
+
+bool ChatMessage::tick(double tickVal)
+{
+    setHeight(getNeededHeight());
+    return ZeichnungHintergrund::tick(tickVal);
+}

+ 17 - 0
FactoryCraft/ChatMessage.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include <Text.h>
+#include <TextFeld.h>
+
+class ChatMessage : public Framework::TextFeld
+{
+private:
+    Framework::Text message;
+    Framework::Text channel;
+    Framework::Text target;
+
+public:
+    ChatMessage(char* data);
+    
+    bool tick(double tickVal) override;
+};

+ 16 - 0
FactoryCraft/FactoryClient.cpp

@@ -438,6 +438,22 @@ void FactoryClient::craftingUIMLRequest(int itemTypeId)
     cs.unlock();
 }
 
+void FactoryClient::sendChatMessage(Framework::Text message)
+{
+    if (!background) return;
+    cs.lock();
+    short length = message.getLength() + 4;
+    background->sende((char*)&length, 2);
+    char msgId = 6;
+    background->sende(&msgId, 1);
+    msgId = 0;
+    background->sende(&msgId, 1);
+    length = message.getLength();
+    background->sende((char*)&length, 2);
+    background->sende(message.getText(), message.getLength());
+    cs.unlock();
+}
+
 bool FactoryClient::isConnected()
 {
     return foreground->isConnected() && background->isConnected();

+ 1 - 0
FactoryCraft/FactoryClient.h

@@ -50,5 +50,6 @@ public:
         char* message,
         unsigned short length);
     void craftingUIMLRequest(int itemTypeId);
+    void sendChatMessage(Framework::Text message);
     bool isConnected();
 };

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -174,6 +174,9 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClCompile Include="Area.cpp" />
     <ClCompile Include="Block.cpp" />
     <ClCompile Include="BlockType.cpp" />
+    <ClCompile Include="Chat.cpp" />
+    <ClCompile Include="ChatHistory.cpp" />
+    <ClCompile Include="ChatMessage.cpp" />
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="CraftingGrid.cpp" />
     <ClCompile Include="CraftingRecipies.cpp" />
@@ -216,6 +219,9 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClInclude Include="Area.h" />
     <ClInclude Include="Block.h" />
     <ClInclude Include="BlockType.h" />
+    <ClInclude Include="Chat.h" />
+    <ClInclude Include="ChatHistory.h" />
+    <ClInclude Include="ChatMessage.h" />
     <ClInclude Include="Chunk.h" />
     <ClInclude Include="Constants.h" />
     <ClInclude Include="CraftingGrid.h" />

+ 21 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -53,6 +53,9 @@
     <Filter Include="Menu\uiml\recipies">
       <UniqueIdentifier>{68659053-193e-4113-8771-3df6b6a9c5c0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Menu\chat">
+      <UniqueIdentifier>{aa163982-63f3-4fe2-b13d-366055b56a00}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Main.cpp">
@@ -175,6 +178,15 @@
     <ClCompile Include="RecipieGroup.cpp">
       <Filter>Menu\uiml\recipies</Filter>
     </ClCompile>
+    <ClCompile Include="Chat.cpp">
+      <Filter>Menu\chat</Filter>
+    </ClCompile>
+    <ClCompile Include="ChatHistory.cpp">
+      <Filter>Menu\chat</Filter>
+    </ClCompile>
+    <ClCompile Include="ChatMessage.cpp">
+      <Filter>Menu\chat</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Area.h">
@@ -303,6 +315,15 @@
     <ClInclude Include="RecipieOutput.h">
       <Filter>Menu\uiml\recipies</Filter>
     </ClInclude>
+    <ClInclude Include="Chat.h">
+      <Filter>Menu\chat</Filter>
+    </ClInclude>
+    <ClInclude Include="ChatMessage.h">
+      <Filter>Menu\chat</Filter>
+    </ClInclude>
+    <ClInclude Include="ChatHistory.h">
+      <Filter>Menu\chat</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <FxCompile Include="DX11CustomVertexShader.hlsl">

+ 37 - 0
FactoryCraft/Game.cpp

@@ -2,6 +2,7 @@
 
 #include <AsynchronCall.h>
 #include <Bildschirm.h>
+#include <DateiSystem.h>
 
 #include "Globals.h"
 #include "Initialisierung.h"
@@ -63,6 +64,32 @@ Game::Game(Bildschirm* zScreen)
     itemListContainer = new ItemListContainer();
     window->zBildschirm()->addMember(
         dynamic_cast<Zeichnung*>(itemListContainer->getThis()));
+
+    chat = new Chat();
+    elements.add(chat);
+
+    LTDBDatei iconsDat;
+    iconsDat.setDatei(new Text("data/bilder/gui_icons.ltdb"));
+    iconsDat.leseDaten(0);
+
+    chatButton = uiFactory.createKnopf(uiFactory.initParam);
+    chatButton->setToolTipText("Chat", zScreen, uiFactory.initParam.schrift);
+    chatButton->setAlphaFeldFarbe(0x5F337AB7);
+    chatButton->setSize(40, 40);
+    chatButton->setPosition(5, zScreen->getBackBufferSize().y - 45);
+    chatButton->addStyle(
+        Framework::Knopf::Style::HBild | Framework::Knopf::Style::HAlpha |Framework::Knopf::Style::Hintergrund);
+    chatButton->setHintergrundBildZ(iconsDat.laden(0, new Text("chat.png")));
+    chatButton->setMausEreignis(
+        [this](void* p, void* o, Framework::MausEreignis me) {
+            if (me.id == ME_RLinks)
+            {
+                chat->addStyle(Fenster::Style::Sichtbar);
+                chatButton->removeStyle(Knopf::Style::Sichtbar);
+            }
+            return 1;
+        });
+    elements.add(chatButton);
 }
 
 Game::~Game()
@@ -258,4 +285,14 @@ bool Game::isItemListVisible()
 const Text* Game::zFilterText()
 {
     return filter->zText();
+}
+
+void Game::makeChatButtonVisible()
+{
+    chatButton->addStyle(Knopf::Style::Sichtbar);
+}
+
+Chat* Game::zChat() const
+{
+    return chat;
 }

+ 5 - 0
FactoryCraft/Game.h

@@ -7,6 +7,7 @@
 #include "DragController.h"
 #include "Menu.h"
 #include "ItemList.h"
+#include "Chat.h"
 
 class Player;
 class InventoryDragSource;
@@ -22,6 +23,8 @@ private:
     DragController<InventoryDragSource, int>* inventoryDragController;
     Framework::TextFeld* filter;
     ItemListContainer* itemListContainer;
+    Framework::Knopf* chatButton;
+    Chat* chat;
     bool recipieVisible;
 
 public:
@@ -39,4 +42,6 @@ public:
     void showItemList();
     bool isItemListVisible();
     const Text* zFilterText();
+    void makeChatButtonVisible();
+    Chat* zChat() const;
 };

+ 24 - 10
FactoryCraft/Initialisierung.cpp

@@ -10,13 +10,10 @@
 
 #include "Globals.h"
 
-Knopf* initKnopf(int x, int y, int br, int hö, __int64 style, char* titel)
+Knopf* createKnopf(const Framework::UIInitParam& params)
 {
-    Knopf* ret = uiFactory.createKnopf(uiFactory.initParam);
-    ret->addStyle(style);
-    ret->setPosition(x, y);
-    ret->setSize(br, hö);
-    ret->setText(titel);
+    Knopf* ret
+        = Framework::defaultUI(params.schrift, params.bildschirm).createKnopf(params);
     ret->setHintergrundFarbe(0xFF000000);
     ret->setRahmenFarbe(0xFF2E6DA4);
     ret->setSchriftFarbe(0xFFFFFFFF);
@@ -26,6 +23,27 @@ Knopf* initKnopf(int x, int y, int br, int h
     return ret;
 }
 
+TextFeld* createTextFeld(const Framework::UIInitParam& params)
+{
+    TextFeld* ret = Framework::defaultUI(params.schrift, params.bildschirm)
+                        .createTextFeld(params);
+    ret->setRahmenFarbe(0xFF6d6d6d);
+    ret->setHintergrundFarbe(0xFF000000);
+    ret->setAlphaFeldFarbe(0xFF3d3d3d);
+    ret->setAlphaFeldStrength(10);
+    return ret;
+}
+
+Knopf* initKnopf(int x, int y, int br, int hö, __int64 style, char* titel)
+{
+    Knopf* ret = uiFactory.createKnopf(uiFactory.initParam);
+    ret->addStyle(style);
+    ret->setPosition(x, y);
+    ret->setSize(br, hö);
+    ret->setText(titel);
+    return ret;
+}
+
 KontrollKnopf* initKontrollKnopf(
     int x, int y, int br, int hö, __int64 style, char* txt)
 {
@@ -58,10 +76,6 @@ TextFeld* initTextFeld(int x, int y, int br, int h
     ret->setText(txt);
     ret->setPosition(x, y);
     ret->setSize(br, hö);
-    ret->setRahmenFarbe(0xFF6d6d6d);
-    ret->setHintergrundFarbe(0xFF000000);
-    ret->setAlphaFeldFarbe(0xFF3d3d3d);
-    ret->setAlphaFeldStrength(10);
     return ret;
 }
 

+ 4 - 0
FactoryCraft/Initialisierung.h

@@ -8,6 +8,7 @@
 #include <initializer_list>
 #include <Knopf.h>
 #include <Tabelle.h>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
@@ -19,6 +20,9 @@ struct OBJTabelleSpalteIni
     int maxBreite;
 };
 
+Knopf* createKnopf(const Framework::UIInitParam& params);
+TextFeld* createTextFeld(const Framework::UIInitParam& params);
+
 Knopf* initKnopf(int x, int y, int br, int hö, __int64 style, char* titel);
 KontrollKnopf* initKontrollKnopf(
     int x, int y, int br, int hö, __int64 style, char* txt);

+ 3 - 0
FactoryCraft/Main.cpp

@@ -13,6 +13,7 @@
 
 #include "CustomDX11API.h"
 #include "Globals.h"
+#include "Initialisierung.h"
 
 void createModels(Bildschirm* zScreen);
 
@@ -168,6 +169,8 @@ int KSGStart Framework::Start(Framework::Startparam p)
     screen.setFillFarbe(0);
 
     uiFactory = Framework::defaultUI(fontRegister->get("normal"), &screen);
+    uiFactory.createKnopf = createKnopf;
+    uiFactory.createTextFeld = createTextFeld;
     initMenus();
 
     RenderTh rTh;

+ 7 - 0
FactoryCraft/World.cpp

@@ -110,6 +110,13 @@ void World::update(bool background)
                     }
                     break;
                 }
+            case 4: // chat message
+                {
+                    ((Game*)(Menu*)menuRegister->get("game"))
+                        ->zChat()
+                        ->addMessage(data + 1);
+                    break;
+                }
             }
             delete[] data;
             // TODO: process messages