Farmers Quest

Got any custom JavaScript additions/tweaks you think other people would like to see? Post 'em here!
Post Reply
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Farmers Quest

Post by dragon slayer »

This is the first of many new quests i intend to make.
I hope me starting this quest system will help people make more just by using it.

i do plain on removing the set tags later on So i will update date this as i improve it. Any ideas or suggestions to help imrpove on this quest system let me know.

You need to make a globel.js
function onPickup( iPickedUp, pGrabber )
{
  var pSock = pGrabber.socket;
  //Check the value of pSock.pickupSpot to determine where the item was picked up from
  switch( pSock.pickupSpot )
  {
    case 0: //nowhere
     return false;
    case 1: //ground
     return false;
    case 2: //ownpack
     return false;     
    case 3: //otherpack
     var oldNumToGet = pGrabber.GetTag( "FQ_numToGet" );
     if( oldNumToGet && pGrabber.GetTag( "FQ_IDTOGET" ) == iPickedUp.id )
     {
        var newNumToGet = (oldNumToGet-1);
        pGrabber.SetTag( "FQ_numToGet", newNumToGet );
        if( newNumToGet )
           pGrabber.SysMessage( "You have "+NumToString( newNumToGet )+" more items to collect." );
        else
           pGrabber.SysMessage( "You have completed your task, return to Farmer Jones for your reward." );
     }
     return false;     
    case 4: //paperdoll
     return false;     
    case 5: //bank
     return false;
    default:
    pGrabber.TextMessage( "Error. Redo from Start." );
    break;
   }
}
farmerjones.js
function onSpeech( myString, myPlayer, myNPC, pSock )
{
   if( !myNPC.InRange( myPlayer, 2 ) )
      return;
   var startQuest = myPlayer.GetTag( "FQ_START" );
   var Speech_Array = myString.split(" ");
   var i = 0, currObj = 0;

   for( i = 1; i <= Speech_Array.length; i++ )
   {
      if( Speech_Array[currObj].match( /\bHail\b/i ) || Speech_Array[currObj].match( /\bHi\b/i ) || Speech_Array[currObj].match( /\bHello\b/i ) )
      {
         myNPC.TurnToward( myPlayer );
         myNPC.TextMessage( "Hail "+myPlayer.name+". You seem like a brave sort, I may have a task for you." );
      }
      else if( Speech_Array[currObj].match( /\bQuest\b/i ) || Speech_Array[currObj].match( /\bAdventure\b/i ) || Speech_Array[currObj].match( /\bTask\b/i ) )    
      {
         myNPC.TurnToward( myPlayer );
         if( myPlayer.GetTag( "FQ_LEVEL" ) )
         {
            myNPC.TextMessage( "I have already given you a task, you may request your reward when you have completed it" );
            return false;
         }
         else
         {
            myPlayer.SetTag( "FQ_START", 1 );
            var myGump = new Gump; // create a new gump  

            myGump.AddPage(0);
            myGump.AddTiledGump( 50, 20, 400, 400, 5124 );
            myGump.AddCheckerTrans( 50, 20, 400, 400 );
            myGump.AddTiledGump( 50, 29, 30, 390, 10460 );
            myGump.AddTiledGump( 34, 140, 17, 279, 9263 );
            myGump.AddGump( 48, 135, 10411 );
            myGump.AddGump( -16, 285, 10402 );
            myGump.AddGump( 0, 10, 10421 );
            myGump.AddGump( 25, 0, 10420 );
            myGump.AddTiledGump( 83, 15, 350, 15, 10250 );
            myGump.AddGump( 34, 419, 10306 );
            myGump.AddGump( 442, 419, 10304 );
            myGump.AddTiledGump( 51, 419, 392, 17, 10101 );
            myGump.AddTiledGump( 415, 29, 44, 390, 2605 );
            myGump.AddTiledGump( 415, 29, 30, 390, 10460 );
            myGump.AddGump( 370, 50, 1417 );
            myGump.AddGump( 425, 0, 10441 );
            myGump.AddGump( 90, 33, 9005 );
            myGump.AddTiledGump( 130, 65, 175, 1, 9101 );
            myGump.AddButton( 95, 395, 0x2ee0, 1, 0, 1 );       // Button - Accept
            myGump.AddButton( 313, 395, 0x2ef2, 1, 0, 0 );        // Button - Refuse
            myGump.AddText( 130, 45, 0x34, "Crappy Quest" );
            myGump.AddText( 98, 140, 0x34, "Description" );
            myGump.AddText( 125, 165, 0x34, "Farmer Jones  looks at you with hope." );
            myGump.AddText( 98, 180, 0x34, "After he puts down his hoe," );
            myGump.AddText( 98, 195, 0x34, "he says If you are brave enough," );
            myGump.AddText( 98, 210, 0x34, "I have a task for you" );
            myGump.AddText( 98, 225, 0x34, "I take it you wish for me to continue." );
            myGump.AddText( 98, 240, 0x34, "I am i need of fertilizer for my garden." );
            myGump.AddText( 98, 255, 0x34, "Are you still interested?" );
            myGump.Send( myPlayer ); // send this gump to client now
            myGump.Free(); // clear this gump from uox-memory
            return false;
         }
      }
      else if( Speech_Array[currObj].match( /\bReward\b/i ) )
      {
         myNPC.TurnToward( myPlayer );
         var taskLevel = myPlayer.GetTag( "FQ_LEVEL" );
         if( taskLevel )
         {
            var numToGet = myPlayer.GetTag( "FQ_numToGet" );
            if( numToGet > 0 )
            {
               myNPC.TextMessage( "You Started a Quest but have not finished it.");
            }
        }
        else
            myNPC.TextMessage( "I don't give rewards I'm a farmer");
            return false;
      }
      else if( Speech_Array[currObj].match( /\bQuite\b/i ) )
      {
               myNPC.TurnToward( myPlayer );
               myNPC.TextMessage( "I better get back to my garden work." );
               myPlayer.SetTag( "FQ_START", 0 );
               myPlayer.SetTag( "FQ_numToGet", -1 );
               myPlayer.SetTag( "FQ_IDTOGET", 0 );
               myPlayer.SetTag( "FQ_LEVEL", 0 );
      }
      currObj++;
   }
}

function onDropItemOnNpc( pDropper, pDroppedOn, iDropped )
{
  pDroppedOn.TurnToward( pDropper );
  var taskLevel = pDropper.GetTag( "FQ_LEVEL" );
  if( taskLevel )
  {
    var numToGet = pDropper.GetTag( "FQ_numToGet" );
    if( numToGet > 0)
    {
       myNPC.TextMessage( "Alas, you still have "+NumToString( numToGet )+" more to get before you receive your reward!");
    }
    else
    {
      var numCrap = pDropper.ResourceCount( 0xF81 );
      var numEye = pDropper.ResourceCount( 0x0f87 );
      var numBlood = pDropper.ResourceCount( 0x0f82 );
      if( numCrap >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." );
       var goldToGive = 0;
       switch( RandomNumber( 0, 2 ) )
       {
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       }
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true );
       pDropper.SoundEffect( 0x0037, false );
       pDropper.SetTag( "FQ_numToGet", 0 );
       pDropper.SetTag( "FQ_IDTOGET", 0 );
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0xF81 );
       return 0;
      }
      else if( numEye >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." );
       var goldToGive = 0;
       switch( RandomNumber( 0, 2 ) )
       {
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       }
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true );
       pDropper.SoundEffect( 0x0037, false );
       pDropper.SetTag( "FQ_numToGet", 0 );
       pDropper.SetTag( "FQ_IDTOGET", 0 );
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0x0f87 );
       return 0;
      }
      else if( numBlood >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." );
       var goldToGive = 0;
       switch( RandomNumber( 0, 2 ) )
       {
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       }
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true );
       pDropper.SoundEffect( 0x0037, false );
       pDropper.SetTag( "FQ_numToGet", 0 );
       pDropper.SetTag( "FQ_IDTOGET", 0 );
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0x0f82 );
       return 0;
      }
      else if( numBlood <= 20 && numEye <= 20 && numCrap <= 20 )
      {
       pDroppedOn.TextMessage( "That is not the amount I asked for." );
       return 0;
      }
    }
  }
     pDroppedOn.TextMessage( "I did not ask for this item." );
     return 0;
}

function onGumpPress(pSock, myButtonID)
{
  var myPlayer = pSock.currentChar;
   switch( myButtonID )
   {
      case 0: // Refuse
         myPlayer.SetTag( "FQ_START", 0 );
         myPlayer.SysMessage("Farmer Jones goes back to his garden work.");
      break;
      case 1: // Accept
         var myGump = new Gump; // create a new gump
         var numToGet = (20);
         var typeToGet = CreateGenericQuest( myPlayer, 1, numToGet );

            myGump.AddPage(0);
            myGump.AddTiledGump( 50, 20, 400, 400, 5124 );
            myGump.AddCheckerTrans( 50, 20, 400, 400 );
            myGump.AddTiledGump( 50, 29, 30, 390, 10460 );
            myGump.AddTiledGump( 34, 140, 17, 279, 9263 );
            myGump.AddGump( 48, 135, 10411 );
            myGump.AddGump( -16, 285, 10402 );
            myGump.AddGump( 0, 10, 10421 );
            myGump.AddGump( 25, 0, 10420 );
            myGump.AddTiledGump( 83, 15, 350, 15, 10250 );
            myGump.AddGump( 34, 419, 10306 );
            myGump.AddGump( 442, 419, 10304 );
            myGump.AddTiledGump( 51, 419, 392, 17, 10101 );
            myGump.AddTiledGump( 415, 29, 44, 390, 2605 );
            myGump.AddTiledGump( 415, 29, 30, 390, 10460 );
            myGump.AddGump( 370, 50, 1417 );
            myGump.AddGump( 425, 0, 10441 );
            myGump.AddGump( 90, 33, 9005 );
            myGump.AddTiledGump( 130, 65, 175, 1, 9101 );
            myGump.AddButton( 313, 395, 0x2eec, 1, 0, 3 );      // Button - Close
            myGump.AddButton( 95, 395, 0x2ef5, 1, 0, 2 );       // Button - Resign
            myGump.AddText( 130, 45, 0x34, "Crappy Quest" );
            myGump.AddText( 98, 140, 0x34, "Description" );
            myGump.AddText( 125, 165, 0x34, "What I would need you to do, is go kill the" );
            myGump.AddText( 98, 180, 0x34, "Crayma and bring me the "+typeToGet+". Some of" );
            myGump.AddText( 98, 195, 0x34, "them have it some don't. What I need from you, is" );
            myGump.AddText( 98, 210, 0x34, "to bring me back "+NumToString( numToGet )+" pieces of "+typeToGet+" so I" );
            myGump.AddText( 98, 225, 0x34, "can use it to help my garden grow. If you" );
            myGump.AddText( 98, 240, 0x34, "decide to go through with this, I will give you" );
            myGump.AddText( 98, 255, 0x34, "a sword and gold as well for your troubles." );
            myGump.Send( myPlayer ); // send this gump to client now
            myGump.Free(); // clear this gump from uox-memory
            return false;
      break;
      case 2: // Resign
         myPlayer.SetTag( "FQ_numToGet", 0 );
         myPlayer.SetTag( "FQ_IDTOGET", 0 );
         myPlayer.SetTag( "FQ_LEVEL", 0 );  
         myPlayer.SetTag( "FQ_START", 0 );
         myPlayer.SysMessage("Farmer Jones goes back to his garden work.");
      break;
      case 3: // Close
      break;
    }
}

function CreateGenericQuest( myPlayer, questLevel, numToGet )
{
   var typeToGet = GetItemType( myPlayer, questLevel );
   myPlayer.SetTag( "FQ_numToGet", numToGet );
   myPlayer.SetTag( "FQ_LEVEL", questLevel );
   myPlayer.SetTag( "FQ_START", 0 );
   return typeToGet;
}

function GetItemType( myPlayer, questLevel )
{
   var retVal = "";
   switch( questLevel )
   {
   case 1:
      switch( RandomNumber( 0, 2 ) )
      {
      case 0:
         myPlayer.SetTag( "FQ_IDTOGET", 0xf81 );
         retVal = "Crayma Crap";
         break;
      case 1:
         myPlayer.SetTag( "FQ_IDTOGET", 0x0f82 );
         retVal = "Crayma Blood";
         break;
      case 2:
         myPlayer.SetTag( "FQ_IDTOGET", 0x0f87 );
         retVal = "Crayma Scales";
         break;
      }
      break;
   }
   return retVal;
}
then make a questitems.dfn and add this items in

Code: Select all

[craymacrap]
{ 
get=base_item
name=Crayma Crap
id=0xf81
pileable=1
amount=1
decay=1
}

[craymablood]
{ 
get=base_item
name=Crayma Blood
id=0x0f82
pileable=1
amount=1
decay=1
}

[craymascales]
{ 
get=base_item
name=Crayma Scales
id=0x0f87
pileable=1
amount=1
decay=1
}
Last edited by dragon slayer on Tue Apr 03, 2012 8:04 pm, edited 2 times in total.
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

Here is the farmerjones.js without the globel.js needed

means you can just add the item to any npc and collect it and you can then turn it in to who ever your farmer is

Code: Select all

function onSpeech( myString, myPlayer, myNPC, pSock ) 
{ 
   if( !myNPC.InRange( myPlayer, 2 ) ) 
      return; 
   var startQuest = myPlayer.GetTag( "FQ_START" ); 
   var Speech_Array = myString.split(" "); 
   var i = 0, currObj = 0; 

   for( i = 1; i <Speech_Array> 0 )
            {
               myNPC.TextMessage( "You Started a Quest but have not finished it.");
            }
        } 
        else 
            myNPC.TextMessage( "I don't give rewards I'm a farmer");
            return false;
      } 
      else if( Speech_Array[currObj].match( /\bQuite\b/i ) ) 
      { 
               myNPC.TurnToward( myPlayer );
               myNPC.TextMessage( "I better get back to my garden work." );
               myPlayer.SetTag( "FQ_START", 0 ); 
               myPlayer.SetTag( "FQ_numToGet", 0 ); 
               myPlayer.SetTag( "FQ_IDTOGET", 0 ); 
               myPlayer.SetTag( "FQ_LEVEL", 0 ); 
      } 
      currObj++; 
   } 
}

function onDropItemOnNpc( pDropper, pDroppedOn, iDropped )
{
  pDroppedOn.TurnToward( pDropper ); 
  var taskLevel = pDropper.GetTag( "FQ_LEVEL" ); 
  if( taskLevel ) 
  { 
      var numCrap = pDropper.ResourceCount( 0xf81 ); 
      var numEye = pDropper.ResourceCount( 0x0f87 ); 
      var numBlood = pDropper.ResourceCount( 0x0f82 ); 
      if( numCrap >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." ); 
       var goldToGive = 0; 
       switch( RandomNumber( 0, 2 ) ) 
       { 
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       } 
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true ); 
       pDropper.SoundEffect( 0x0037, false ); 
       pDropper.SetTag( "FQ_numToGet", 0 ); 
       pDropper.SetTag( "FQ_IDTOGET", 0 ); 
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0xF81 ); 
       return 0;
      }
      else if( numEye >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." ); 
       var goldToGive = 0; 
       switch( RandomNumber( 0, 2 ) ) 
       { 
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       } 
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true ); 
       pDropper.SoundEffect( 0x0037, false ); 
       pDropper.SetTag( "FQ_numToGet", 0 ); 
       pDropper.SetTag( "FQ_IDTOGET", 0 ); 
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0x0f87 ); 
       return 0;
      }
      else if( numBlood >= 20)
      {
       pDroppedOn.TextMessage( "Wonderful work my friend, here is your reward." ); 
       var goldToGive = 0; 
       switch( RandomNumber( 0, 2 ) ) 
       { 
       case 0:      goldToGive = 50;      break;
       case 1:      goldToGive = 75;      break;
       case 2:      goldToGive = 100;      break;
       } 
       CreateDFNItem( pDropper.socket, pDropper, "0x0EED", goldToGive, "ITEM", true ); 
       pDropper.SoundEffect( 0x0037, false ); 
       pDropper.SetTag( "FQ_numToGet", 0 ); 
       pDropper.SetTag( "FQ_IDTOGET", 0 ); 
       pDropper.SetTag( "FQ_LEVEL", 0 );
       pDropper.UseResource( 20, 0x0f82 ); 
       return 0;
      }
      else if( numBlood <= 20 && numEye <= 20 && numCrap <= 20 )
      {
       pDroppedOn.TextMessage( "That is not the amount I asked for." );
       return 0;
      }
  }
     pDroppedOn.TextMessage( "I did not ask for this item." );
     return 0;
}

function onGumpPress(pSock, myButtonID) 
{ 
  var myPlayer = pSock.currentChar;
   switch( myButtonID ) 
   { 
      case 0: // Refuse
         myPlayer.SetTag( "FQ_START", 0 ); 
         myPlayer.SysMessage("Farmer Jones goes back to his garden work.");
      break; 
      case 1: // Accept
         var myGump = new Gump; // create a new gump
         var numToGet = (20); 
         var typeToGet = CreateGenericQuest( myPlayer, 1, numToGet );

            myGump.AddPage(0);
            myGump.AddTiledGump( 50, 20, 400, 400, 5124 );
            myGump.AddCheckerTrans( 50, 20, 400, 400 );
            myGump.AddTiledGump( 50, 29, 30, 390, 10460 );
            myGump.AddTiledGump( 34, 140, 17, 279, 9263 );
            myGump.AddGump( 48, 135, 10411 );
            myGump.AddGump( -16, 285, 10402 );
            myGump.AddGump( 0, 10, 10421 );
            myGump.AddGump( 25, 0, 10420 );
            myGump.AddTiledGump( 83, 15, 350, 15, 10250 );
            myGump.AddGump( 34, 419, 10306 );
            myGump.AddGump( 442, 419, 10304 );
            myGump.AddTiledGump( 51, 419, 392, 17, 10101 );
            myGump.AddTiledGump( 415, 29, 44, 390, 2605 );
            myGump.AddTiledGump( 415, 29, 30, 390, 10460 );
            myGump.AddGump( 370, 50, 1417 );
            myGump.AddGump( 425, 0, 10441 );
            myGump.AddGump( 90, 33, 9005 );
            myGump.AddTiledGump( 130, 65, 175, 1, 9101 );
            myGump.AddButton( 313, 395, 0x2eec, 1, 0, 3 );      // Button - Close
            myGump.AddButton( 95, 395, 0x2ef5, 1, 0, 2 );       // Button - Resign
            myGump.AddText( 130, 45, 0x34, "Crappy Quest" );
            myGump.AddText( 98, 140, 0x34, "Description" );
            myGump.AddText( 125, 165, 0x34, "What I would need you to do, is go kill the" );
            myGump.AddText( 98, 180, 0x34, "Crayma and bring me the "+typeToGet+". Some of" );
            myGump.AddText( 98, 195, 0x34, "them have it some don't. What I need from you, is" );
            myGump.AddText( 98, 210, 0x34, "to bring me back "+NumToString( numToGet )+" pieces of "+typeToGet+" so I" );
            myGump.AddText( 98, 225, 0x34, "can use it to help my garden grow. If you" );
            myGump.AddText( 98, 240, 0x34, "decide to go through with this, I will give you" );
            myGump.AddText( 98, 255, 0x34, "a sword and gold as well for your troubles." );
            myGump.Send( myPlayer ); // send this gump to client now 
            myGump.Free(); // clear this gump from uox-memory 
            return false; 
      break;
      case 2: // Resign
         myPlayer.SetTag( "FQ_numToGet", 0 ); 
         myPlayer.SetTag( "FQ_IDTOGET", 0 ); 
         myPlayer.SetTag( "FQ_LEVEL", 0 );  
         myPlayer.SetTag( "FQ_START", 0 ); 
         myPlayer.SysMessage("Farmer Jones goes back to his garden work.");
      break;
      case 3: // Close
      break; 
    }
}

function CreateGenericQuest( myPlayer, questLevel, numToGet ) 
{ 
   var typeToGet = GetItemType( myPlayer, questLevel ); 
   myPlayer.SetTag( "FQ_numToGet", numToGet ); 
   myPlayer.SetTag( "FQ_LEVEL", questLevel ); 
   myPlayer.SetTag( "FQ_START", 0 ); 
   return typeToGet; 
} 

function GetItemType( myPlayer, questLevel ) 
{ 
   var retVal = ""; 
   switch( questLevel ) 
   { 
   case 1: 
      switch( RandomNumber( 0, 2 ) ) 
      { 
      case 0: 
         myPlayer.SetTag( "FQ_IDTOGET", 0xf81 ); 
         retVal = "Crayma Crap"; 
         break; 
      case 1: 
         myPlayer.SetTag( "FQ_IDTOGET", 0x0f82 ); 
         retVal = "Crayma Blood"; 
         break; 
      case 2: 
         myPlayer.SetTag( "FQ_IDTOGET", 0x0f87 ); 
         retVal = "Crayma Scales"; 
         break; 
      } 
      break;
   }
   return retVal; 
} 
RandallFlagg26
UOX3 Newbie
Posts: 16
Joined: Wed May 18, 2011 1:25 am
Has thanked: 0
Been thanked: 0

Post by RandallFlagg26 »

How do I implement the quest?
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

have you every made any .js files?

If so here small instructions

take the global.js and put it in js folder
Now open up the jse_fileassociations

Find this line
[SCRIPT_LIST]
{
//-------------------------------------------
// CORE:[0-99] Rerserved for specific core server needs
//-------------------------------------------

add this line
0=global.js

now just add the rets of the scripts to your custom folder thats inside the js folder.

add this lines to your jse_fileassociations
3005=custom/Quests/farmerjones.js

Then make a new npc from scatch and give him this tag

script=3005

if your still having problems with this i could help you in irc.
RandallFlagg26
UOX3 Newbie
Posts: 16
Joined: Wed May 18, 2011 1:25 am
Has thanked: 0
Been thanked: 0

Post by RandallFlagg26 »

kk Done. 2 more things:

1. In your second post some of your code got lost from the for loop on line 9 (no semi-colon and i increment). Then a bunch of lines inadvertently must have wandered off immediately following line 9. So I just took all of the code from your original post.

2. I don't know what a crayma is or what it looks like. I did a quick search on google but couldn't catch a glimpse of the elusive crayma. I could only find articles referring to the quest itself. Do you know what it looks like? Some post somewhere said that "it looks like walking black plants".
Post Reply