View Single Post
  #2  
Old 08-01-2008, 05:08 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

My ISP web hosting is down for maintenance, so here is the patch:

Code:
diff -u --recursive ../EQEmu-0.7.0-1119/common/ruletypes.h ./common/ruletypes.h
--- ../EQEmu-0.7.0-1119/common/ruletypes.h      2008-08-01 19:38:04.000000000 +0100
+++ ./common/ruletypes.h        2008-08-01 19:37:31.000000000 +0100
@@ -141,6 +141,7 @@
 RULE_INT ( NPC, SayPauseTimeInSec, 5)
 RULE_INT ( NPC, OOCRegen, 0)
 RULE_BOOL ( NPC, BuffFriends, false )
+RULE_BOOL ( NPC, EnableNPCQuestJournal, false)
 RULE_CATEGORY_END()

 RULE_CATEGORY ( Aggro )
diff -u --recursive ../EQEmu-0.7.0-1119/zone/client.cpp ./zone/client.cpp
--- ../EQEmu-0.7.0-1119/zone/client.cpp 2008-05-31 05:12:30.000000000 +0100
+++ ./zone/client.cpp   2008-08-01 18:58:22.000000000 +0100
@@ -819,6 +819,47 @@
        safe_delete_array(buffer);
 }

+
+void Client::QuestJournalledMessage(const char *npcname, const char* message) {
+
+       // npcnames longer than 60 characters crash the client when they log back in
+       const int MaxNPCNameLength = 60;
+       // I assume there is an upper safe limit on the message length. Don't know what it is, but 4000 doesn't crash
+       // the client.
+       const int MaxMessageLength = 4000;
+
+       char OutNPCName[MaxNPCNameLength+1];
+       char OutMessage[MaxMessageLength+1];
+
+       // Apparently Visual C++ snprintf is not C99 compliant and doesn't put the null terminator
+       // in if the formatted string >= the maximum length, so we put it in.
+       //
+       snprintf(OutNPCName, MaxNPCNameLength, "%s", npcname); OutNPCName[MaxNPCNameLength]='\0';
+       snprintf(OutMessage, MaxMessageLength, "%s", message); OutMessage[MaxMessageLength]='\0';
+
+       uint32 len_packet = sizeof(SpecialMesg_Struct) + strlen(OutNPCName) + strlen(OutMessage);
+       EQApplicationPacket* app = new EQApplicationPacket(OP_SpecialMesg, len_packet);
+       SpecialMesg_Struct* sm=(SpecialMesg_Struct*)app->pBuffer;
+
+       sm->header[0] = 0;
+       sm->header[1] = 2;
+       sm->header[2] = 0;
+       sm->msg_type = 0x0a;
+       sm->target_spawn_id = GetID();
+
+       char *dest = &sm->sayer[0];
+
+       sprintf(dest, "%s", OutNPCName);
+
+       dest = dest + strlen(OutNPCName) + 13;
+
+       sprintf(dest, "%s", OutMessage);
+
+       QueuePacket(app);
+
+       safe_delete(app);
+}
+
 void Client::SetMaxHP() {
        if(dead)
                return;
diff -u --recursive ../EQEmu-0.7.0-1119/zone/client.h ./zone/client.h
--- ../EQEmu-0.7.0-1119/zone/client.h   2008-06-15 00:07:57.000000000 +0100
+++ ./zone/client.h     2008-07-31 16:29:25.000000000 +0100
@@ -216,6 +216,7 @@
        void    ChannelMessageReceived(int8 chan_num, int8 language, const char* message, const char* targetname=NULL);
        void    ChannelMessageSend(const char* from, const char* to, int8 chan_num, int8 language, const char* message, ...);
        void    Message(int32 type, const char* message, ...);
+       void    QuestJournalledMessage(const char *npcname, const char* message);
        void    SendSound();

        int32   GetAdventureID() const {return 0/*m_pp.adventure_id*/; }
diff -u --recursive ../EQEmu-0.7.0-1119/zone/entity.cpp ./zone/entity.cpp
--- ../EQEmu-0.7.0-1119/zone/entity.cpp 2008-07-21 19:58:29.000000000 +0100
+++ ./zone/entity.cpp   2008-07-31 18:53:45.000000000 +0100
@@ -1151,6 +1151,30 @@
        }
 }

+
+void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator, float dist, const char* mobname, const char* message)
+{
+       Client *c;
+       LinkedListIterator<Client*> iterator(client_list);
+       float dist2 = dist * dist;
+
+       // Send the message to the quest initiator such that the client will enter it into the NPC Quest Journal
+       if(QuestInitiator) {
+
+               char *buf = new char[strlen(mobname) + strlen(message) + 10];
+               sprintf(buf, "%s says, '%s'", mobname, message);
+               QuestInitiator->QuestJournalledMessage(mobname, buf);
+               safe_delete_array(buf);
+       }
+       // Use the old method for all other nearby clients
+       for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
+       {
+               c = iterator.GetData();
+               if(c && (c != QuestInitiator) && c->DistNoRoot(*sender) <= dist2)
+                       c->Message_StringID(10, GENERIC_SAY, mobname, message);
+       }
+}
+
 //sender can be null
 void EntityList::QueueClients(Mob* sender, const EQApplicationPacket* app, bool ignore_sender, bool ackreq) {
        LinkedListIterator<Client*> iterator(client_list);
diff -u --recursive ../EQEmu-0.7.0-1119/zone/entity.h ./zone/entity.h
--- ../EQEmu-0.7.0-1119/zone/entity.h   2008-05-30 23:44:12.000000000 +0100
+++ ./zone/entity.h     2008-07-31 16:44:22.000000000 +0100
@@ -204,6 +204,7 @@
        void    MessageClose(Mob* sender, bool skipsender, float dist, int32 type, const char* message, ...);
        void    Message_StringID(Mob *sender, bool skipsender, int32 type, int32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0);
        void    MessageClose_StringID(Mob *sender, bool skipsender, float dist, int32 type, int32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0);
+       void    QuestJournalledSayClose(Mob *sender, Client *QuestIntiator, float dist, const char* mobname, const char* message);
        void    ChannelMessageFromWorld(const char* from, const char* to, int8 chan_num, int32 guilddbid, int8 language, const char* message);
        void    ChannelMessage(Mob* from, int8 chan_num, int8 language, const char* message, ...);
        void    ChannelMessageSend(Mob* to, int8 chan_num, int8 language, const char* message, ...);
diff -u --recursive ../EQEmu-0.7.0-1119/zone/mob.cpp ./zone/mob.cpp
--- ../EQEmu-0.7.0-1119/zone/mob.cpp    2008-06-15 00:07:57.000000000 +0100
+++ ./zone/mob.cpp      2008-07-31 16:40:05.000000000 +0100
@@ -2019,6 +2019,13 @@
                GENERIC_SAY, GetCleanName(), buf);
 }

+
+void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str)
+{
+
+        entity_list.QuestJournalledSayClose(this, QuestInitiator, 200, GetCleanName(), str);
+}
+
 //
 // solar: this is like the above, but the first parameter is a string id
 //
diff -u --recursive ../EQEmu-0.7.0-1119/zone/mob.h ./zone/mob.h
--- ../EQEmu-0.7.0-1119/zone/mob.h      2008-06-19 15:56:51.000000000 +0100
+++ ./zone/mob.h        2008-07-31 16:40:34.000000000 +0100
@@ -550,6 +550,7 @@
        virtual void    Message_StringID(int32 type, int32 string_id, int32 distance = 0) {}
        virtual void    Message_StringID(int32 type, int32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0, const char* message9=0, int32 distance = 0) {}
        void Say(const char *format, ...);
+       void QuestJournalledSay(Client *QuestInitiator, const char *str);
        void Say_StringID(int32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0);
        void Shout(const char *format, ...);
        void Emote(const char *format, ...);
diff -u --recursive ../EQEmu-0.7.0-1119/zone/questmgr.cpp ./zone/questmgr.cpp
--- ../EQEmu-0.7.0-1119/zone/questmgr.cpp       2008-06-15 00:07:57.000000000 +0100
+++ ./zone/questmgr.cpp 2008-07-31 18:17:01.000000000 +0100
@@ -73,6 +73,7 @@
 #include "parser.h"
 #include "event_codes.h"
 #include "guild_mgr.h"
+#include "../common/rulesys.h"


 extern Zone* zone;
@@ -193,7 +194,11 @@
 }

 void QuestManager::say(const char *str) {
-       owner->Say(str);
+
+       if(RuleB(NPC, EnableNPCQuestJournal) && initiator)
+               owner->QuestJournalledSay(initiator, str);
+       else
+               owner->Say(str);
 }

 void QuestManager::me(const char *str) {
Reply With Quote