Task System Guide

This page further details the use of the EQEmu Task System.

The EQEmu Task System allows implementation of quests that utilize the clients Task Window (alt+Q). Many aspects of this system can be found throughout this wiki; this guide attempts to organize that information on a single page to inform the reader who wishes to understand and utilize the Task System.

Much of the Task System functionality can be found in /zones/task.cpp and should be referenced by those comfortable with looking at the EQEmu source code.

While every attempt will be made to keep this page updated, please reference the additional supporting documentation found in the Database Schema, Quest API, and Changelog.

Section Description

Link

Database Schema: All of the DB tables for the task system

Database Schema

GM Commands: in-game GM commands for the task system

GM Commands

Task System Rules: server rules effecting the task system

Task System Rules

Logging Options: use with the Logging System

Logging Options

Quest API: quest methods and EVENT triggers relating to the task system

Quest API

Database Schema

The most up to date information regarding the database schema can be found in the Database Schema Space for Tasks. The information presented here is current as of this writing.

Tasks Table

Field Descriptions

Column

Data Type

Description

id

int

Unique Task Identifier; use 1 - 9999, a value of 0 should NOT be used

type

tinyint

Task Type; 0=Task, 1=Shared, 2=Quest, 3=Expedition

duration

int

Duration in seconds; if 0, the task has no time limit

duration_code

tinyint

Duration Code; 0=None, 1=Short, 2=Medium, 3=Long

title

varchar

Title

description

text

Description; only the active task description displays

reward

varchar

Reward Description

rewardid

int

Item ID number, or a reference to a list of item ID numbers (from goallists table)

cashreward

int

Cash Reward, listed in copper (system will convert to plat, gold, etc.)

xpreward

int

Experience Reward; for level-based, set a negative value using the following formula: max level * 100 + experience percent

rewardmethod

tinyint

Reward Method: 0 = Single Item ID, 1 = List of Items (in the goallist table), 2 = Quest Controlled (reward granted through NPC quest script)

minlevel

tinyint

Minimum Level to obtain tasks

maxlevel

tinyint

Maximum Level to obtain tasks

repeatable

tinyint

Repeatable: 0 = False, 1 = True

faction_reward

int

Faction Reward

completion_emote

varchar

Completion Emote

Task_Activities Table

Field Descriptions

Column

Data Type

Description

taskid

int

Task Identifier (ID from Tasks table); each activity for a task will utilize the same ID.

activityid

int

Activity Identifier: Starts at 0, must be sequential

step

int

Step: 0 = Always Available, >0 = Must Complete Previous ("stepped" task)

activitytype

tinyint

Activity Type (or see below)

target_name

varchar

Target Name

item_list

varchar

Item Identifier List

skill_list

varchar

Skill Identifier List

spell_list

varchar

Spell Identifier List

description_override

varchar

Description Override

goalid

int

Goal Identifier or Goal List Identifier

goalmethod

int

Goal Method:

0 = Single Value (npc_type ID or item ID)

1 = List (refers to the goallist table to use a list of npc_type IDs or Item IDs)

2 = Under control of quest system

goalcount

int

Goal Count (how many of the things in the goal id must be done)

delivertonpc

int

Deliver To NPC: 0 = No Delivery NPC, >0 = npc_type ID

zones

varchar

Zones List--use the zoneidnumber field; "0" displays "ALL". Activities will only be counted if completed in the assigned zone. Can also be used as "Touch" for visiting an assigned zone.

optional

tinyint

Optional: 0 = False, 1 = True; if a task activity is optional, the task will be complete when all non-optional task activities are completed.

Activity Types

Please note that quest::updatetaskactivity could be used in many EVENT triggers if you did not want to use the task system as described in the table below.

Type ID

Type Name

Information and usage

1

Deliver

To have this activity automatically handled by the task system without the need to write any Perl quest code, set:

  • goalmethod 0

  • goalid to the id of the item you want delivered

  • delivertonpc to the npc_types id you want the item delivered to

  • zoneid to the zoneidnumber the npc is in (or 0 for all)

If you wish to allow the player to deliver any out of a group of items, then you can use a list. To do this, create a list in the goallist table containing the allowable items. Then set the goalmethod to 1 and put the list number in the goalid field.

2

Kill

To have this activity automatically handled by the task system without the need to write any Perl quest code, set:

  • goalmethod to 0

  • goalid to the id of the npc that must be killed (from the npc_types table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber if the mobs must be killed in a particular zone to count.

If you wish to allow the player to kill any out of a group of NPC types, then you can use a list as described for the Deliver activity. For common mobs, you will probably always be using lists, since there are a lot of entries for mobs with the same name in the npc_types table which differ by level, etc.

3

Loot

To have this activity automatically handled by the task system without the need to write any Perl quest code, set:

  • goalmethod to 0

  • goalid to the id of the item that must be looted (from the items table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber if the item must be looted in a particular zone to count.

If you wish to allow the player to loot any one of a group of items, then you can use a list as described for the Deliver activity.

4

Speak With

To have this activity automatically handled by the task system without the need to write any Perl quest code, set:

  • goalmethod to 0

  • goalid to the id of the NPC that must be spoken to (from the npc_types table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber that the NPC is in.

If you wish to allow the player to speak to any one of a group of NPCs, then you can use a list as described for the Deliver activity.

5

Explore

To have this activity automatically handled by the task system without the need to write any Perl quest code, you will need to add a row to the proximity table. Once you have added the row and given it a unique exploreid number, in the activity table, set:

  • goalmethod to 0

  • goalid to the exploreid of your newly created row in the proximity table.

  • zoneid should be set to the zoneidnumber that the proximity is in.

It should be possible to set up multiple proximities in the same zone, using lists, such that any of the proximities will trigger the activity complete.

6

Tradeskill

To have this activity automatically handled by the task system, set:

  • goalmethod to 0

  • goalid to the id of the item that must be created (from the items table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber that the items must be created in.

If you wish to allow the player to create any one of a group of items, then you can use a list as described for the Deliver activity. Sometimes there are several items with the same name that can be created from a tradeskill, CLASS 1 Wood Point arrows being one of them.

7

Fish

To have this activity automatically handled by the task system, set:

  • goalmethod to 0

  • goalid to the id of the item that must be fished (from the items table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber that the items must be fished in.

If you wish to allow the player to fish any one of a group of items, then you can use a list as described for the Deliver activity.

8

Forage

To have this activity automatically handled by the task system, set:

  • goalmethod to 0

  • goalid to the id of the item that must be foraged (from the items table).

  • zoneid should be set to 0 (any zone), or the zoneidnumber that the items must be fished in.

If you wish to allow the player to forage any one of a group of items, then you can use a list as described for the Deliver activity.

9

Use

10

Use

11

Touch

To have this activity automatically handled by the task system, set:

  • goalmethod to 0

Since the zoneid field is used to specify the zoneidnumber, the goalid field is not used. It is also not possible to specify a list of zones.

100

Give Cash

To have this activity automatically handled by the task system, set:

  • goalmethod to 0

  • npctypeid to the id of the NPC that the cash should be given to

  • zoneid should be set to 0 (any zone), or the zoneidnumber that the NPC is found in.

Character_Tasks Table

Field Descriptions

Column

Data Type

Description

charid

int

Character Identifier; ID from character_data

taskid

int

Task Identifier; ID from tasks table

slot

int

Slot; the slot number (up to 19) that causes the activity to

display in order to the client

type

tinyint

Task Type; 0=Task, 1=Shared, 2=Quest, 3=Expedition

acceptedtime

int

Accepted Time UNIX Timestamp

Character_Activities Table

Field Descriptions

Column

Data Type

Description

charid

int

Character Identifier; ID from character_data

taskid

int

Task Identifier; ID from tasks table

activityid

int

Activity Identifier, ID from tasks table

donecount

int

Done Count (IE 'items looted', 'npcs killed', etc.)

completed

tinyint

Completed: 0 = False, 1 = True

Completed Tasks

If the rule TaskSystem:RecordCompletedTasks is set to false, then this table is not used.

Field Descriptions

Column

Data Type

Description

charid

int

Character Identifier; ID from character_data table

completedtime

int

Completed Time UNIX Timestamp

taskid

int

Task Identifier; ID from tasks table

activityid

int

Activity Identifier; ID from tasks table

This table may have duplicate entries for repeatable tasks. To display Optional Tasks, be sure to set the rule TaskSystem:RecordCompletedOptionalTasks to true.

Goallists Table

Field Descriptions

Column

Data Type

Description

listid

int

Goal List Identifier; repeat ID for multiple entries

entry

int

Entry Identifier; either npc_type id or item id

Example: list id 10 for a "kill" mission could have three rows, all with list id 10, and entries of 2001, 2102, and 2103 (for Fippy Darkpaw, Kraxz Darkpaw, and Grarrax Darkpaw).

Proximities Table

The rule TaskSystem:EnableTaskProximity must be set to true to allow the use of proximities independent of proximities defined by quest scripts for npcs (IE for "explore" tasks).

Field Descriptions

Column

Data Type

Description

zoneid

int

Zone Identifier; use the zoneidnumber field

exploreid

int

Explore Identifier; match the goalid in the activity table for type 5 (explore) activities

minx

float

Minimum X Coordinate

maxx

float

Maximum X Coordinate

miny

float

Minimum Y Coordinate

maxy

float

Maximum Y Coordinate

minz

float

Minimum Z Coordinate

maxz

float

Maximum Z Coordinate

Overlapping proximities will only trigger proximity detection for the proximity with the lowest-numbered exploreid.

Tasksets Table

Task Sets are intended to make it easier to write quest NPCs that can offer a lot of tasks. While this functionality can also be achieved with quest::assigntask, it is important to note that players can remove tasks when writing your scripts. A Task Set could require a series of tasks in a progression.

Field Descriptions

Column

Data Type

Description

id

int

Unique Task Set Entry Identifier

taskid

int

Task Identifier; ID from the tasks table

Character_enabledtasks Table

Field Descriptions

Column

Data Type

Description

charid

int

Character Identifier; ID from character_data

taskid

int

Task Identifier; ID from tasks table

GM Commands

Command

Description

#task show

Shows the active tasks for the targeted client

#task update [count]

Updates the specified activity by 1, or by [count]

#task reloadall

Reload all information relating to tasks from DB (all zones)

#task reload task

Reload all information for the specified task from the DB (all zones)

#task reload lists

Reload all information from the goallists table (all zones)

#task reload prox

Reload all information from the proximities table (all zones)

#task reload sets

Reload task sets (all zones)

Task System Rules

Rule Name

Default Value

Description

TaskSystem:KeepOneRecordPerCompletedTask

True

Keeps one record for each completed task (the client displays the most recent 50; use quest::istaskcompleted for lookups).

TaskSystem:EnableTaskProximity

True

Makes use of the 'proximities' table, independent of quest::set_proximitiy

TaskSystem:RecordCompletedOptionalActivities

True

Makes use of the 'character_activities' table for optional tasks

TaskSystem:PeriodicCheckTimer

5

Seconds between checks for failed tasks. Also used by the 'Touch' activity

TaskSystem:RecordCompletedTasks

True

Makes use of the 'character_activities' table for non-optional tasks

TaskSystem:EnableTaskSystem

True

Globally enable or disable the Task system

QueryServ:PlayerLogTaskUpdates

False

Logs Player Task Updates

Logging Options

These options are present in the Logging System through logsys_categories or in-game via command #logs set [output] [type] [level]

1 LOG_CATEGORY( TASKS )
2 LOG_TYPE( TASKS, GLOBALLOAD, DISABLED )
3 LOG_TYPE( TASKS, CLIENTLOAD, DISABLED )
4 LOG_TYPE( TASKS, UPDATE, DISABLED )
5 LOG_TYPE( TASKS, CLIENTSAVE, DISABLED )
6 LOG_TYPE( TASKS, PACKETS, DISABLED )
7 LOG_TYPE( TASKS, PROXIMITY, DISABLED )

TASKS UPDATE is used to print out debug information when checking if activities are completed.

Quest API (for the task system)

These are the quest::[methods] and EVENT triggers that are related to the Task System.

Be sure to reference the Quest API in the event that functionality is expanded.

taskselector

Parameter(s):

task_id (int)

Usage:

Used to bring up the Task Selector Window with the specified tasks available for selection (from 1 to 40 task_id(s)). Note that when the task selector is brought up via this method, no check is made as to whether the character has the tasks enabled.

Example:

sub EVENT_SAY {
if ($text=~/hail/i) {
quest::say("Heyo! Looking for an exciting [task] to fill the time?");
}
if ($text=~/task/i) {
#:: Select task 103
quest::taskselector(103);
}
}

task_setselector

Parameter(s):

task_set_id (int)

Usage:

Sets the Task Set, by provided Task Set ID.

Example:

#:: Set task set 202
quest::task_setselector(202);

istaskactive

Parameter(s):

task_id (int)

Usage:

Used to determine if a task is active, by Task ID.

Example:

#:: Check if task 212 is active
quest::istaskactive(212); #:: Returns bool

istaskactivityactive

Parameter(s):

task_id (int), activity_id (int)

Usage:

Used to determine if a task activity is active, by Task ID and Activity ID.

Example:

#:: Check if Activity 9 of Task 212 is active
quest::istaskactivityactive(212, 9); #:: Returns bool

updatetaskactivity

Parameter(s):

task_id (int), activity_id (int), count (int), ignore_quest_update (bool)

Usage:

Used to increment the done count of the specified task is active. The parameter for ignore_quest_update is optional, and defaults to false; the parameter for count default to 1 (increase count by 1).

Example:

#:: Update Task ID 219 activity 9, by 1 count
quest::updatetaskactivity(216,9);

resettaskactivity

Parameter(s):

task_id (int), activity_id (int)

Usage:

Sets the done count to 0 for the specified Task ID

Example:

#:: Reset the activity done count for task 202
quest::resettaskactivity(202);

taskexplorearea

Parameter(s):

explore_id (int)

Usage:

Used to mark any explore activities (type 5), which have the numeric value Explore ID in their Goal ID field, and for which the Zone ID of the activity is either 0 or this zone, as completed.

Example:

#:: Mark Task 21 complete
quest::taskexplorearea(21);

assigntask

Parameter(s):

task_id (int), npcid (int), enforce_level_requirement = false (bool)

Usage:

Used to assign a task to a client, optionally this can include the NPC ID and whether or not to enforce the level requirement specified in the DB.

Example:

#:: Assign Task 102
quest::assigntask(102);
#:: Assign Task 103 with level requirement enforced
quest::assigntask(103, 1);
#:: Assign Task 104 and include the NPC ID
$client->AssignTask(104, $npc->GetID());
#:: Assign Task 105, include the NPC ID with level requirement enforced
$client->AssignTask(105, $npc->GetID(), 1);

failtask

Parameter(s):

task_id (int)

Usage:

Fails the task, by Task ID, for the client character that triggered the event.

Example:

#:: Fail Task 216
quest::failtask(216);

tasktimeleft

Parameter(s):

task_id (int)

Usage:

Returns the amount of time left, in seconds, before the specified task runs out. -1 is returned if there is no time limit, or if the player does not have the task.

Example:

#:: Create a scalar variable to store the amount of time left for Task ID 22
$timeremaining = quest::tasktimeleft(22); #:: Returns int
if ($timeremaining => 1) {
quest::say("You have $timeremaining seconds left--better hurry!");
}
else {
quest::say("Sorry $name, but you're out of time!");
}

istaskcompleted

Parameter(s):

task_id (int)

Usage:

Used to determine if a task is completed, by Task ID.

Example:

#:: Check if task 212 is completed
quest::istaskcompleted(212); #:: Returns bool

enabletask

Parameter(s):

task_id (int)

Usage:

Enables a task.

Example:

#:: Match if the player has an active task
if ($task != 0) {
#:: Create a scalar variable to store the active speak-to activity
$activity = quest::activespeakactivity($task);
#:: Mark the activity as complete
quest::updatetaskactivity($task, $activity);
quest::say("Well done!");
#:: Offer the next task, if there is one
if (!quest::istaskactive($task)) {
#:: Disable the task so that it cannot be repeated
quest::disabletask($task);
#:: Match if there are tasks remaining in the Task Set
if ($task != quest::lasttaskinset(200)) {
quest::say("Well done, I have another task if you are willing.");
#:: Enable the next Task in the Task Set
quest::enabletask(quest::nexttaskinset(200, $task));
}
#:: Match if there are no tasks remaining in the task set
else {
quest::say("Thank you for cleansing Qeynos Hills!");
}
}
}

disabletask

Parameter(s):

task_id (int)

Usage:

Disables a task so that it is not available to a client character. Useful if you do not want someone to repeat a task.

Example:

#:: Match if the player has an active task
if ($task != 0) {
#:: Create a scalar variable to store the active speak-to activity
$activity = quest::activespeakactivity($task);
#:: Mark the activity as complete
quest::updatetaskactivity($task, $activity);
quest::say("Well done!");
#:: Offer the next task, if there is one
if (!quest::istaskactive($task)) {
#:: Disable the task so that it cannot be repeated
quest::disabletask($task);
#:: Match if there are tasks remaining in the Task Set
if ($task != quest::lasttaskinset(200)) {
quest::say("Well done, I have another task if you are willing.");
#:: Enable the next Task in the Task Set
quest::enabletask(quest::nexttaskinset(200, $task));
}
#:: Match if there are no tasks remaining in the task set
else {
quest::say("Thank you for cleansing Qeynos Hills!");
}
}
}

istaskenabled

Parameter(s):

task_id (int)

Usage:

Used to determine if a task is enabled, by Task ID.

Example:

#:: Check if task 212 is enabled
quest::istaskenabled(212); #:: Returns bool

enabledtaskcount

Parameter(s):

task_set (int)

Usage:

Counts the enabled tasks in the specified Task Set.

Example:

#:: Match if there are no enabled tasks in Task Set 10
if (quest::enabledtaskcount(10) == 0) {
quest::enabletask(50, 51, 52);
}

firsttaskinset

Parameter(s):

task_set (int)

Usage:

Returns the first task in the specified Task Set.

Example:

sub EVENT_SAY {
#:: If the player hasn't completed the last task in the Task Set
if (!quest::istaskcompleted(quest::lasttaskinset(200))) {
#:: If the player has no tasks enabled for this task set, enable the first one
if (quest::enabledtaskcount(200) == 0) {
quest::say("You have not done any of my tasks before!");
#:: Enable the first task in Task Set 200
quest::enabletask(quest::firsttaskinset(200));
}
}
}

lasttaskinset

Parameter(s):

task_set (int)

Usage:

Returns the last task in the specified Task Set.

Example:

#:: Find the Task ID of the last task in Task Set 200
quest::lasttaskinset(200); #:: Returns int

nexttaskinset

Parameter(s):

task_set (int), task_id (int)

Usage:

Returns the next task in the specified Task Set that comes after the specified Task ID.

Example:

sub EVENT_SAY {
#:: Create a scalar variable to store a task integer
$task = quest::activespeaktask();
#:: Match if there is an active task to speak to the NPC
if ($task != 0) {
#:: Match if there are no active tasks for the current speaking task
if (!quest::istaskactive($task)) {
#:: Disable the current speaking task
quest::disabletask($task);
#:: Match if the current speaking task is NOT the last task in the Task Set
if ($task != quest::lasttaskinset(200)) {
quest::say("Well done, I have another task if you are willing.");
#:: Enable the next task in Task Set 200
quest::enabletask(quest::nexttaskinset(200, $task));
}
else {
quest::say("Thank you for cleansing Qeynos Hills!");
}
}
}
}

activespeaktask

Parameter(s):

None.

Usage:

Returns the Task ID of the lowest numbered task slot if the player who triggered the event has an active task with an active activity to speak to the NPC (returns 0 if not).

Example:

If you have task id 150: activity 0--kill three rats, activity 1--talk with NPC, activity 2--kill four fire beetles, activity 3--talk with NPC.

sub EVENT_SAY {
#:: Match text for hail, case insensitive
if ($text=~/hail/i) {
#:: Create a scalar variable to store the current task that has a speak activity
$speaktask = quest::activespeaktask(); #:: Returns int
#:: Match if there's an active task with a speak activity
if ($speaktask => 1) {
quest::say("You have a task to speak with me and its ID is $speaktask.");
}
#:: Match if there's NO active task with a speak activity
else {
quest::say("You do not have any tasks with a speaking activity at this time.");
}
}
}

activespeakactivity

Parameter(s):

task_id (int)

Usage:

Returns the Activity ID of the lowest numbered active activity to speak with an NPC in the specified task.

Example:

If you have task id 150: activity 0--kill three rats, activity 1--talk with NPC, activity 2--kill four fire beetles, activity 3--talk with NPC.

sub EVENT_SAY {
#:: Match text for hail, case insensitive
if ($text=~/hail/i) {
#:: Create a scalar variable to store the current speak activity for task 150
$speakactivity = quest::activespeakactivity(150); #:: Returns int
#:: Match if the player is on the first speak activity
if ($speakactivity == 1) {
quest::say("I really hate rats.");
}
#:: Match if the player is on the second speak activity
elsif ($speakactivity == 3) {
quest::say("I really hate fire beetles.");
}
}
}

activetasksinset

Parameter(s):

task_set (int)

Usage:

Returns the number of tasks in the given TaskSet that the player has active.

Example:

You have a TaskSet "20", which consists of three tasks--200, 201, 202.

sub EVENT_SAY {
#:: Create a scalar variable to store the number of active tasks in TaskSet 20
$activetaskcount = quest::activetasksinset(20); #:: returns int
#:: Match text for hail, case insensitive
if ($text=~/hail/i) {
quest::say("You have $activetaskcount tasks remaining.");
}
}

completedtasksinset

Parameter(s):

task_set (int)

Usage:

Returns the number of tasks in the given Task Set that the player has completed.

Example:

sub EVENT_SAY {
#:: Match text for "tasks", case insensitive
if ($text=~/tasks/i) {
#:: Create a scalar variable to store the count of completed tasks in task set "200"
my $TasksComplete = quest::completedtasksinset(200); #:: Returns int
quest::say("You have completed $TasksComplete tasks.");
}
}

EVENT_TASKACCEPTED

Trigger

  • when a player accepts a task from the task selector window.

If the assigntask(taskid) function is used to forcibly assign a task to a player, then this sub will also be called with task_id set to taskid if assigntask is successful.

EVENT_TASK_COMPLETE

Trigger

  • when a player completes a task.

Exports

Name

Type

Usage

donecount

int

quest::say($donecount); # returns int

activity_id

int

quest::say($activity_id); # returns int

task_id

int

quest::say($task_id); # returns int

EVENT_TASK_FAIL

Trigger

  • When a player fails a task.

Exports

Name

Type

Usage

task_id

int

quest::say($task_id); # returns int

EVENT_TASK_STAGE_COMPLETE

Trigger

  • When a task stage is completed.

Exports

Name

Type

Usage

activity_id

int

quest::say($activity_id); # returns int

task_id

int

quest::say($task_id); # returns int

Example

  • In this example, when a player completes a task, it triggers the event and tries to match with task ID 212; if it matches, a yellow message is displayed to the client.

Perl
Lua
Perl
sub EVENT_TASK_STAGE_COMPLETE {
#:: Match task id 212
if ($task_id == 212) {
$client->Message(15,"The zombie presence seems somewhat lessened, and perhaps they have been quelled...for the time being.");
}
}
Lua
function event_task_stage_complete(e)
--:: Match task id 212
if (e.task_id == 212) then
e.self:Message(15, "The zombie presence seems somewhat lessened, and perhaps they have been quelled...for the time being.");
end
end

EVENT_TASK_UPDATE

Trigger

  • when a player's task is updated.

Exports

Name

Type

Usage

donecount

int

quest::say($donecount); # returns int

activity_id

int

quest::say($activity_id); # returns int

task_id

int

quest::say($task_id); # returns int