mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-24 03:22:26 +00:00
Merge branch 'shared_tasks' of github.com:EQEmu/Server into shared_tasks_service
This commit is contained in:
commit
0b26c80d8f
@ -1393,11 +1393,13 @@ sub fetch_latest_windows_binaries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub fetch_latest_windows_binaries_bots {
|
sub fetch_latest_windows_binaries_bots {
|
||||||
print "[Update] Fetching Latest Windows Binaries with Bots...\n";
|
print "[Update] Fetching Latest Windows Binaries (unstable) with Bots...\n";
|
||||||
get_remote_file($install_repository_request_url . "master_windows_build_bots.zip", "updates_staged/master_windows_build_bots.zip", 1);
|
get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/eqemu-x86-bots.zip", "updates_staged/eqemu-x86-bots.zip", 1);
|
||||||
|
#::: old repository kept for reference until no issues reported
|
||||||
|
#::: get_remote_file($install_repository_request_url . "master_windows_build_bots.zip", "updates_staged/master_windows_build_bots.zip", 1);
|
||||||
print "[Update] Fetched Latest Windows Binaries with Bots...\n";
|
print "[Update] Fetched Latest Windows Binaries with Bots...\n";
|
||||||
print "[Update] Extracting...\n";
|
print "[Update] Extracting...\n";
|
||||||
unzip('updates_staged/master_windows_build_bots.zip', 'updates_staged/binaries/');
|
unzip('updates_staged/eqemu-x86-bots.zip', 'updates_staged/binaries/');
|
||||||
my @files;
|
my @files;
|
||||||
my $start_dir = "updates_staged/binaries";
|
my $start_dir = "updates_staged/binaries";
|
||||||
find(
|
find(
|
||||||
|
|||||||
@ -21,30 +21,30 @@ CREATE TABLE `task_replay_groups` (
|
|||||||
PRIMARY KEY(`id`)
|
PRIMARY KEY(`id`)
|
||||||
);
|
);
|
||||||
CREATE TABLE `character_task_lockouts` (
|
CREATE TABLE `character_task_lockouts` (
|
||||||
`charid` INT NOT NULL,
|
`character_id` INT NOT NULL,
|
||||||
`replay_group` INT NOT NULL,
|
`replay_group` INT NOT NULL,
|
||||||
`original_id` INT NOT NULL,
|
`original_id` INT NOT NULL,
|
||||||
`timestamp` INT NOT NULL,
|
`timestamp` INT NOT NULL,
|
||||||
PRIMARY KEY(`charid`, `replay_group`)
|
PRIMARY KEY(`character_id`, `replay_group`)
|
||||||
);
|
);
|
||||||
CREATE TABLE `shared_task_state` (
|
CREATE TABLE `shared_task_state` (
|
||||||
`id` INT NOT NULL,
|
`id` INT NOT NULL,
|
||||||
`taskid` INT NOT NULL,
|
`task_id` INT NOT NULL,
|
||||||
`acceptedtime` INT NOT NULL,
|
`accepted_time` INT NOT NULL,
|
||||||
`locked` TINYINT NOT NULL DEFAULT '0',
|
`is_locked` TINYINT NOT NULL DEFAULT '0',
|
||||||
PRIMARY KEY(`id`)
|
PRIMARY KEY(`id`)
|
||||||
);
|
);
|
||||||
CREATE TABLE `shared_task_activities` (
|
CREATE TABLE `shared_task_activities` (
|
||||||
`shared_id` INT NOT NULL,
|
`shared_task_id` INT NOT NULL,
|
||||||
`activity_id` INT NOT NULL,
|
`activity_id` INT NOT NULL,
|
||||||
`done_count` INT NOT NULL,
|
`done_count` INT NOT NULL,
|
||||||
`completed` TINYINT,
|
`completed` TINYINT,
|
||||||
PRIMARY KEY(`shared_id`, `activity_id`)
|
PRIMARY KEY(`shared_task_id`, `activity_id`)
|
||||||
);
|
);
|
||||||
CREATE TABLE `shared_task_members` (
|
CREATE TABLE `shared_task_members` (
|
||||||
`shared_id` INT NOT NULL,
|
`shared_task_id` INT NOT NULL,
|
||||||
`charid` INT NOT NULL,
|
`character_id` INT NOT NULL,
|
||||||
`name` VARCHAR(64) NOT NULL,
|
`character_name` VARCHAR(64) NOT NULL,
|
||||||
`leader` TINYINT,
|
`is_leader` TINYINT DEFAULT 0,
|
||||||
PRIMARY KEY(`charid`)
|
PRIMARY KEY(shared_task_id, character_id)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -23,6 +23,7 @@ data_buckets
|
|||||||
db_str
|
db_str
|
||||||
doors
|
doors
|
||||||
eqtime
|
eqtime
|
||||||
|
faction_base_data
|
||||||
faction_list
|
faction_list
|
||||||
faction_list_mod
|
faction_list_mod
|
||||||
fear_hints
|
fear_hints
|
||||||
|
|||||||
@ -373,7 +373,7 @@ int ClientListEntry::GetTaskLockoutTimeLeft(int id) const
|
|||||||
[id](const TaskTimer &a) { return a.ID == id; });
|
[id](const TaskTimer &a) { return a.ID == id; });
|
||||||
|
|
||||||
if (it != m_task_replay_timers.end())
|
if (it != m_task_replay_timers.end())
|
||||||
return it->expires - Timer::GetCurrentTime();
|
return it->expires - time(nullptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -384,7 +384,7 @@ int ClientListEntry::GetTaskLockoutTimeLeft(int id) const
|
|||||||
bool ClientListEntry::CleanExpiredTaskLockouts() const
|
bool ClientListEntry::CleanExpiredTaskLockouts() const
|
||||||
{
|
{
|
||||||
std::string query =
|
std::string query =
|
||||||
StringFormat("DELETE FROM `character_task_lockouts` WHERE `charid` = %i AND `timestamp` > %i", pcharid,
|
StringFormat("DELETE FROM `character_task_lockouts` WHERE `character_id` = %i AND `timestamp` > %i", pcharid,
|
||||||
Timer::GetCurrentTime());
|
Timer::GetCurrentTime());
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
return results.Success();
|
return results.Success();
|
||||||
@ -397,7 +397,7 @@ bool ClientListEntry::LoadTaskLockouts()
|
|||||||
{
|
{
|
||||||
CleanExpiredTaskLockouts();
|
CleanExpiredTaskLockouts();
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
"SELECT `replay_group`, `original_id`, `timestamp` FROM `character_task_lockouts` WHERE `charid` = %i",
|
"SELECT `replay_group`, `original_id`, `timestamp` FROM `character_task_lockouts` WHERE `character_id` = %i",
|
||||||
pcharid);
|
pcharid);
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
|
|||||||
@ -82,7 +82,7 @@ void SharedTaskManager::HandleTaskRequest(ServerPacket *pack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto &task = ret.first->second;
|
auto &task = ret.first->second;
|
||||||
task.AddMember(leader_name, cle_leader, true);
|
task.AddMember(leader_name, cle_leader, cle_leader->CharID(), true);
|
||||||
|
|
||||||
if (players.empty()) {
|
if (players.empty()) {
|
||||||
// send instant success to leader
|
// send instant success to leader
|
||||||
@ -133,7 +133,7 @@ void SharedTaskManager::HandleTaskRequest(ServerPacket *pack)
|
|||||||
|
|
||||||
// check our lock out timer
|
// check our lock out timer
|
||||||
int expires = cle->GetTaskLockoutExpire(task_id);
|
int expires = cle->GetTaskLockoutExpire(task_id);
|
||||||
if ((expires - Timer::GetCurrentTime()) >= 0) {
|
if ((expires - time(nullptr)) >= 0) {
|
||||||
// failure TODO: appropriate message, we need to send the timestamp here
|
// failure TODO: appropriate message, we need to send the timestamp here
|
||||||
auto pack = new ServerPacket(ServerOP_TaskReject, leader_name.size() + 1 + 8);
|
auto pack = new ServerPacket(ServerOP_TaskReject, leader_name.size() + 1 + 8);
|
||||||
pack->WriteUInt32(0); // string ID or just generic fail message
|
pack->WriteUInt32(0); // string ID or just generic fail message
|
||||||
@ -146,7 +146,7 @@ void SharedTaskManager::HandleTaskRequest(ServerPacket *pack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we're good, add to task
|
// we're good, add to task
|
||||||
task.AddMember(name, cle);
|
task.AddMember(name, cle, cle->CharID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ bool SharedTaskManager::LoadSharedTaskState()
|
|||||||
{
|
{
|
||||||
// one may think we should clean up expired tasks, but we don't just in case world is booting back up after a crash
|
// one may think we should clean up expired tasks, but we don't just in case world is booting back up after a crash
|
||||||
// we will clean them up in the normal process loop so zones get told to clean up
|
// we will clean them up in the normal process loop so zones get told to clean up
|
||||||
std::string query = "SELECT `id`, `taskid`, `acceptedtime`, `locked` FROM `shared_task_state`";
|
std::string query = "SELECT `id`, `task_id`, `accepted_time`, `is_locked` FROM `shared_task_state`";
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
@ -389,14 +389,14 @@ bool SharedTaskManager::LoadSharedTaskState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query = "SELECT `shared_id`, `charid`, `name`, `leader` FROM `shared_task_members` ORDER BY shared_id ASC";
|
query = "SELECT `shared_task_id`, `character_id`, `character_name`, `is_leader` FROM `shared_task_members` ORDER BY shared_task_id ASC";
|
||||||
results = database.QueryDatabase(query);
|
results = database.QueryDatabase(query);
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
int task_id = atoi(row[0]);
|
int task_id = atoi(row[0]);
|
||||||
// hmm not sure best way to do this, fine for now
|
// hmm not sure best way to do this, fine for now
|
||||||
if (tasks.count(task_id) == 1)
|
if (tasks.count(task_id) == 1)
|
||||||
tasks[task_id].AddMember(row[2], nullptr, atoi(row[3]) != 0);
|
tasks[task_id].AddMember(row[2], nullptr, atoi(row[1]), atoi(row[3]) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ bool SharedTaskManager::LoadSharedTaskState()
|
|||||||
// But the crash case may actually dictate we should :P
|
// But the crash case may actually dictate we should :P
|
||||||
|
|
||||||
// set next_id to highest used ID
|
// set next_id to highest used ID
|
||||||
query = "SELECT MAX(id) FROM shared_task_state";
|
query = "SELECT IFNULL(MAX(id), 0) FROM shared_task_state";
|
||||||
results = database.QueryDatabase(query);
|
results = database.QueryDatabase(query);
|
||||||
if (results.Success() && results.RowCount() == 1) {
|
if (results.Success() && results.RowCount() == 1) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|||||||
@ -6,16 +6,21 @@
|
|||||||
|
|
||||||
#include "../common/servertalk.h"
|
#include "../common/servertalk.h"
|
||||||
#include "../common/global_tasks.h"
|
#include "../common/global_tasks.h"
|
||||||
|
#include "cliententry.h"
|
||||||
|
|
||||||
class ClientListEntry;
|
class ClientListEntry;
|
||||||
|
|
||||||
struct SharedTaskMember {
|
struct SharedTaskMember {
|
||||||
std::string name;
|
std::string name;
|
||||||
ClientListEntry *cle;
|
ClientListEntry *cle;
|
||||||
|
int char_id;
|
||||||
bool leader;
|
bool leader;
|
||||||
// TODO: monster mission stuff
|
// TODO: monster mission stuff
|
||||||
SharedTaskMember() : cle(nullptr), leader(false) {}
|
SharedTaskMember() : cle(nullptr), char_id(0), leader(false) {}
|
||||||
SharedTaskMember(std::string name, ClientListEntry *cle, bool leader) : name(name), cle(cle), leader(leader) {}
|
SharedTaskMember(std::string name, ClientListEntry *cle, int char_id, bool leader)
|
||||||
|
: name(name), cle(cle), char_id(char_id), leader(leader)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedTask {
|
class SharedTask {
|
||||||
@ -24,11 +29,16 @@ public:
|
|||||||
SharedTask(int id, int task_id) : id(id), task_id(task_id), locked(false) {}
|
SharedTask(int id, int task_id) : id(id), task_id(task_id), locked(false) {}
|
||||||
~SharedTask() {}
|
~SharedTask() {}
|
||||||
|
|
||||||
void AddMember(std::string name, ClientListEntry *cle = nullptr, bool leader = false)
|
void AddMember(std::string name, ClientListEntry *cle = nullptr, int char_id = 0, bool leader = false)
|
||||||
{
|
{
|
||||||
members.push_back({name, cle, leader});
|
members.push_back({name, cle, char_id, leader});
|
||||||
if (leader)
|
if (leader)
|
||||||
leader_name = name;
|
leader_name = name;
|
||||||
|
if (char_id == 0)
|
||||||
|
return;
|
||||||
|
auto it = std::find(char_ids.begin(), char_ids.end(), char_id);
|
||||||
|
if (it == char_ids.end())
|
||||||
|
char_ids.push_back(char_id);
|
||||||
}
|
}
|
||||||
void MemberLeftGame(ClientListEntry *cle);
|
void MemberLeftGame(ClientListEntry *cle);
|
||||||
inline const std::string &GetLeaderName() const { return leader_name; }
|
inline const std::string &GetLeaderName() const { return leader_name; }
|
||||||
@ -59,6 +69,7 @@ private:
|
|||||||
bool locked;
|
bool locked;
|
||||||
std::string leader_name;
|
std::string leader_name;
|
||||||
std::vector<SharedTaskMember> members;
|
std::vector<SharedTaskMember> members;
|
||||||
|
std::vector<int> char_ids; // every char id of someone to be locked out, different in case they leave/removed
|
||||||
ClientTaskInformation task_state; // book keeping
|
ClientTaskInformation task_state; // book keeping
|
||||||
|
|
||||||
friend class SharedTaskManager;
|
friend class SharedTaskManager;
|
||||||
|
|||||||
@ -1877,6 +1877,10 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk
|
|||||||
if (r)
|
if (r)
|
||||||
r->MemberZoned(this);
|
r->MemberZoned(this);
|
||||||
|
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
|
|
||||||
dead_timer.Start(5000, true);
|
dead_timer.Start(5000, true);
|
||||||
m_pp.zone_id = m_pp.binds[0].zoneId;
|
m_pp.zone_id = m_pp.binds[0].zoneId;
|
||||||
m_pp.zoneInstance = m_pp.binds[0].instance_id;
|
m_pp.zoneInstance = m_pp.binds[0].instance_id;
|
||||||
|
|||||||
@ -439,6 +439,7 @@ NPCType *Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::st
|
|||||||
bot_npc_type->skip_global_loot = true;
|
bot_npc_type->skip_global_loot = true;
|
||||||
//bot_npc_type->rare_spawn = false;
|
//bot_npc_type->rare_spawn = false;
|
||||||
bot_npc_type->stuck_behavior = Ground;
|
bot_npc_type->stuck_behavior = Ground;
|
||||||
|
bot_npc_type->skip_auto_scale = true;
|
||||||
|
|
||||||
return bot_npc_type;
|
return bot_npc_type;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3396,6 +3396,11 @@ void Client::LinkDead()
|
|||||||
if(raid){
|
if(raid){
|
||||||
raid->MemberZoned(this);
|
raid->MemberZoned(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
|
|
||||||
// save_timer.Start(2500);
|
// save_timer.Start(2500);
|
||||||
linkdead_timer.Start(RuleI(Zone,ClientLinkdeadMS));
|
linkdead_timer.Start(RuleI(Zone,ClientLinkdeadMS));
|
||||||
SendAppearancePacket(AT_Linkdead, 1);
|
SendAppearancePacket(AT_Linkdead, 1);
|
||||||
|
|||||||
@ -791,7 +791,9 @@ public:
|
|||||||
uint32 GetCharMaxLevelFromQGlobal();
|
uint32 GetCharMaxLevelFromQGlobal();
|
||||||
uint32 GetCharMaxLevelFromBucket();
|
uint32 GetCharMaxLevelFromBucket();
|
||||||
|
|
||||||
|
inline bool IsStanding() const {return (playeraction == 0);}
|
||||||
inline bool IsSitting() const {return (playeraction == 1);}
|
inline bool IsSitting() const {return (playeraction == 1);}
|
||||||
|
inline bool IsCrouching() const {return (playeraction == 2);}
|
||||||
inline bool IsBecomeNPC() const { return npcflag; }
|
inline bool IsBecomeNPC() const { return npcflag; }
|
||||||
inline uint8 GetBecomeNPCLevel() const { return npclevel; }
|
inline uint8 GetBecomeNPCLevel() const { return npclevel; }
|
||||||
inline void SetBecomeNPC(bool flag) { npcflag = flag; }
|
inline void SetBecomeNPC(bool flag) { npcflag = flag; }
|
||||||
@ -1027,6 +1029,7 @@ public:
|
|||||||
inline void ProcessTaskProximities(float X, float Y, float Z) { if(taskstate) taskstate->ProcessTaskProximities(this, X, Y, Z); }
|
inline void ProcessTaskProximities(float X, float Y, float Z) { if(taskstate) taskstate->ProcessTaskProximities(this, X, Y, Z); }
|
||||||
inline void AssignTask(int TaskID, int NPCID, bool enforce_level_requirement = false) { if (taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID, enforce_level_requirement); }
|
inline void AssignTask(int TaskID, int NPCID, bool enforce_level_requirement = false) { if (taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID, enforce_level_requirement); }
|
||||||
inline void AssignSharedTask(int TaskID, int NPCID, int id, int accepted_time, std::vector<std::string> &members) { if (taskstate) taskstate->AcceptNewSharedTask(this, TaskID, NPCID, id, accepted_time, members); }
|
inline void AssignSharedTask(int TaskID, int NPCID, int id, int accepted_time, std::vector<std::string> &members) { if (taskstate) taskstate->AcceptNewSharedTask(this, TaskID, NPCID, id, accepted_time, members); }
|
||||||
|
inline void AddToSharedTask(int TaskID) { if (taskstate) taskstate->AddToSharedTask(this, TaskID); }
|
||||||
inline int ActiveSpeakTask(int NPCID) { if(taskstate) return taskstate->ActiveSpeakTask(NPCID); else return 0; }
|
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 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); }
|
inline void FailTask(int TaskID) { if(taskstate) taskstate->FailTask(this, TaskID); }
|
||||||
@ -1045,6 +1048,7 @@ public:
|
|||||||
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
|
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
|
||||||
inline int GetTaskLockoutExpire(int id) { return 0; } // stub
|
inline int GetTaskLockoutExpire(int id) { return 0; } // stub
|
||||||
inline int GetTaskLockoutTimeLeft(int id) { return 0; } // stub
|
inline int GetTaskLockoutTimeLeft(int id) { return 0; } // stub
|
||||||
|
inline SharedTaskState *GetSharedTask() { return taskstate ? taskstate->GetSharedTask() : nullptr; }
|
||||||
|
|
||||||
inline const EQEmu::versions::ClientVersion ClientVersion() const { return m_ClientVersion; }
|
inline const EQEmu::versions::ClientVersion ClientVersion() const { return m_ClientVersion; }
|
||||||
inline const uint32 ClientVersionBit() const { return m_ClientVersionBit; }
|
inline const uint32 ClientVersionBit() const { return m_ClientVersionBit; }
|
||||||
|
|||||||
@ -1799,7 +1799,7 @@ void Client::Handle_OP_AcceptNewSharedTask(const EQApplicationPacket *app)
|
|||||||
auto *ant = (AcceptNewSharedTask_Struct*)app->pBuffer;
|
auto *ant = (AcceptNewSharedTask_Struct*)app->pBuffer;
|
||||||
|
|
||||||
if (ant->task_id > 0 && RuleB(TaskSystem, EnableTaskSystem) && taskstate)
|
if (ant->task_id > 0 && RuleB(TaskSystem, EnableTaskSystem) && taskstate)
|
||||||
taskstate->PendSharedTask(this, ant->task_id, ant->task_master_id);
|
taskstate->RequestSharedTask(this, ant->task_id, ant->task_master_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app)
|
void Client::Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app)
|
||||||
|
|||||||
@ -149,6 +149,9 @@ bool Client::Process() {
|
|||||||
{
|
{
|
||||||
myraid->MemberZoned(this);
|
myraid->MemberZoned(this);
|
||||||
}
|
}
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +174,9 @@ bool Client::Process() {
|
|||||||
if (myraid) {
|
if (myraid) {
|
||||||
myraid->MemberZoned(this);
|
myraid->MemberZoned(this);
|
||||||
}
|
}
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
return false; //delete client
|
return false; //delete client
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +659,9 @@ bool Client::Process() {
|
|||||||
myraid->MemberZoned(this);
|
myraid->MemberZoned(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
OnDisconnect(false);
|
OnDisconnect(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -694,6 +703,10 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
|||||||
if (MyRaid)
|
if (MyRaid)
|
||||||
MyRaid->MemberZoned(this);
|
MyRaid->MemberZoned(this);
|
||||||
|
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||||
|
|
||||||
/* QS: PlayerLogConnectDisconnect */
|
/* QS: PlayerLogConnectDisconnect */
|
||||||
@ -2101,6 +2114,10 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
|||||||
if(r)
|
if(r)
|
||||||
r->MemberZoned(this);
|
r->MemberZoned(this);
|
||||||
|
|
||||||
|
auto shared_task = GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(this);
|
||||||
|
|
||||||
m_pp.zone_id = chosen->zone_id;
|
m_pp.zone_id = chosen->zone_id;
|
||||||
m_pp.zoneInstance = chosen->instance_id;
|
m_pp.zoneInstance = chosen->instance_id;
|
||||||
database.MoveCharacterToZone(CharacterID(), database.GetZoneName(chosen->zone_id));
|
database.MoveCharacterToZone(CharacterID(), database.GetZoneName(chosen->zone_id));
|
||||||
|
|||||||
@ -537,6 +537,9 @@ void EntityList::MobProcess()
|
|||||||
Log(Logs::General, Logs::Error, "About to delete a client still in a raid.");
|
Log(Logs::General, Logs::Error, "About to delete a client still in a raid.");
|
||||||
r->MemberZoned(mob->CastToClient());
|
r->MemberZoned(mob->CastToClient());
|
||||||
}
|
}
|
||||||
|
auto shared_task = mob->CastToClient()->GetSharedTask();
|
||||||
|
if (shared_task)
|
||||||
|
shared_task->MemberZoned(mob);
|
||||||
entity_list.RemoveClient(id);
|
entity_list.RemoveClient(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -972,8 +972,8 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||||
MoveItem_Struct* delitem = (MoveItem_Struct*)outapp->pBuffer;
|
DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer;
|
||||||
delitem->from_slot = slot_id;
|
delitem->from_slot = slot_id;
|
||||||
delitem->to_slot = 0xFFFFFFFF;
|
delitem->to_slot = 0xFFFFFFFF;
|
||||||
delitem->number_in_stack = 0xFFFFFFFF;
|
delitem->number_in_stack = 0xFFFFFFFF;
|
||||||
|
|||||||
@ -615,11 +615,21 @@ void Lua_Client::UntrainDiscAll(bool update_client) {
|
|||||||
self->UntrainDiscAll(update_client);
|
self->UntrainDiscAll(update_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_Client::IsStanding() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsStanding();
|
||||||
|
}
|
||||||
|
|
||||||
bool Lua_Client::IsSitting() {
|
bool Lua_Client::IsSitting() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->IsSitting();
|
return self->IsSitting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_Client::IsCrouching() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsCrouching();
|
||||||
|
}
|
||||||
|
|
||||||
void Lua_Client::SetFeigned(bool v) {
|
void Lua_Client::SetFeigned(bool v) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->SetFeigned(v);
|
self->SetFeigned(v);
|
||||||
@ -1621,7 +1631,9 @@ luabind::scope lua_register_client() {
|
|||||||
.def("UntrainDisc", (void(Lua_Client::*)(int,bool))&Lua_Client::UntrainDisc)
|
.def("UntrainDisc", (void(Lua_Client::*)(int,bool))&Lua_Client::UntrainDisc)
|
||||||
.def("UntrainDiscAll", (void(Lua_Client::*)(void))&Lua_Client::UntrainDiscAll)
|
.def("UntrainDiscAll", (void(Lua_Client::*)(void))&Lua_Client::UntrainDiscAll)
|
||||||
.def("UntrainDiscAll", (void(Lua_Client::*)(bool))&Lua_Client::UntrainDiscAll)
|
.def("UntrainDiscAll", (void(Lua_Client::*)(bool))&Lua_Client::UntrainDiscAll)
|
||||||
|
.def("IsStanding", (bool(Lua_Client::*)(void))&Lua_Client::IsStanding)
|
||||||
.def("IsSitting", (bool(Lua_Client::*)(void))&Lua_Client::IsSitting)
|
.def("IsSitting", (bool(Lua_Client::*)(void))&Lua_Client::IsSitting)
|
||||||
|
.def("IsCrouching", (bool(Lua_Client::*)(void))&Lua_Client::IsCrouching)
|
||||||
.def("SetFeigned", (void(Lua_Client::*)(bool))&Lua_Client::SetFeigned)
|
.def("SetFeigned", (void(Lua_Client::*)(bool))&Lua_Client::SetFeigned)
|
||||||
.def("GetFeigned", (bool(Lua_Client::*)(void))&Lua_Client::GetFeigned)
|
.def("GetFeigned", (bool(Lua_Client::*)(void))&Lua_Client::GetFeigned)
|
||||||
.def("AutoSplitEnabled", (bool(Lua_Client::*)(void))&Lua_Client::AutoSplitEnabled)
|
.def("AutoSplitEnabled", (bool(Lua_Client::*)(void))&Lua_Client::AutoSplitEnabled)
|
||||||
|
|||||||
@ -148,7 +148,9 @@ public:
|
|||||||
void UntrainDisc(int slot, bool update_client);
|
void UntrainDisc(int slot, bool update_client);
|
||||||
void UntrainDiscAll();
|
void UntrainDiscAll();
|
||||||
void UntrainDiscAll(bool update_client);
|
void UntrainDiscAll(bool update_client);
|
||||||
|
bool IsStanding();
|
||||||
bool IsSitting();
|
bool IsSitting();
|
||||||
|
bool IsCrouching();
|
||||||
void SetFeigned(bool v);
|
void SetFeigned(bool v);
|
||||||
bool GetFeigned();
|
bool GetFeigned();
|
||||||
bool AutoSplitEnabled();
|
bool AutoSplitEnabled();
|
||||||
|
|||||||
@ -239,6 +239,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
p_depop = false;
|
p_depop = false;
|
||||||
loottable_id = npc_type_data->loottable_id;
|
loottable_id = npc_type_data->loottable_id;
|
||||||
skip_global_loot = npc_type_data->skip_global_loot;
|
skip_global_loot = npc_type_data->skip_global_loot;
|
||||||
|
skip_auto_scale = npc_type_data->skip_auto_scale;
|
||||||
rare_spawn = npc_type_data->rare_spawn;
|
rare_spawn = npc_type_data->rare_spawn;
|
||||||
no_target_hotkey = npc_type_data->no_target_hotkey;
|
no_target_hotkey = npc_type_data->no_target_hotkey;
|
||||||
primary_faction = 0;
|
primary_faction = 0;
|
||||||
|
|||||||
@ -468,6 +468,7 @@ public:
|
|||||||
|
|
||||||
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
|
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
|
||||||
|
|
||||||
|
inline bool IsSkipAutoScale() const { return skip_auto_scale; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -612,6 +613,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
uint32 loottable_id;
|
uint32 loottable_id;
|
||||||
bool skip_global_loot;
|
bool skip_global_loot;
|
||||||
|
bool skip_auto_scale;
|
||||||
bool p_depop;
|
bool p_depop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
void NpcScaleManager::ScaleNPC(NPC * npc)
|
void NpcScaleManager::ScaleNPC(NPC * npc)
|
||||||
{
|
{
|
||||||
|
if (npc->IsSkipAutoScale())
|
||||||
|
return;
|
||||||
|
|
||||||
int8 npc_type = GetNPCScalingType(npc);
|
int8 npc_type = GetNPCScalingType(npc);
|
||||||
int npc_level = npc->GetLevel();
|
int npc_level = npc->GetLevel();
|
||||||
bool is_auto_scaled = IsAutoScaled(npc);
|
bool is_auto_scaled = IsAutoScaled(npc);
|
||||||
|
|||||||
@ -2596,6 +2596,32 @@ XS(XS_Client_UntrainDiscAll) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Client_IsStanding); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Client_IsStanding)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Client::IsStanding(THIS)");
|
||||||
|
{
|
||||||
|
Client * THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Client")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Client *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsStanding();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Client_IsSitting); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Client_IsSitting); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Client_IsSitting) {
|
XS(XS_Client_IsSitting) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -2620,6 +2646,32 @@ XS(XS_Client_IsSitting) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Client_IsCrouching); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Client_IsCrouching)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Client::IsCrouching(THIS)");
|
||||||
|
{
|
||||||
|
Client * THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Client")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Client *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsCrouching();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Client_IsBecomeNPC); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Client_IsBecomeNPC); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Client_IsBecomeNPC) {
|
XS(XS_Client_IsBecomeNPC) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -6338,7 +6390,9 @@ XS(boot_Client) {
|
|||||||
newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$");
|
newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$");
|
newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$");
|
newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsStanding"), XS_Client_IsStanding, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$");
|
newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsCrouching"), XS_Client_IsCrouching, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$");
|
newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$");
|
||||||
newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$");
|
newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$");
|
||||||
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
|
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
|
||||||
|
|||||||
@ -3084,6 +3084,21 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, ClientTaskInf
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: stub
|
||||||
|
SharedTaskState *TaskManager::LoadSharedTask(int id)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedTaskState *TaskManager::GetSharedTask(int id)
|
||||||
|
{
|
||||||
|
auto it = SharedTasks.find(id);
|
||||||
|
if (it == SharedTasks.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
bool ClientTaskState::IsTaskActivityCompleted(TaskType type, int index, int ActivityID)
|
bool ClientTaskState::IsTaskActivityCompleted(TaskType type, int index, int ActivityID)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -3387,10 +3402,13 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor
|
|||||||
parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0);
|
parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function will do a bunch of verification, then set up a pending state which will then send a request
|
/*
|
||||||
// to world and send off requests to out of group zones to ask if they can join the task
|
* This function is a proxy for OP_AccetNewSharedTask since it has to fire to
|
||||||
// Once the we get all of the replies that pass, we will then assign the task
|
* world. We do a handful of checks on the leader, then build a packet with a
|
||||||
void ClientTaskState::PendSharedTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement)
|
* list of all the members in our group/raid if applicable. The verification for
|
||||||
|
* the other members is done in world.
|
||||||
|
*/
|
||||||
|
void ClientTaskState::RequestSharedTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement)
|
||||||
{
|
{
|
||||||
if (!taskmanager || TaskID < 0 || TaskID >= MAXTASKS) {
|
if (!taskmanager || TaskID < 0 || TaskID >= MAXTASKS) {
|
||||||
c->Message(13, "Task system not functioning, or TaskID %i out of range.", TaskID);
|
c->Message(13, "Task system not functioning, or TaskID %i out of range.", TaskID);
|
||||||
@ -3550,11 +3568,47 @@ void ClientTaskState::AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int
|
|||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
|
|
||||||
|
ActiveSharedTask = task_state;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// there are a few issues we need to solve with this
|
// there are a few issues we need to solve with this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called when world sends ServerOP_TaskZoneCreated to trigger
|
||||||
|
* members to join. If the task doesn't already exist, we need to load it from
|
||||||
|
* the DB.
|
||||||
|
*
|
||||||
|
* This is also called in LoadClientTaskState() when they notice they have a
|
||||||
|
* shared task they need to join. (Called from first OP_ZoneEntry)
|
||||||
|
*/
|
||||||
|
void ClientTaskState::AddToSharedTask(Client *c, int TaskID)
|
||||||
|
{
|
||||||
|
auto task = taskmanager->GetSharedTask(TaskID);
|
||||||
|
if (!task)
|
||||||
|
task = taskmanager->LoadSharedTask(TaskID);
|
||||||
|
|
||||||
|
if (!task) {// FUCK
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
task->MemberEnterZone(c);
|
||||||
|
|
||||||
|
// send packets
|
||||||
|
auto task_activity = task->GetActivity();
|
||||||
|
taskmanager->SendSingleActiveTaskToClient(c, *task_activity, false, true);
|
||||||
|
task->SendMembersList(c);
|
||||||
|
|
||||||
|
// So normally getting a task we would send EVENT_TASK_ACCEPTED here, but
|
||||||
|
// this isn't an accept step. I guess we should add another event in case
|
||||||
|
// they need the same thing TODO
|
||||||
|
|
||||||
|
ActiveSharedTask = task;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) {
|
void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) {
|
||||||
|
|
||||||
float LastX = c->ProximityX();
|
float LastX = c->ProximityX();
|
||||||
@ -3780,7 +3834,7 @@ void SharedTaskState::LockTask()
|
|||||||
void SharedTaskState::MemberZoned(Mob *player)
|
void SharedTaskState::MemberZoned(Mob *player)
|
||||||
{
|
{
|
||||||
auto it = std::find_if(members.begin(), members.end(),
|
auto it = std::find_if(members.begin(), members.end(),
|
||||||
[&player](const SharedTaskMember &a) { return a.name == player->GetName(); });
|
[&player](const SharedTaskMember &a) { return a.entity == player; });
|
||||||
|
|
||||||
if (it == members.end()) // guess they weren't in this group, w/e
|
if (it == members.end()) // guess they weren't in this group, w/e
|
||||||
return;
|
return;
|
||||||
|
|||||||
11
zone/tasks.h
11
zone/tasks.h
@ -146,8 +146,6 @@ public:
|
|||||||
int GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID);
|
int GetTaskActivityDoneCountFromTaskID(int TaskID, int ActivityID);
|
||||||
int GetTaskStartTime(TaskType type, int index);
|
int GetTaskStartTime(TaskType type, int index);
|
||||||
void AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
void AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
||||||
void AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int id, int accepted_time, std::vector<std::string> &members);
|
|
||||||
void PendSharedTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
|
||||||
void FailTask(Client *c, int TaskID);
|
void FailTask(Client *c, int TaskID);
|
||||||
int TaskTimeLeft(int TaskID);
|
int TaskTimeLeft(int TaskID);
|
||||||
int IsTaskCompleted(int TaskID);
|
int IsTaskCompleted(int TaskID);
|
||||||
@ -180,9 +178,15 @@ public:
|
|||||||
int ActiveTasksInSet(int TaskSetID);
|
int ActiveTasksInSet(int TaskSetID);
|
||||||
int CompletedTasksInSet(int TaskSetID);
|
int CompletedTasksInSet(int TaskSetID);
|
||||||
bool HasSlotForTask(TaskInformation *task);
|
bool HasSlotForTask(TaskInformation *task);
|
||||||
|
// shared task related functions
|
||||||
|
void AcceptNewSharedTask(Client *c, int TaskID, int NPCID, int id, int accepted_time, std::vector<std::string> &members);
|
||||||
|
void AddToSharedTask(Client *c, int TaskID);
|
||||||
|
void RequestSharedTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement = false);
|
||||||
|
|
||||||
inline bool HasFreeTaskSlot() { return ActiveTask.TaskID == TASKSLOTEMPTY; }
|
inline bool HasFreeTaskSlot() { return ActiveTask.TaskID == TASKSLOTEMPTY; }
|
||||||
|
|
||||||
|
inline SharedTaskState *GetSharedTask() { return ActiveSharedTask ; }
|
||||||
|
|
||||||
friend class TaskManager;
|
friend class TaskManager;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -266,8 +270,9 @@ public:
|
|||||||
bool IsTaskRepeatable(int TaskID);
|
bool IsTaskRepeatable(int TaskID);
|
||||||
friend class ClientTaskState;
|
friend class ClientTaskState;
|
||||||
|
|
||||||
void LoadSharedTask(int id); // loads the shared task state
|
SharedTaskState *LoadSharedTask(int id); // loads the shared task state
|
||||||
SharedTaskState *CreateSharedTask(int id, int task_id);
|
SharedTaskState *CreateSharedTask(int id, int task_id);
|
||||||
|
SharedTaskState *GetSharedTask(int id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TaskGoalListManager GoalListManager;
|
TaskGoalListManager GoalListManager;
|
||||||
|
|||||||
@ -1991,6 +1991,17 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_TaskZoneCreated:
|
||||||
|
{
|
||||||
|
int task_id = pack->ReadUInt32();
|
||||||
|
char name[64] = { 0 };
|
||||||
|
pack->ReadString(name);
|
||||||
|
|
||||||
|
auto client = entity_list.GetClientByName(name);
|
||||||
|
if (client)
|
||||||
|
client->AddToSharedTask(task_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
std::cout << " Unknown ZSopcode:" << (int)pack->opcode;
|
std::cout << " Unknown ZSopcode:" << (int)pack->opcode;
|
||||||
std::cout << " size:" << pack->size << std::endl;
|
std::cout << " size:" << pack->size << std::endl;
|
||||||
|
|||||||
@ -2675,6 +2675,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
||||||
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
||||||
temp_npctype_data->use_model = atoi(row[110]);
|
temp_npctype_data->use_model = atoi(row[110]);
|
||||||
|
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
|
||||||
|
|
||||||
// If NPC with duplicate NPC id already in table,
|
// If NPC with duplicate NPC id already in table,
|
||||||
// free item we attempted to add.
|
// free item we attempted to add.
|
||||||
@ -2877,6 +2878,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
|
|||||||
tmpNPCType->scalerate = atoi(row[43]);
|
tmpNPCType->scalerate = atoi(row[43]);
|
||||||
tmpNPCType->spellscale = atoi(row[44]);
|
tmpNPCType->spellscale = atoi(row[44]);
|
||||||
tmpNPCType->healscale = atoi(row[45]);
|
tmpNPCType->healscale = atoi(row[45]);
|
||||||
|
tmpNPCType->skip_global_loot = true;
|
||||||
|
tmpNPCType->skip_auto_scale = true;
|
||||||
|
|
||||||
// If Merc with duplicate NPC id already in table,
|
// If Merc with duplicate NPC id already in table,
|
||||||
// free item we attempted to add.
|
// free item we attempted to add.
|
||||||
|
|||||||
@ -143,6 +143,7 @@ struct NPCType
|
|||||||
bool untargetable;
|
bool untargetable;
|
||||||
bool skip_global_loot;
|
bool skip_global_loot;
|
||||||
bool rare_spawn;
|
bool rare_spawn;
|
||||||
|
bool skip_auto_scale; // just so it doesn't mess up bots or mercs, probably should add to DB too just in case
|
||||||
int8 stuck_behavior;
|
int8 stuck_behavior;
|
||||||
uint16 use_model;
|
uint16 use_model;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user