Quests

From Meridian 59 - Open Source Wiki
Jump to: navigation, search

Adding Quests

The quest system uses three files:

..\kod\util\questengine.kod, which is where the actual quest data and quest strings are, and from which quest nodes are created;

..\kod\object\passive\questnode.kod, which handles a lot of the quest data implementation, in nodes created by QuestEngine. Data for prize types are also listed in here;

..\kod\object\passive\quest.kod, which handles player requisites for quests, assigning nodes and a few other functions.

The system works quite well and it is reasonably easy to add new quests. If you're using existing prize types and penalties it is even easier, but new prize types are also quite easy to implement. There are example templates in questengine.kod but I will include one here as an example.

Any new quest requires the quest string triggers/responses to be placed under resources in questengine.kod, a 'quest template' to be placed in the Recreate() function in questengine.kod, any quest nodes to be placed under RecreateQuestNodes(), also in questengine.kod and the new QST_ID (from the quest template) to be placed in blakston.khd.

Here's some examples from a newly created quest (resources omitted, these are simple):

Quest Template:

  % QST_ID_RAISE_LICH
   plQuestTemplates = cons([  piDefaultNumPlayers,\
			      piDefaultQuestType,\
			      Q_PLAYER_NOTNEWBIE,\
			      [ 217, 218, 219 ],\
			      1,\
			      [],\
			      100,
			      [ [ Q_R2_HAS_HEALTH_LEVEL, 120 ]  ]
			                                    ], plQuestTemplates );

Quest Nodes:

  % template #217 is lichraise quest
  if send( self, @AddQuestNodeTemplate, #questnode_type = QN_TYPE_SHOWUP )
  {
     lNPCs = $;
     for oNPC in send( send( SYS, @GetLibrary ), @GetOccupationList, #cNPC_class = &DeadLich ) { lNPCs = cons( oNPC, lNPCs );}
     send( self, @SetQuestNodeNPCList, #index = 217, #new_NPC_list = lNPCs );
  }
  else
  {
     debug( "Error building QN #217" );
  }
  % template #218 is lich raise quest
  if send( self, @AddQuestNodeTemplate, #questnode_type = QN_TYPE_MESSAGE, #NPC_modifier = QN_NPCMOD_SAME,
        #cargolist = [ lichraise_trigger_2 ],
        #timelimit = 120 )    % 2 min
  {
     send( self, @SetQuestNodeAssignHint, #index = 218, #new_hint = lichraise_assign_2 );
  }
  else
  {
     debug( "Error building QN #218" );
  }
  % template #219 is lich raise quest
  if send( self, @AddQuestNodeTemplate, #questnode_type = QN_TYPE_ITEMFINDCLASS, #NPC_modifier = QN_NPCMOD_SAME,
        #cargolist = [ [ QN_PRIZETYPE_ITEMCLASS, &OfferingQor, 1 ] ],
        #prizelist = [ [ QN_PRIZETYPE_RECEIVE_LICH ] ],
        #penaltylist = [ [QN_PRIZETYPE_BOON, QN_PRIZE_BOON_MYSTICISM , -3, 2 ] ],
        #timelimit = 3 * 24 * 3600 )    % 3 days
  {
     send( self, @SetQuestNodeAssignHint, #index = 219, #new_hint = lichraise_assign_3 );
     send( self, @SetQuestNodeSuccessHint, #index = 219, #new_hint = lichraise_success_3 );
     send( self, @SetQuestNodeFailureHint, #index = 219, #new_hint = lichraise_failure_3 );
  }
  else
  {
     debug( "Error building QN #219" );
  }

Quest ID flag in blakston.khd:

  QST_ID_RAISE_LICH             = 75


This particular quest requires some extra code because of the new prize type, which in this case summons a lich. Adding new ones in questnode.kod is pretty simple by following the code already there, and adding a flag for the new prize type in blakston.khd. This quest is also set by a lich dying, which needs to spawn a new instance of the quest for the next person (see quest template related code in lich.kod and deadlich.kod, which will be available when the quest is added to the game). This usually isn't necessary for quests as they will set themselves however this is a rare case, but also an example that the quest system is fairly flexible and can (with the inclusion of new prize and penalty types) be coded to do pretty much anything.