Merge pull request #438 from hateborne/master

Add Optional Enforce Task Level Requirement on AssignTask
This commit is contained in:
Akkadius 2015-07-16 18:12:06 -05:00
commit 417b034273
10 changed files with 72 additions and 15 deletions

View File

@ -1,5 +1,12 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 07/15/2015 ==
Hateborne: Added optional ability to enforce task level requirements in perl and lua via an added, optional parameter to $client->AssignTask and quest::assigntask.
Use cases:
quest::assigntask(703); # this still assigns the task as normal, no functional change
quest::assigntask(703, 1); # this will assign the task, provided the character meets the db-stored level requirements
$client->AssignTask(703, $npc->GetID()); # still assigns the task as normal, no functional change
$client->AssignTask(703, $npc->GetID(), 1); # this will assign the task, provided the character meets the db-stored level requirements
== 07/06/2015 ==
mackal: Implement Triple Attack Skill
Parses showed about rand(1000) for the chance, may need more investigating

View File

@ -997,7 +997,7 @@ public:
inline void DisableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->DisableTask(CharacterID(), TaskCount, TaskList); }
inline bool IsTaskEnabled(int TaskID) { return (taskstate ? taskstate->IsTaskEnabled(TaskID) : false); }
inline void ProcessTaskProximities(float X, float Y, float Z) { if(taskstate) taskstate->ProcessTaskProximities(this, X, Y, Z); }
inline void AssignTask(int TaskID, int NPCID) { if(taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID); }
inline void AssignTask(int TaskID, int NPCID, bool enforce_level_requirement = false) { if (taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID, enforce_level_requirement); }
inline int ActiveSpeakTask(int NPCID) { if(taskstate) return taskstate->ActiveSpeakTask(NPCID); else return 0; }
inline int ActiveSpeakActivity(int NPCID, int TaskID) { if(taskstate) return taskstate->ActiveSpeakActivity(NPCID, TaskID); else return 0; }
inline void FailTask(int TaskID) { if(taskstate) taskstate->FailTask(this, TaskID); }

View File

@ -2383,11 +2383,19 @@ XS(XS__assigntask)
{
dXSARGS;
unsigned int taskid;
if(items == 1) {
bool enforce_level_requirement = false;
if(items == 1 || items == 2) {
taskid = (int)SvIV(ST(0));
quest_manager.assigntask(taskid);
if (items == 2)
{
if ((int)SvIV(ST(1)) == 1)
{
enforce_level_requirement = true;
}
}
quest_manager.assigntask(taskid, enforce_level_requirement);
} else {
Perl_croak(aTHX_ "Usage: assigntask(taskid)");
Perl_croak(aTHX_ "Usage: assigntask(taskid, enforce_level_requirement)");
}
XSRETURN_EMPTY;

View File

@ -1077,6 +1077,11 @@ void Lua_Client::AssignTask(int task, int npc_id) {
self->AssignTask(task, npc_id);
}
void Lua_Client::AssignTask(int task, int npc_id, bool enforce_level_requirement) {
Lua_Safe_Call_Void();
self->AssignTask(task, npc_id, enforce_level_requirement);
}
void Lua_Client::FailTask(int task) {
Lua_Safe_Call_Void();
self->FailTask(task);
@ -1525,6 +1530,7 @@ luabind::scope lua_register_client() {
.def("FindSpellBookSlotBySpellID", (int(Lua_Client::*)(int))&Lua_Client::FindSpellBookSlotBySpellID)
.def("UpdateTaskActivity", (void(Lua_Client::*)(int,int,int))&Lua_Client::UpdateTaskActivity)
.def("AssignTask", (void(Lua_Client::*)(int,int))&Lua_Client::AssignTask)
.def("AssignTask", (void(Lua_Client::*)(int,int,bool))&Lua_Client::AssignTask)
.def("FailTask", (void(Lua_Client::*)(int))&Lua_Client::FailTask)
.def("IsTaskCompleted", (bool(Lua_Client::*)(int))&Lua_Client::IsTaskCompleted)
.def("IsTaskActive", (bool(Lua_Client::*)(int))&Lua_Client::IsTaskActive)

View File

@ -242,6 +242,7 @@ public:
int FindSpellBookSlotBySpellID(int spell_id);
void UpdateTaskActivity(int task, int activity, int count);
void AssignTask(int task, int npc_id);
void AssignTask(int task, int npc_id, bool enforce_level_requirement);
void FailTask(int task);
bool IsTaskCompleted(int task);
bool IsTaskActive(int task);

View File

@ -5126,13 +5126,20 @@ XS(XS_Client_AssignTask); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_AssignTask)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: Client::AssignTask(THIS, TaskID, NPCID)");
if (items != 3 && items != 4)
Perl_croak(aTHX_ "Usage: Client::AssignTask(THIS, TaskID, NPCID, enforce_level_requirement)");
{
Client * THIS;
int TaskID = (int)SvIV(ST(1));
int NPCID = (int)SvIV(ST(2));
bool enforce_level_requirement = false;
if (items == 4)
{
if ((int)SvIV(ST(3)) == 1)
{
enforce_level_requirement = true;
}
}
if (sv_derived_from(ST(0), "Client")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Client *,tmp);
@ -5142,7 +5149,7 @@ XS(XS_Client_AssignTask)
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->AssignTask(TaskID, NPCID);
THIS->AssignTask(TaskID, NPCID, enforce_level_requirement);
}
XSRETURN_EMPTY;
}
@ -6477,7 +6484,7 @@ XS(boot_Client)
newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$");
newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$");
newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$");
newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$");
newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$");
newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$");
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$");

View File

@ -2200,11 +2200,11 @@ void QuestManager::taskexploredarea(int exploreid) {
initiator->UpdateTasksOnExplore(exploreid);
}
void QuestManager::assigntask(int taskid) {
void QuestManager::assigntask(int taskid, bool enforce_level_requirement) {
QuestManagerCurrentQuestVars();
if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner)
initiator->AssignTask(taskid, owner->GetID());
if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner)
initiator->AssignTask(taskid, owner->GetID(), enforce_level_requirement);
}
void QuestManager::failtask(int taskid) {

View File

@ -188,7 +188,7 @@ public:
void updatetaskactivity(int task, int activity, int count, bool ignore_quest_update = false);
void resettaskactivity(int task, int activity);
void taskexploredarea(int exploreid);
void assigntask(int taskid);
void assigntask(int taskid, bool enforce_level_requirement = false);
void failtask(int taskid);
int tasktimeleft(int taskid);
int istaskcompleted(int taskid);

View File

@ -895,6 +895,26 @@ bool TaskManager::AppropriateLevel(int TaskID, int PlayerLevel) {
}
int TaskManager::GetTaskMinLevel(int TaskID)
{
if (Tasks[TaskID]->MinLevel)
{
return Tasks[TaskID]->MinLevel;
}
return -1;
}
int TaskManager::GetTaskMaxLevel(int TaskID)
{
if (Tasks[TaskID]->MaxLevel)
{
return Tasks[TaskID]->MaxLevel;
}
return -1;
}
void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID) {
unsigned int EnabledTaskIndex = 0;
@ -2948,7 +2968,7 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) {
}
void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID) {
void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement) {
if(!taskmanager || TaskID<0 || TaskID>=MAXTASKS) {
c->Message(13, "Task system not functioning, or TaskID %i out of range.", TaskID);
@ -2973,6 +2993,12 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID) {
}
}
if (enforce_level_requirement && !taskmanager->AppropriateLevel(TaskID, c->GetLevel()))
{
c->Message(13, "You are outside the level range of this task.");
return;
}
if(!taskmanager->IsTaskRepeatable(TaskID) && IsTaskCompleted(TaskID)) return;
// We do it this way, because when the Client cancels a task, it retains the sequence number of the remaining

View File

@ -168,7 +168,7 @@ public:
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 AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
void FailTask(Client *c, int TaskID);
int TaskTimeLeft(int TaskID);
int IsTaskCompleted(int TaskID);
@ -230,6 +230,8 @@ public:
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);
int GetTaskMinLevel(int TaskID);
int GetTaskMaxLevel(int TaskID);
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);