EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   Client popup window (like in the tutorial zone) (https://www.eqemulator.org/forums/showthread.php?t=26012)

Derision 08-25-2008 11:50 AM

Client popup window (like in the tutorial zone)
 
Discussion: http://eqemulator.net/forums/showthread.php?t=26312

This patch allows the quest system to send a 'popup' window to the client as you see in the tutorial zone.

Patch against the code from KLS' SVN on googlecode:

Code:

diff -u --recursive ../kikiaemu-read-only/common/eq_packet_structs.h ./common/eq_packet_structs.h
--- ../kikiaemu-read-only/common/eq_packet_structs.h    2008-08-25 15:39:01.000000000 +0100
+++ ./common/eq_packet_structs.h        2008-08-25 16:14:21.000000000 +0100
@@ -2929,6 +2929,16 @@
        uint8  unknown5;
 };

+// 4244 bytes. Is not really an 'OnLevelMessage', it causes a popup box to display in the client
+// Text looks like HTML.
+struct OnLevelMessage_Struct {
+/*0000*/      char    Title[128];
+/*0128*/      char    Text[4100];
+/*4228*/      uint32  unknown4228;
+/*4232*/      uint32  unknown4232;
+/*4236*/      uint32  unknown4236;
+/*4240*/      uint32  unknown4240;
+};

 struct BankerChange_Struct {
        uint32  platinum;
diff -u --recursive ../kikiaemu-read-only/utils/patch_Titanium.conf ./utils/patch_Titanium.conf
--- ../kikiaemu-read-only/utils/patch_Titanium.conf    2008-08-25 15:41:12.000000000 +0100
+++ ./utils/patch_Titanium.conf 2008-08-25 16:14:48.000000000 +0100
@@ -448,7 +448,7 @@
 OP_OpenDiscordMerchant=0x0000  #8 bytes
 OP_DiscordMerchantInventory=0x0000    #long item packet
 OP_GiveMoney=0x0000    #16 bytes, pp, gp, sp, cp.
-OP_OnLevelMessage=0x0000
+OP_OnLevelMessage=0x1dde
 OP_RequestKnowledgeBase=0x0000
 OP_KnowledgeBase=0x0000
 OP_SlashAdventure=0x571a      # /adventure
diff -u --recursive ../kikiaemu-read-only/zone/client.cpp ./zone/client.cpp
--- ../kikiaemu-read-only/zone/client.cpp      2008-08-25 15:43:43.000000000 +0100
+++ ./zone/client.cpp  2008-08-25 16:13:25.000000000 +0100
@@ -3276,3 +3276,22 @@
        safe_delete(outapp);
 }

+void Client::SendPopupToClient(char *Title, char *Text) {
+
+      EQApplicationPacket *outapp = new EQApplicationPacket(OP_OnLevelMessage, sizeof(OnLevelMessage_Struct));
+      OnLevelMessage_Struct *olms = (OnLevelMessage_Struct *) outapp->pBuffer;
+
+      if((strlen(Title) > (sizeof(olms->Title)-1)) ||
+          (strlen(Text) > (sizeof(olms->Text)-1))) return;
+
+      strcpy(olms->Title, Title);
+      strcpy(olms->Text, Text);
+
+      olms->unknown4228 = 0xffffffff;
+      olms->unknown4232 = 0xffffffff;
+      olms->unknown4236 = 0x00000000;
+      olms->unknown4240 = 0xffffffff;
+
+      QueuePacket(outapp);
+      safe_delete(outapp);
+}
diff -u --recursive ../kikiaemu-read-only/zone/client.h ./zone/client.h
--- ../kikiaemu-read-only/zone/client.h 2008-08-25 15:43:43.000000000 +0100
+++ ./zone/client.h    2008-08-25 16:12:45.000000000 +0100
@@ -684,6 +684,7 @@
        int FindSpellBookSlotBySpellID(int16 spellid);
        int GetNextAvailableSpellBookSlot();
        int16  GetMaxSkillAfterSpecializationRules(SkillType skillid, int16 maxSkill);
+      void SendPopupToClient(char *Title, char *Text);


 protected:
diff -u --recursive ../kikiaemu-read-only/zone/perlparser.cpp ./zone/perlparser.cpp
--- ../kikiaemu-read-only/zone/perlparser.cpp  2008-08-25 15:43:43.000000000 +0100
+++ ./zone/perlparser.cpp      2008-08-25 16:11:17.000000000 +0100
@@ -1756,6 +1756,17 @@
        XSRETURN_EMPTY;
 }

+XS(XS__popup); // prototype to pass -Wmissing-prototypes
+XS(XS__popup) {
+      dXSARGS;
+
+      if (items != 2)
+              Perl_croak(aTHX_ "Usage: popup(windowtitle, text)");
+
+      quest_manager.popup(SvPV_nolen(ST(0)), SvPV_nolen(ST(1)));
+
+      XSRETURN_EMPTY;
+}
 /*

 This is the callback perl will look for to setup the
@@ -1880,6 +1891,7 @@
                newXS(strcpy(buf, "playergender"), XS__playergender, file);
                newXS(strcpy(buf, "playersize"), XS__playersize, file);
                newXS(strcpy(buf, "playertexture"), XS__playertexture, file);
+              newXS(strcpy(buf, "popup"), XS__popup, file);
        XSRETURN_YES;
 }

diff -u --recursive ../kikiaemu-read-only/zone/questmgr.cpp ./zone/questmgr.cpp
--- ../kikiaemu-read-only/zone/questmgr.cpp    2008-08-25 15:43:43.000000000 +0100
+++ ./zone/questmgr.cpp 2008-08-25 16:12:16.000000000 +0100
@@ -1387,4 +1387,9 @@
 void QuestManager::playertexture(int newtexture)
 {
                        initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture);
-}
\ No newline at end of file
+}
+
+void QuestManager::popup(char *title, char *text) {
+
+      if(initiator) initiator->SendPopupToClient(title, text);
+}
diff -u --recursive ../kikiaemu-read-only/zone/questmgr.h ./zone/questmgr.h
--- ../kikiaemu-read-only/zone/questmgr.h      2008-08-25 15:43:43.000000000 +0100
+++ ./zone/questmgr.h  2008-08-25 16:11:41.000000000 +0100
@@ -146,6 +146,7 @@
        void playergender(int gender_id);
        void playersize(int newsize);
        void playertexture(int newtexture);
+      void popup(char *title, char *text);

        //not in here because it retains perl types
        //thing ChooseRandom(array_of_things)

To use it, from a Perl quest:

Code:

quest::popup("Join the revolution!", "<br>&nbsp;&nbsp; &nbsp;&nbsp;Welcome to the Mines of Gloomingdeep. Your fellow captives
                                      need your help to fight the kobolds.  When you are ready to leave the tutorial, talk to
                                      Arias and he will show you the way to your home city.  Should you decide to leave, you
                                      will be able to return to the tutorial from the character select screen until you are
                                      level ten.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;If you need to refresh your memory on topics
                                      that we have already covered, feel free to click on the question mark icon on the
                                      <c \"#00A000\">Toolbar</c> located at the top of your screen.
                                      <br ><br>&nbsp;&nbsp;&nbsp;&nbsp;<c \"#F07F00\">Click 'OK' to continue .</c>");

Note that I broke the example up onto multiple lines for readability. It all needs to be on one line in your quest (unless you can have multiline strings in Perl).

The first argument is the window title, the second is the text to display in the window, which looks like HTML. The above example comes out looking like this:

http://www.rama.demon.co.uk/popup.jpg

Only one popup can be active at a time. If you send another while one is already up, it will overwrite the one already showing.

OP_OnLevelMessage needs to be changed from 0x0000 to 0x1dde in patch_Titanium.conf (same value as is already in patch_6.2.conf)

Derision 08-26-2008 03:17 PM

My guess was right, the text field is 4096 bytes, so the struct is actually this:

Code:

struct OnLevelMessage_Struct {
/*0000*/        char    Title[128];
/*0128*/        char    Text[4096];
/*4224*/        uint32  Buttons;
/*4228*/        uint32  unknown4228;
/*4232*/        uint32  PopupID;
/*4236*/        uint32  unknown4236;
/*4240*/        uint32  unknown4240;
};

If buttons = 0, just the OK button is displayed and this sends the opcode when pressed.

If buttons = 1, Yes and No buttons are displayed. Clicking Yes sends the opcode, clicking No does nothing.

If buttons = 256, the OK button is displayed, along with the MP3 Player controls!


All times are GMT -4. The time now is 12:04 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.