Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #1  
Old 08-07-2008, 04:04 PM
Flare83
Sarnak
 
Join Date: Aug 2008
Location: usa
Posts: 43
Default

Damn edit button

The main things i remember from the task system was

EQlive must of kept a table for what quests you completed. Becuase some of the quests where long 12 mission arcs.
DoN used it heavely for its raids/group content.
GoD/OoW used the alt+z window for it's missions. i think they are alot different but on the other hand might be alot alike /shrug.
Ldon used alt+v i think
Reply With Quote
  #2  
Old 08-07-2008, 05:35 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

Quote:
No, the way I see it working is, whenever you kill a mob, or loot something, the server will need to check if you have any active tasks, and if killing that mob, or looting that item, was an objective of the task, then incrementing the kill/loot count for the task and sending the Task Complete packet when you have killed/looted the required number.
Basically, we can already handle this kind of stuff via player quests too, proximity mobs for explore etc.

Would add a internal task tracking system for time, completion/failure and maybe item amounts since that would be cumbersome then could probably do the rest via quests.

quest::updatetaskvalue(taskfield,value)
quest::enabletaskforplayer()
quest::disabletaskforplayer()
quest::opentaskwindow()
quest::istaskcompleted(taskid)

etc. probably more or different.

Biggest issue if you've gotten most the packets worked out will probably be trying to with some finesse track the quests offered. Since quests offered to a player will vary based on: who the player is(race,class), what they've done(tasks/quests complete), which npc is giving it.

That said if you need help and I get time I'd be most excited to help you hammer out a system to do it.
Reply With Quote
  #3  
Old 08-08-2008, 03:11 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Maybe quest globals could be used for tracking purposes for tasks? They sounds to be similar systems and I think you would just need to allow the task window to work with the quest globals system. If so, it seems like it would minimize the work needed to get this finished. Or maybe use some of the code from the globals system to implement something similar to be used only for tasks. I am sure you would need a table for tracking them and similar fields.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #4  
Old 08-08-2008, 04:49 AM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

Actually it would probably be harder to integrate it into an old system than to create a new one as the system would probably be fairly straight forward really. For performance issues I think also it's probably not a good idea; think every time you have to do a quest action you need to re-export globals, integrating it into qglobals would probably inc the number of globals in use by a lot and make it just that much more work every time the server processed quests.
Reply With Quote
  #5  
Old 08-08-2008, 06:09 AM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

Quote:
Originally Posted by KLS View Post
Actually it would probably be harder to integrate it into an old system than to create a new one as the system would probably be fairly straight forward really.

Yes, I was looking at the quest system this morning, and that was my thought.

While I am at work, I thought I would start sketching out how to implement this,
and welcome any thoughts you have on my tentative design choices.

First the tables. Global tables for the stuff that doesn't change (once the task is written),
and character tables to record their progress.


Code:
CREATE TABLE GlobalTasks (
	id int(11) unsigned NOT NULL,
	duration int(11) unsgined NOT NULL,
	description varchar(4000) NOT NULL,
	reward varchar(100) NOT NULL,
	startzone int(11) NOT NULL,
	PRIMARY KEY(id)
)

CREATE TABLE GlobalActivities (
	id int(11) unsigned NOT NULL,
	activityid int(11) unsigned default '0',
	activitytype tinyint unsigned,   // Kill, Loot, Deliver, Explore, etc
	text1 VARCHAR(100) default '',   // For Deliver tasks, this is the NPC name to deliver to, or name of mob for kill tasks etc
	text2 VARCHAR(100) default '',   // For Deliver tasks, this is the text name of the item to deliver, or item to loot for loot tasks
	itemid int(11),			 // item number for loot tasks.
	npcid int(11),                   // npcid for kill tasks
	exploreid int(11) default 0,     // For explore tasks, this is a unique number to identify the proximity event that needs to be triggered
        goalcount tinyint default 1,     // How many things to kill, deliver, loot, etc
        zoneid int(11),                  // The ID number of the zone that this task is performed in
	PRIMARY KEY(id, activityid)
)

I am unsure as to whether the text1/text2 fields are required,
or whether I should just pull the npc name/item name as
required based on their id. The npc name/item name is sent as
text in the Task packets. Keeping the text fields as well would
allow the Task designer to be a bit vaguer/ more 'roleplay' in
their objectives if they wished, e.g. 'Kill the master of Karnor'
rather than 'Kill Venril Sathir'.


CREATE TABLE CharacterTasks (
	charid int(11) unsigned NOT NULL,
	taskid int(11) unsigned NOT NULL,
	acceptedtime int(11) unsigned,               // Timestamp of when the player accepted the task
	completedtime int(11) unsigned default '0',  // 0 for an unfished task
	PRIMARY KEY(charid, taskid)
)

CREATE TABLE CharacterActivities (
	charid int(11) unsigned NOT NULL,
	taskid int(11) unsigned NOT NULL,
	activityid int(11) unsigned,
	donecount tinyint default '0',
	completed tinyint(1) default '0', // Not strictly needed, but probably quicker than cross referencing the Global Activity table to check if an activity is complete
        PRIMARY KEY(charid, taskid, activityid)
)
The active and completed task information is not retained by the client, certainly not across
logins, and probably not across zoning, so needs to be resent after zoning.

As I see it, zone will need to load the global task and activity tables in their entirety on
zone bootup. This may become an issue later on if their are lots of tasks written. As this is
global static data, it could be a candidate for shared memory, but I will leave that for the
future.

The next issue is how to represent the Tasks in memory. Each Task has a unique ID. I am leaning
toward #defining a MAXTASKID (say 10000 ?), and using a fixed size array ...

TaskInformation* Tasks[MAXTASKID]

The benefit I see of doing this is fast cross referencing to the Task/Activity information from
the per-character data. I think this would also make it easier to #reloadtask a single task
during development.

Onto the per-character info. Should I restrict a character to a maximum number of active tasks, e.g. 20 ?
The benefit I see to this is it constrains the amount of checking that needs to be done on killing/looting
to see if there is a matching goal in the characters active activities.

Pseudo Code:

On NPC Kill or Loot:
for each active task the character has:
for each open activity in that Task:
if ActivityGoal == Kill This NPCType or Loot this item.id Increment Goal Count

It did occur to me that an extra flag could be added to the npc_types and item tables, 'involvedintask',
so that the code could check this flag and if it is set to No, not bother checking the characters
active tasks.

Task initiation will be done through the existing Perl quest system, so the usual checks
for class, race, faction can be done before the NPC initiates the Task Chooser. (Also provide
a function so that a check can be made in Perl to see if the player has already completed
a particular task, so as not to offer it again).

I also see Task Completion/Reward as being handled by the Perl quest system, i.e. the last
activity in a Task would be go speak to an NPC who would then do something along the lines
of:

Code:
if quest::ActiveTask(1234) && quest::TaskActivityComplete(1234,10) .... give reward, quest::TaskComplete(1234)
I would be interested in any links to quests on Alla that use the Task system. I've
been using http://everquest.allakhazam.com/db/q...tml?quest=3237 as a guide, as
that is the one in the packet collect I was looking at.
Reply With Quote
  #6  
Old 08-08-2008, 10:19 AM
Andrew80k
Dragon
 
Join Date: Feb 2007
Posts: 659
Default

Looks like you have a good handle on it, and your initial approach seems viable to me. I would think that limiting the number of active quests a toon can have is wise at this point. Once you get started implementing it, I'm sure you'll come across other challenges. As for tasks, I'm mostly familiar with these...

This is an example of a collect task:

http://everquest.allakhazam.com/db/q...tml?quest=4320

This is a combo kill/collect:

http://everquest.allakhazam.com/db/q...tml?quest=3065

I know we're not up to DoN yet, but these tasks are examples.
Reply With Quote
  #7  
Old 08-08-2008, 04:54 PM
KLS
Administrator
 
Join Date: Sep 2006
Posts: 1,348
Default

Quote:
Task initiation will be done through the existing Perl quest system, so the usual checks
for class, race, faction can be done before the NPC initiates the Task Chooser. (Also provide
a function so that a check can be made in Perl to see if the player has already completed
a particular task, so as not to offer it again).
See this to me presents a unique problem in that it would be cumbersome if not impossible to write quests to include all the tasks a person has from a given npc. Keep in mind some task givers are giving out lots and lots of tasks, especially the ones for shards and such give out literal boatloads of tasks.

Personally I'd do something like:

Code:
CREATE TABLE TaskSet (
	id int(11) unsigned NOT NULL,
	globaltaskid int(11) unsgined NOT NULL,
	PRIMARY KEY(id, globaltaskid)
)
Would allow you to group tasks together into tasksets and the quest code could be simplified to quest::BringUpTaskWindow(taskset). Different npcs offer different tasks and more than 1 at a time if you qualify for them on live.

Would also need some way of enabling the tasks if one were to go with such an implementation.
Quote:
CREATE TABLE CharacterTasksEnabled (
charid int(11) unsigned NOT NULL,
taskid int(11) unsigned NOT NULL,
enabled tinyint(1) default '0',
PRIMARY KEY(charid, taskid)
)
Could then offer quest::EnableTask(taskid), quest::DisableTask(taskid), etc to make it much simpler to write quests that use the task system.

Putting it in shared memory is also probably a better option as the structures are probably going to need to be in some cases quite large and with the assumed 10000 entries it would really add up for a server that loads quite a few zones. A couple MB per zone doesn't seem like a big deal until you load up 50.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 06:33 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3