eqemu-server/zone/tasks.h
2013-02-16 16:14:39 -08:00

263 lines
8.4 KiB
C++

/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TASKS_H
#define TASKS_H
#include "../common/types.h"
#include "mob.h"
#include <vector>
#include <queue>
using namespace std;
#define MAXTASKS 10000
#define MAXTASKSETS 1000
// The Client has a hard cap of 19 active tasks
#define MAXACTIVETASKS 19
// The Max Chooser (Task Selector entries) is capped at 40 in the Titanium Client.
#define MAXCHOOSERENTRIES 40
// The Client has a hard cap of 20 activities per task.
#define MAXACTIVITIESPERTASK 20
// This is used to determine if a client's active task slot is empty.
#define TASKSLOTEMPTY 0
// Command Codes for worldserver ServerOP_ReloadTasks
//
#define RELOADTASKS 0
#define RELOADTASKGOALLISTS 1
#define RELOADTASKPROXIMITIES 2
#define RELOADTASKSETS 3
class Client;
struct TaskGoalList_Struct {
int ListID;
int Size;
int Min, Max;
int *GoalItemEntries;
};
// This is used for handling lists, loading them from the database, searching them.
// Used for lists of NPCs to kill, items to loot, etc, as well as lists of items to
// reward the player with on completion of the task.
//
class TaskGoalListManager {
public:
TaskGoalListManager();
~TaskGoalListManager();
bool LoadLists();
int GetListByID(int ListID);
bool IsInList(int ListID, int Entry);
int GetFirstEntry(int ListID);
vector<int> GetListContents(int ListIndex);
private:
TaskGoalList_Struct *TaskGoalLists;
int NumberOfLists;
};
typedef struct {
int ExploreID;
float MinX, MaxX, MinY, MaxY, MinZ, MaxZ;
} TaskProximity;
// This class is used for managing proximities so that Quest NPC proximities don't need to be used.
class TaskProximityManager {
public:
TaskProximityManager();
~TaskProximityManager();
bool LoadProximities(int ZoneID);
int CheckProximities(float X, float Y, float Z);
private:
vector<TaskProximity> TaskProximities;
};
typedef enum { METHODSINGLEID = 0, METHODLIST = 1, METHODQUEST = 2 } TaskMethodType;
struct ActivityInformation {
int StepNumber;
int Type;
char *Text1;
char *Text2;
char *Text3;
int GoalID;
TaskMethodType GoalMethod;
int GoalCount;
int DeliverToNPC;
int ZoneID;
bool Optional;
};
typedef enum { ActivitiesSequential = 0, ActivitiesStepped = 1 } SequenceType;
struct TaskInformation {
int Duration;
char *Title;
char *Description;
char *Reward;
int RewardID;
int CashReward; // Expressed in copper
int XPReward;
TaskMethodType RewardMethod;
int StartZone;
int ActivityCount;
SequenceType SequenceMode;
int LastStep;
short MinLevel;
short MaxLevel;
bool Repeatable;
ActivityInformation Activity[MAXACTIVITIESPERTASK];
};
typedef enum { ActivityHidden = 0, ActivityActive = 1, ActivityCompleted = 2 } ActivityState;
typedef enum { ActivityDeliver = 1, ActivityKill = 2, ActivityLoot = 3, ActivitySpeakWith = 4, ActivityExplore = 5,
ActivityTradeSkill = 6, ActivityFish = 7, ActivityForage = 8, ActivityUse1 = 9, ActivityUse2 = 10,
ActivityTouch = 11, ActivityGiveCash = 100 } ActivityType;
struct ClientActivityInformation {
int ActivityID;
int DoneCount;
ActivityState State;
bool Updated; // Flag so we know if we need to update the database
};
struct ClientTaskInformation {
int TaskID;
int CurrentStep;
int AcceptedTime;
bool Updated;
ClientActivityInformation Activity[MAXACTIVITIESPERTASK];
};
struct CompletedTaskInformation {
int TaskID;
int CompletedTime;
bool ActivityDone[MAXACTIVITIESPERTASK];
};
class ClientTaskState {
public:
ClientTaskState();
~ClientTaskState();
void ShowClientTasks(Client *c);
inline int GetActiveTaskCount() { return ActiveTaskCount; }
int GetActiveTaskID(int index);
bool IsTaskActivityCompleted(int index, int ActivityID);
int GetTaskActivityDoneCount(int index, int ActivityID);
int GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID);
int GetTaskStartTime(int index);
void AcceptNewTask(Client *c, int TaskID, int NPCID);
void FailTask(Client *c, int TaskID);
int TaskTimeLeft(int TaskID);
int IsTaskCompleted(int TaskID);
bool IsTaskActive(int TaskID);
bool IsTaskActivityActive(int TaskID, int ActivityID);
ActivityState GetTaskActivityState(int index, int ActivityID);
void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count);
void ResetTaskActivity(Client *c, int TaskID, int ActivityID);
void CancelTask(Client *c, int SequenceNumber, bool RemoveFromDB = true);
void CancelAllTasks(Client *c);
void RemoveTask(Client *c, int SequenceNumber);
bool UpdateTasksByNPC(Client *c, int ActivityType, int NPCTypeID);
void UpdateTasksOnKill(Client *c, int NPCTypeID);
void UpdateTasksForItem(Client *c, ActivityType Type, int ItemID, int Count=1);
void UpdateTasksOnExplore(Client *c, int ExploreID);
bool UpdateTasksOnSpeakWith(Client *c, int NPCTypeID);
bool UpdateTasksOnDeliver(Client *c, uint32 *Items, int Cash, int NPCTypeID);
void UpdateTasksOnTouch(Client *c, int ZoneID);
void ProcessTaskProximities(Client *c, float X, float Y, float Z);
bool TaskOutOfTime(int Index);
void TaskPeriodicChecks(Client *c);
void SendTaskHistory(Client *c, int TaskIndex);
void RewardTask(Client *c, TaskInformation *Task);
void EnableTask(int CharID, int TaskCount, int *TaskList);
void DisableTask(int CharID, int TaskCount, int *TaskList);
bool IsTaskEnabled(int TaskID);
int EnabledTaskCount(int TaskSetID);
int ActiveSpeakTask(int NPCID);
int ActiveSpeakActivity(int NPCID, int TaskID);
int ActiveTasksInSet(int TaskSetID);
int CompletedTasksInSet(int TaskSetID);
friend class TaskManager;
private:
bool UnlockActivities(int CharID, int TaskIndex);
void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count=1);
int ActiveTaskCount;
ClientTaskInformation ActiveTasks[MAXACTIVETASKS];
vector<int>EnabledTasks;
vector<CompletedTaskInformation> CompletedTasks;
int LastCompletedTaskLoaded;
bool CheckedTouchActivities;
};
class TaskManager {
public:
TaskManager();
~TaskManager();
int GetActivityCount(int TaskID);
bool LoadSingleTask(int TaskID);
bool LoadTasks(int SingleTask=0);
void ReloadGoalLists();
inline void LoadProximities(int ZoneID) { ProximityManager.LoadProximities(ZoneID); }
bool LoadTaskSets();
bool LoadClientState(Client *c, ClientTaskState *state);
bool SaveClientState(Client *c, ClientTaskState *state);
void SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *TaskList);
void SendTaskSelectorNew(Client *c, Mob *mob, int TaskCount, int *TaskList);
bool AppropriateLevel(int TaskID, int PlayerLevel);
void TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID);
void SendActiveTasksToClient(Client *c, bool TaskComplete=false);
void SendSingleActiveTaskToClient(Client *c, int TaskIndex, bool TaskComplete, bool BringUpTaskJournal=false);
void SendTaskActivityShort(Client *c, int TaskID, int ActivityID, int ClientTaskIndex);
void SendTaskActivityLong(Client *c, int TaskID, int ActivityID, int ClientTaskIndex,
bool Optional, bool TaskComplete=false);
void SendTaskActivityNew(Client *c, int TaskID, int ActivityID, int ClientTaskIndex,
bool Optional, bool TaskComplete=false);
void SendCompletedTasksToClient(Client *c, ClientTaskState *state);
void ExplainTask(Client *c, int TaskID);
int FirstTaskInSet(int TaskSet);
int LastTaskInSet(int TaskSet);
int NextTaskInSet(int TaskSet, int TaskID);
bool IsTaskRepeatable(int TaskID);
friend class ClientTaskState;
private:
TaskGoalListManager GoalListManager;
TaskProximityManager ProximityManager;
TaskInformation* Tasks[MAXTASKS];
vector<int> TaskSets[MAXTASKSETS];
void SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal=false);
};
#endif