View Single Post
  #1  
Old 08-15-2004, 04:18 AM
Cisyouc
Demi-God
 
Join Date: Jun 2004
Location: Heaven.
Posts: 1,260
Default LDoN Recruiter v0.1 Beta (MMC)

Hello, all!
After noticing that many server's haven't really used the LDoN zones, I decided to take up this project to create an adventure recruiter using only (if I can), Perl Quests. After a few days of tinkering with it, making it as easy as I can to set up, I have created a system that is NOT PERFECT BY ANY MEANS!! Compared to the EQLive system it is very inefficient and buggy. Here is a discription of what it does.

One of the main problems with this system is that LDoNs usually have mobs designated for your level. This system cannot do that, so if you use this, it is suggested that each dungeon be suited for a certain level range.

Sample (I cant give out a definate chart as everyone has a different max level):

MMCA for levels 10-15
MMCB for levels 15-20 (or hard version of mmca)
MMCC for levels 25-30 (or hard version of mmcb)
MMCD for levels 35-40 (or hard version of mmcc)
MMCE for levels 45-50 (or hard version of mmcd)
MMCF for levels 50-55 (or hard version of mmce)
MMCG for levels 55-60 (or hard version of mmcf)
MMCH for levels 60-65 (or hard version of mmcg)
MMCI for levels 65-70 (or 65+ if thats your max)
MMCJ for levels 70-75 (or 65+ if thats your max)

BETA VERSION is only for Mistmoore Catacombs. Once I work some bugs out I will make a .zip version for each theme.

So this is how it works:
Quote:
You say, 'Hail, Mistmoore Adventure Recruiter.'

Mistmoore Adventure Recruiter says, 'Greetings $name! The Wayfarer's Brotherhood is looking for new recruits to head into the Lost Dungeons of Norrath. Are you a young [adventurer]?'

You say, 'I am an adventurer.'

The Lost Dungeons that currently have no explorer's inside are:
The [Forlorn Caverns]
The [Dreary Grotto]
The [Asylum of Invoked Stone]
The [Chambers of Eternal Affliction]
The [Sepulcher of the Damned]
The [Ritualistic Summoning Ground]
The [Cesspits of Putresence]
The [Aisles of Blood]
The [Halls of Sanguinary Rites]
The [Infernal Sanctuary]
You will recieve XX adventure points from an adventure.
(XX would be replaced with player level minus 5)

You say, 'Forlorn Caverns'
Your Dungeon has NOT yet began. You must speak with the dungeon master to start.

(Forlorn Caverns is removed from the 'adventurer' list and if someone were to say 'forlorn caverns' they get a message saying that dungeon is not available.)
(Player is sent into the Forlorn Caverns)

You say, 'Hail, Dungeon Master'
Dungeon Master says, 'Thank Mithaniel, You're here $name! When you're ready to begin killing I will [start] the timer for you. Remember to come back to me when you're done to [end] the adventure, otherwise you won't be able to request a new adventure.'

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expirerence!!
[ERROR]
You did not start the timer at the Dungeon Master located at the zone in! You did NOT Recieve Bonus Expierence for this kill and this kill did NOT count toward your reward.

You say, 'Start'
Your dungeon has began.

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
You have killed 1/50 Required Monsters.
You gain expierence!!
Bonus expierence was awarded for this kill.

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
You have killed 2/50 Required Monsters.
You gain expierence!!
Bonus expierence was awarded for this kill.

(...more kills pass...)

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
You have killed 49/50 Required Monsters.
You gain expierence!!
Bonus expierence was awarded for this kill.

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
You have completed your adventure!
You have recieved XX points for your adventure!
Please return to the dungeon master to exit.

You say, 'Hail, Dungeon Master.'
Dungeon Master says, 'Thank you for completing this dungeon!'
(You are sent into Butcherblock at Recruiter.)
(Forlorn Caverns is back on the 'adventurer' list)
(All variables for kills and the like are back to 0)
Like EQLive, I have implemented an Hour and 30 Minute Timer, but it works a little different.

Lets say you are killing in a dungeon...
Quote:
You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
You have killed 32/50 Required Monsters.
You gain expierence!!
Bonus expierence was awarded for this kill.

(Time Expires)

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
Your 1 Hour and 30 Minute Timer has expired. Please go to the dungeon master to end the dungeon. No Bonus Expierence was Awarded for this kill.

You slash A Scion Swirlything for 20000 points of damage!
You have slain A Scion Swirlything!
You gain expierence!!
Your 1 Hour and 30 Minute Timer has expired. Please go to the dungeon master to end the dungeon. No Bonus Expierence was Awarded for this kill.

You say, 'Hail, Dungeon Master'
Dungeon Master says, 'Hello Again, $name. You may [end] this dungeon if it need be now.'

You say, 'End'

Dungeon Master says, 'Thanks for the help!'
(Forlorn Caverns is put back on the list.)
(All variables are reset to 0.)
Now lets say someone in the group DID NOT /say end the adventure, it CAN mess up the adventure recruiter because they expect you to still be in there. However, once the timer runs out all but 2 variables are reset to 0, and 1 of them will automatically change 1:40:00 after the adventure was /say start'd. (and that is the variable that tells the recruiter if its empty. 0 for yes, 1 for no). The other one just tells the Dungeon Master what to say on hail. So when the next group comes, when they hail the Dungeon Master to start the adventure, they will automatically be ported back to BB as if they won the adventure (no points awarded). All they have to do is ask for Forlorn Caverns again, and they can continue playing.

========================
DEBUGGING
========================

Because the system has many flaws, I have implemented for GMs or whoever is setting up the quest wants, a DEBUG feature. What this basically does is reset's all the variables back to 0. There is a debug feature on both the Adventure Recruiter and Dungeon Master. Its DEFAULT MINIMUM STATUS to allow you to debug is 200, but you can change that on this line found in both quest pages:
Code:
if($text=~/debug/i)
  {
  if($status >= 200)
    {
Once debugged on both NPC's, the adventure system is all clear, meaning that all dungeons will be available on the recruiter, the timer in the dungeon has been stopped, and kills has been reset to 0 (as if it has been /say end'd fine).

========================
Installation
========================
To install this on your server you must HAVE the following.
  • quest_globals.sql sourced into your database.
  • Knowledge of targlobal(), setglobal(), delglobal();
  • Knowledge of how to compile an EQEMu Source (You WONT need to, but if you don't know how to compile you probably won't understand my guide.)
  • Knowledge of EQEMu itself.
  • Preferably, access to the following commands: #zone, #spawn, #npcspawn, or a ZoneViewer and Access to the Database.
  • Access to ./quests

Now, to begin, you will need to:
  • Spawn an Adventure Recruiter in Butcherblock. EQLive (and default for this quest) is "Xyzelauna_Tu`Valzir", a level 65 Dark Elf Warrior, texture 3 helm 2, located at ButcherBlock -2493, -1124, -5.3 heading 6.0.
  • Spawn a Dungeon Master at the zone-in of every dungeon. (mmca, mmcb, mmcc, mmcd, mmce, mmcf, mmcg, mmch, mmci, mmcj.) It is suggested you make this npc level 255 or something, hence, unkillable.
  • Spawn at LEAST 50 (unless you change the amount of needed mobs to win) mobs per dungeon. Use the EQEMu guidebook for ldon _chr models and numbers.

Each type of mob should be inserted so the npc type itself has the same npc_types id.

EVERY NPC TYPE ID that is in a dungeon (mmca, mmcb, mmcc, etc..) and is a MOB that you are supposed to kill MUST have this quest attached to it.

Along with the quest, EVERY NPC TYPE ID must have qglobal to "1". Whether its a mob being killed, the dungeon master or the Recruiter. it MUST have qglobal ON (which is "1").

The quest you have to put for the MOBS-TO-BE-KILLED in the dungeons is this:
Code:
###################################################################
#Cisyouc`s Zone Instancing System                                 
#Lost Dungeons of Norrath					  
#Created by CISYOUC of Prexus II				  
#For Development of Any Server on the EQEMulator.net Network.	  
#Please do not remove this header.				  
#								  
#NPCID               : 000000					  
#ZONE                : mmca - mmcj				  
#NPC USAGE           : Adventure Mob 			          
###################################################################
sub EVENT_DEATH
{
if($done == 0)
  {
  if($began == 1)
    {
    if($kills <= 49)
      {
      $remaining = ((50-$kills));
      quest::setglobal("kills",$kills + 1,"3","T013000");
      quest::me("You have killed $kills/50 Required Monsters.");
      $calcexp1 = (($ulevel*5));
      $bonusexp = (($calcexp1*1000));
      quest::exp($bonusexp);
      quest::me("Bonus Expierence was Awarded for this kill.");
      }
    if($kills == 50)
      {
      $calc2 = (($ulevel-5));
      quest::addldonpoints($calc2,3);
      quest::me("You have completed your Adventure!");
      quest::me("You have recieved $calc2 points for your adventure!");
      quest::me("Please return to the Dungeon Master to exit.");
      quest::setglobal("gotpoints","1","3","T010000");
      }
    if($kills >= 51)
      {
      quest::me("You have killed $kills/50 Required Monsters.");
      quest::me("You have already won this adventure; no bonus expierence was awarded and this kill did NOT count toward an adventure point reward.");
      }
    }
   if($began == 0)
     {
     quest::me("[ERROR]");
     quest::me("You did not start the timer at the Dungeon Master located at the zone in! You did NOT Recieve Bonus Expierence for this kill and this kill did NOT count toward your reward.");
     }
   }
   if($done == 1)
     {
     quest::me("[ERROR]");
     quest::me("Your 1 Hour and 30 Minute Timer has expired. Please go to the dungeon master to end the dungeon. No Bonus Expierence was Awarded for this kill.");
     }
   }
}
########################################################
#END
For the Adventure Recruiter:
Code:
###################################################################
#Cisyouc`s Zone Instancing System                                 
#Lost Dungeons of Norrath					  
#Created by CISYOUC of Prexus II				  
#For Development of Any Server on the EQEMulator.net Network.	  
#Please do not remove this header.				  
#								  
#NPCID               : 000000					  
#ZONE                : butcher					  
#NPC USAGE           : Adventure Recruiter			  
###################################################################
#
sub EVENT_SAY
{
if($adven == 0){
if($ulevel >= 10){
if($text=~/hail/i)
  {
  quest::say("Greetings $name! The Wayfarer's Brotherhood is looking for new recruits to head into the Lost Dungeons of Norrath. Are you a young [adventurer]?");
  }
if($text=~/adventurer/i)
  {
     quest::me("The Lost Dungeons that currently have no explorer's inside are:");
     
   if($mmca == 0)
     {
     quest::me("The [Forlorn Caverns]");
     }
   if($mmcb == 0)
     {
     quest::me("The [Dreary Grotto]");
     }
   if($mmcc == 0)
     {
     quest::me("The [Asylum of Invoked Stone]");
     }
   if($mmcd == 0)
     {
     quest::me("The [Chambers of Eternal Afflictions]");
     }
   if($mmce == 0)
     {
     quest::me("The [Sepulcher of the Damned]");
     }
   if($mmcf == 0)
     {
     quest::me("The [Ritualistic Summoning Ground]");
     }
   if($mmcg == 0)
     {
     quest::me("The [Cesspits of Putresence]");
     }
   if($mmch == 0)
     {
     quest::me("The [Aisles of Blood]");
     }
   if($mmci == 0)
     {
     quest::me("The [Halls of Sanguinary Rites]");
     }
   if(mmcj == 0)
     {
     quest::me("The [Infernal Sanctuary]");
     }
     $result = (($ulevel-5));
     quest::me("Your level allows you to get $result points from this adventure.");
     
  }
if($text=~/forlorn caverns/i)
  {
  if($mmca == 0)
    {
    quest::targlobal("mmca","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");
    quest::movegrp(233,-589,-383,8.05);
    }
  if($mmca == 1)
    {
    quest::me("''mmca'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/dreary grotto/i)
  {
  if($mmcb == 0)
    {
    quest::targlobal("mmcb","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(238,-525,-26,23.67);
    }
  if($mmcb == 1)
    {
    quest::me("''mmcb'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/Asylum of Invoked Stone/i)
  {
  if($mmcc == 0)
    {
    quest::targlobal("mmcc","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(243,1229,510,-3.12);
    }
  if($mmcc == 1)
    {
    quest::me("''mmcc'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/Chambers of Eternal Affliction/i)
  {
  if($mmcd == 0)
    {
    quest::targlobal("mmcd","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(248,-228,-589,1.08);
    }
  if($mmcd == 1)
    {
    quest::me("''mmcd'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/sepulcher of the damned/i)
  {
  if($mmce == 0)
    {
    quest::targlobal("mmce","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(253,-578,330,1.11);
    }
  if($mmce == 1)
    {
    quest::me("''mmce'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/ritualistic summoning ground/i)
  {
  if($mmcf == 0)
    {
    quest::targlobal("mmcf","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(258,-167,400,-12.13);
    }
  if($mmcf == 1)
    {
    quest::me("''mmcf'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }

if($text=~/cesspits of putrescence/i)
  {
  if($mmcg == 0)
    {
    quest::targlobal("mmcg","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(263,425,405,3.82);
    }
  if($mmcg == 1)
    {
    quest::me("''mmcg'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/aisles of blood/i)
  {
  if($mmch == 0)
    {
    quest::targlobal("mmch","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(268,-340,-331,20.35);
    }
  if($mmch == 1)
    {
    quest::me("''mmch'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/halls of sanguinary rites/i)
  {
  if($mmci == 0)
    {
    quest::targlobal("mmci","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(272,592,-283,3.78);
    }
  if($mmci == 1)
    {
    quest::me("''mmci'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
  }
if($text=~/infernal sanctuary/i)
  {
  if($mmcj == 0)
    {
    quest::targlobal("mmcj","1","T014500",68134,$charid,68);
    quest::setglobal("adven","1","5","T013000");
    quest::me("Your Dungeon has NOT yet began. You must speak with the dungeon master to start.");

    quest::movegrp(276,227,538.3.87);
    }
  if($mmcj == 1)
    {
    quest::me("''mmcj'' is currently in use at this time. After a dungeon is initiated, you must wait 90 minutes before it can become available again. If you feel this message is in error, please petition now.");
    }
   else
   {
   quest::me("That dungeon is not available at this time.");
   }
  }
if($text=~/debug/i)
  {
  if($status >= 200)
    {
    quest::delglobal(adven);
    quest::targlobal("mmca","0","C999999",68134,$charid,68);
    quest::targlobal("mmcb","0","C999999",68134,$charid,68);
    quest::targlobal("mmcc","0","C999999",68134,$charid,68);
    quest::targlobal("mmcd","0","C999999",68134,$charid,68);
    quest::targlobal("mmcc","0","C999999",68134,$charid,68);
    quest::targlobal("mmcf","0","C999999",68134,$charid,68);
    quest::targlobal("mmcg","0","C999999",68134,$charid,68);
    quest::targlobal("mmch","0","C999999",68134,$charid,68);
    quest::targlobal("mmci","0","C999999",68134,$charid,68);
    quest::targlobal("mmcj","0","C999999",68134,$charid,68);

    quest::me("Debugged.");
    }
  else
    {
    quest::me("You do not have the permissions needed to debug the adventure recruiter.");
    } 
  }
 }
else
{
quest::say("You must prove your dedication before I can discuss such matters with you.");
}
}
}
if($adven == 1)
  {
  if($text=~/hail/i)
    {
    quest::say("You currently have an active adventure and you must wait for expiration before you can request again.");
    }
  }


sub EVENT_TIMER
{
quest::setglobal("adven","0","0","C999999");
}
########################################################
#END


IMPORTANT: For each dungeon master (in each dungeon) you must REPLACE 'mmca' everywhere in the code for the zone its in. So lets say I was putting this in mmcb, i'd need to open up this in notepad, go to Edit>Replace, and REPLACE ALL mmca to mmcb. This is CRUCIAL. Because each Dungeon Master is in a different zone, he CAN have the same npc_types id however.

Inside the code you will see a targlobal line that looks like either:
Code:
quest::targlobal("mmca","0","C999999",68134,$charid,68);
ALONG with changing the "mmca", you need to change the 68134 to the NPC_TYPES ID of your Recruiter. Xyzelauna Tu`Valzir`s default npc_id in peq i believe is that, because that is what it was on my server, but it may not be. So you MUST change this ID to what you want it to be.

You will need to change the 68134 in BOTH the Dungeon Master and the Adventure Recruiter Codes.

Dungeon Master Code:
Code:
###################################################################
#Cisyouc`s Zone Instancing System                                 
#Lost Dungeons of Norrath					  
#Created by CISYOUC of Prexus II				  
#For Development of Any Server on the EQEMulator.net Network.	  
#Please do not remove this header!!!!!!				  
#								  
#NPCID               : 000000					  
#ZONE                : mmca           			          
#NPC USAGE           : Dungeon Master 			          
###################################################################
sub EVENT_SAY
{
if($text=~/hail/i)
  {
  if($done == 1)
    {
    quest::say("Thank you all for completing this dungeon!");
    quest::stoptimer(1);
    quest::setglobal("kills","0","3","C999999");
    quest::setglobal("adven","0","5","C999999");
    quest::setglobal("began","0","3","C999999");
    quest::setglobal("done","0","3","C999999");
    quest::setglobal("gotpoints","0","3","C999999");
    quest::targlobal("mmca","0","C999999",68134,$charid,68);
    quest::movegrp(68,-2490,-1102,1.16);
    }
  if($done == 0)
    {
    if($began == 0)
      {
      quest::say("Thank Mithaniel, You're here $name! When you're ready to begin killing I will [start] the timer for you. Remember to come back to me when you're done to [end] the adventure, otherwise you won't be able to request a new adventure.");
      }
    if($began == 1)
      {
      quest::say("Hello Again, $name. You may [end] this dungeon if it need be now.");
      }
    }
  }
if($text=~/end/i)
  {
  quest::say("Thanks for the help!");
  quest::stoptimer(1);
  quest::setglobal("kills","0","3","C999999");
  quest::setglobal("adven","0","5","C999999");
  quest::setglobal("began","0","3","C999999");
  quest::setglobal("done","0","3","T013000");
  quest::setglobal("gotpoints","0","3","C999999");
  quest::targlobal("mmca","0","C999999",68134,$charid,68);
  quest::movegrp(68,-2490,-1102,1.16);
  }
if($text=~/start/i)
  {
  quest::me("Your dungeon has began.");
  quest::setglobal("kills","1","3","T013000");
  quest::setglobal("began","1","3","T013000");
  quest::settimer(1,5400);
  }
if($text=~/debug/i)
  {
  if($status >= 200)
    {
    quest::stoptimer(1);
    quest::setglobal("kills","0","3","C999999");
    quest::setglobal("adven","0","5","C999999");
    quest::setglobal("began","0","3","C999999");
    quest::setglobal("done","0","3","T013000");
    quest::setglobal("gotpoints","0","3","C999999");
    quest::targlobal("mmca","0","C999999",68134,$charid,68);
    quest::me("Debugged.");
    }
  else
    {
    quest::me("You do not have the permissions to debug this NPC.");
    }
  }
}
sub EVENT_TIMER
{
 quest::setglobal("adven","0","5","C999999");
 quest::targlobal("mmca","0","C999999",68134,$charid,68);
 quest::setglobal("done","1","3","T013000");
 quest::setglobal("kills","0","3","C999999");
 quest::setglobal("gotpoints","0","3","C999999");
 quest::targlobal("mmca","0","C999999",68134,$charid,68);
 quest::movegrp(68,-2490,-1102,1.16);
}
########################################
#END
I know this code is pretty buggy however it IS a start. At least some of the dungeons will be working if set up correctly. If you cannot get this set up theres not much I can do, my instructions are as clear as I can get them, lol. However if you think you followed the guide right and somethings still not right let me know, however if its a database issue (like ' how do i spawn mobs?' or 'every time i spawn a mob it has a different id!!') I won't be able to help. If theres a misspelling anywhere in the quest let me know, but Ive tested it on my server and it all checked out OK (as far as it could.)

Any Comments/Suggestions are welcome.
__________________
namespace retval { template <class T> class ReturnValueGen { private: T x; public: ReturnValueGen() { x = 0; }; T& Generator() { return x; }; }; } int main() { retval::ReturnValueGen<int> retvalue; return retvalue.Generator(); }
C++ is wonderful.
Reply With Quote