EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Q&A (https://www.eqemulator.org/forums/forumdisplay.php?f=599)
-   -   Question about updating existing Quests... (https://www.eqemulator.org/forums/showthread.php?t=31005)

kameko 04-10-2010 05:33 PM

Question about updating existing Quests...
 
Hello,

I'm just new to setting up a server and as of now I have working setup using the latest files. I did create a character on EZ Server first and noticed that when speaking with NPCs the text from them was a different color and that the response text was clickable. I really like this idea.

So, I did a bit of research, and I now know how to do this myself (using quest::saylink() )

I am wondering if anyone has taken the time, or wrote some kind of program to automatically update all the quest files to use saylink ?

I could probably write a program to do this, but I was wondreing if it's been done already.

Thanks,

Kameko

trevius 04-10-2010 05:45 PM

I don't think anyone has made anything to make saylinks for you. Some need to be made manually anyway for certain scenarios.

For the whispers from NPCs that are different colors and only go directly to the player, you can add this plugin:

http://www.eqemulator.org/forums/showthread.php?t=30448

kameko 04-14-2010 02:01 PM

I did it!

I wrote a program to update all the quests.

What my program does is scan through the file and pick out everything between
[ and ].

Then I make a variable out of this and update the quest file. Kinda hard to explain, so I'll post a sample file...

Before:
Code:

sub EVENT_SAY {
if($text=~/Hail/i){
quest::say("Oh hello. $name.  My name is Ilscent.  I am glad to see you. but I am in a bit of a [bind] right now.");
}
if($text=~/what bind/i){
quest::say("Well. I promised an ally of ours that I would send him a case of Jumjum juice for all the help he has given us.  I had planned on taking it to him myself but I have too many chores to do here on the farm. Will you take the [jumjum juice] to him?");
}
if($text=~/jumjum juice/i){
quest::say("Oh. thank you so much!  His name is Xanuusus and he lives in the Plains of Karana. in the foothills along their northern edge. actually.  We are most grateful for your help.  Xanuusus normally rewards messengers well.");
quest::summonitem("13411");
 }
}
#END of FILE Zone:rivervale  ID:19102 -- Ilscent_Tagglefoot

and After:

Code:

my $jumjum_juice = quest::saylink("jumjum juice", 0, "jumjum juice");
my $bind = quest::saylink("what bind", 0, "bind");
sub EVENT_SAY {
if($text=~/Hail/i){
plugin::Whisper("Oh hello. $name.  My name is Ilscent.  I am glad to see you. but I am in a bit of a $bind right now.");
}
if($text=~/what bind/i){
plugin::Whisper("Well. I promised an ally of ours that I would send him a case of Jumjum juice for all the help he has given us.  I had planned on taking it to him myself but I have too many chores to do here on the farm. Will you take the $jumjum_juice to him?");
}
if($text=~/jumjum juice/i){
plugin::Whisper("Oh. thank you so much!  His name is Xanuusus and he lives in the Plains of Karana. in the foothills along their northern edge. actually.  We are most grateful for your help.  Xanuusus normally rewards messengers well.");
quest::summonitem("13411");
 }
}
#END of FILE Zone:rivervale  ID:19102 -- Ilscent_Tagglefoot

This program is not perfect! This is still a work in progress and I am hoping that some of you guys will download it and test it out yourself.

http://tigerstudios.net/QuestUpdater.zip

place the exe in the quest directory, and run it there. It will go through every file that ends in .pl in that directory, and every directory within that one.

I recommend making a backup of your quest files first.

If you are running windows vista or 7 it will need admin to run it, I'm not sure why it does, but I think it is due to file access. I'm looking into it.

I have tested this in rivervale with a new halfling and it works great so far.

It also changes quest::say to plugin::Whisper. I found this makes reading the text in game a bit easier.

If there is enough support and interest in this I will continue working on it and make a GUI for it with configurable options.

Just let me know.

Thanks,

Kameko

pfyon 04-14-2010 04:12 PM

What language did you write it in? Any chance of releasing the source?

I worked a bit on something like this a few months ago in perl, just to change quest::say() into quest::say(,langid) to make different mobs talk different languages, but didn't go anywhere with it.

kameko 04-14-2010 06:42 PM

Hello,

I wrote it in C++

two files...

main.cpp
Code:

#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/string.h>
#include <wx/textfile.h>
#include <wx/ffile.h>
#include <conio.h>
#include <stdio.h>

#include "CDirTraverser.h"

void ProcessFile(const wxString& filename);

int main()
{
        int                iStatus = 0;
        int                iProcessedFiles = 0;

        wxDir        dir(wxGetCwd());
        wxArrayString        files;

        CDirTraverser traverser(files);
        dir.Traverse(traverser);
       
        for(int i = 0; i < files.GetCount(); i++)
                ProcessFile(files[i]);

        printf("Done\n");
       
        while(!_kbhit()) {}

        return iStatus;
}



void ProcessFile(const wxString& filename)
{
        wxTextFile tFile;
        wxArrayString        variableList;
        wxArrayString        asTag1, asTag2, asTag3;
        wxArrayString        asTempTag2;

        // tag1 will be the variable name
        // tag2 is what your character will say
        // tag3 is what will be displayed on screen
        wxString        tag1, tag2, tag3;

        tFile.Open(filename);
       
        tFile.AddLine(wxT(" "));
        tFile.AddLine(wxT(" "));
        tFile.AddLine(wxT(" "));

        for(int i = 0; i < tFile.GetLineCount();i++)
        {
                // Swap out quest::say for plugin::Whisper
                if(tFile[i].Contains(wxT("quest::say")))
                        tFile[i].Replace(wxT("quest::say"), wxT("plugin::Whisper"));


                while(tFile[i].Contains('['))
                {
                        wxString temp1 = tFile[i].AfterFirst('[');
                        tag3 = temp1.BeforeFirst(']');
                       
                        tag1 = tag3;
                        if(tag1.Contains(' '))
                                tag1.Replace(wxT(" "), wxT("_"));
                        if(tag1.Contains("'"))
                                tag1.Replace(wxT("'"), wxT("_"));

                       
                        // Add tag1 and tag3 to thier arraystrings
                        asTag1.Add(tag1);
                        asTag3.Add(tag3);

                        // Remove the first [ in the line and replace with $
                        // Remove the first ] in the line.
                        tFile[i].Replace(tag3, "", false);
                        tFile[i].Replace("[", "$" + tag1, false);
                        tFile[i].Replace("]", "", false);

                } // while(tFile[i].Contains('['))
               
                // Get a list of possible tag2 strings
                if(tFile[i].Contains("$text=~/"))
                {
                        wxString temp = tFile[i].AfterFirst(wxT('/'));
                        asTempTag2.Add(temp.BeforeFirst(wxT('/')));
                }
        } // for(int i = 0; i < tFile.GetLineCount();i++)

        // Need to go through the file again and get tag2
        for(int i = 0; i < asTag3.Count(); i++)                                // For every tag3 look for a
        {                                                                                                        // matching string
                for(int j = 0; j < asTempTag2.Count(); j++)
                {
                        if(asTempTag2[j].Contains(asTag3[i]))
                        {
                                variableList.Add("my $" + asTag1[i] + " = quest::saylink(\""+ asTempTag2[j] + "\", 0, \"" + asTag3[i] + "\");");
                        }
                } // for(int j = 0; j < asTempTag2.Count(); j++)
        } // for(int i = 0; i < asTag3.Count(); i++)
               
        // Now add the variablelist to the begining of the file
        for(int i = 0; i < variableList.Count(); i++)
                tFile.InsertLine(variableList[i], 0);

        puts(filename + "...done!");
       
        tFile.Write();
        tFile.Close();

        return;
}

and
CDirTraverser.h
Code:

#pragma once

#include <wx\dir.h>

class CDirTraverser :
        public wxDirTraverser
{
public:
        CDirTraverser(wxArrayString& files) : m_files(files) { }
       
        virtual wxDirTraverseResult OnFile(const wxString& filename);
        virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname));
   
        private:
        wxArrayString& m_files;
};

CDirTraverser.cpp
Code:

#include "CDirTraverser.h"

wxDirTraverseResult CDirTraverser::OnFile(const wxString& filename)
{
        if(filename.EndsWith(wxT(".pl")))
        {
                m_files.Add(filename);
                //ProcessFile(filename);
        }
        return wxDIR_CONTINUE;
}

wxDirTraverseResult CDirTraverser::OnDir(const wxString& WXUNUSED(dirname))
{
        return wxDIR_CONTINUE;
}

I have been playing around with wxWidgets for other programming projects, so used some things from it in this code.

It's messy right now... I just hacked this together over the last 2 days. I'll be cleaning it up soon. Been actually playing eq now that I can click on links and not have to type them in!

oh, I have noticed just one thing that this code does affect, the npc quest journal in game isn't getting updated because npcs are now whispering to you... I'll look into this later on

Enjoy

Kameko


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

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