-Merc upkeep timers fixed to display properly. They now persist through zones as well as save to the database properly.

-Merc unsuspend timers should now be more reliable across zone shutdown.
This commit is contained in:
SecretsOTheP 2013-03-23 04:58:03 -04:00
parent ac040b5197
commit abaad22eb4
6 changed files with 31 additions and 33 deletions

View File

@ -3015,7 +3015,7 @@ ENCODE(OP_ReadBook) {
eq->window = emu->window; eq->window = emu->window;
OUT(type); OUT(type);
eq->invslot = 0; // Set to hard 0 since it's not required for the structure to work eq->invslot = 0; // Set to hard 0 since it's not required for the structure to work
memcpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile)); strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE(); FINISH_ENCODE();
} }

View File

@ -232,6 +232,7 @@ Client::Client(EQStreamInterface* ieqs)
dead_timer.Disable(); dead_timer.Disable();
camp_timer.Disable(); camp_timer.Disable();
autosave_timer.Disable(); autosave_timer.Disable();
GetMercTimer()->Disable();
instalog = false; instalog = false;
pLastUpdate = 0; pLastUpdate = 0;
pLastUpdateWZ = 0; pLastUpdateWZ = 0;
@ -562,8 +563,8 @@ bool Client::Save(uint8 iCommitNow) {
if(GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS)) if(GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS))
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS); GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
if(merc_timer.Enabled()) { if(GetMercTimer()->Enabled()) {
GetMercInfo().MercTimerRemaining = merc_timer.GetRemainingTime(); GetMercInfo().MercTimerRemaining = GetMercTimer()->GetRemainingTime();
} }
if (GetMerc() && !dead) { if (GetMerc() && !dead) {

View File

@ -1124,7 +1124,7 @@ public:
void UpdateMercTimer(); void UpdateMercTimer();
void UpdateMercLevel(); void UpdateMercLevel();
void CheckMercSuspendTimer(); void CheckMercSuspendTimer();
Timer GetMercTimer() { return merc_timer; }; Timer* GetMercTimer() { return &merc_timer; };
const char* GetRacePlural(Client* client); const char* GetRacePlural(Client* client);
const char* GetClassPlural(Client* client); const char* GetClassPlural(Client* client);
void SendWebLink(const char* website); void SendWebLink(const char* website);

View File

@ -13814,7 +13814,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app)
} }
if(entityID > 0) { if(entityID > 0) {
SendMercTimerPacket(entityID, mercState, suspendedTime, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); SendMercTimerPacket(entityID, mercState, suspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
} }
} }

View File

@ -249,7 +249,7 @@ bool Client::Process() {
UpdateMercTimer(); UpdateMercTimer();
} }
if(GetMercInfo().MercTemplateID != 0) if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended)
{ {
if(p_timers.Expired(&database, pTimerMercSuspend, false)) { if(p_timers.Expired(&database, pTimerMercSuspend, false)) {
CheckMercSuspendTimer(); CheckMercSuspendTimer();

View File

@ -5310,7 +5310,7 @@ void Client::UpdateMercTimer()
if(merc && !merc->IsSuspended()) if(merc && !merc->IsSuspended())
{ {
if(merc_timer.Check()) if(GetMercTimer()->Check())
{ {
uint32 upkeep = Merc::CalcUpkeepCost(merc->GetMercTemplateID(), GetLevel()); uint32 upkeep = Merc::CalcUpkeepCost(merc->GetMercTemplateID(), GetLevel());
@ -5325,8 +5325,9 @@ void Client::UpdateMercTimer()
} }
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS); GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
SendMercTimerPacket(GetMercID(), 5, 0, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); SendMercTimerPacket(GetMercID(), 5, 0, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
merc_timer.Start(RuleI(Mercs, UpkeepIntervalMS)); GetMercTimer()->Start(RuleI(Mercs, UpkeepIntervalMS));
GetMercTimer()->SetTimer(GetMercInfo().MercTimerRemaining);
// Send upkeep charge message and reset the upkeep timer // Send upkeep charge message and reset the upkeep timer
if (GetClientVersion() < EQClientRoF) if (GetClientVersion() < EQClientRoF)
@ -5507,6 +5508,12 @@ bool Client::CheckCanUnsuspendMerc() {
return false; return false;
} }
if(!GetPTimers().Expired(&database, pTimerMercSuspend, false))
{
SendMercMerchantResponsePacket(16);
Message(0, "You must wait %i seconds before unsuspending your mercenary.", GetPTimers().GetRemainingTime(pTimerMercSuspend)); //todo: find this packet response and tell them properly.
return false;
}
return true; return true;
} }
@ -5528,9 +5535,7 @@ void Client::CheckMercSuspendTimer()
{ {
if(GetMercInfo().SuspendedTime != 0) { if(GetMercInfo().SuspendedTime != 0) {
if(time(NULL) >= GetMercInfo().SuspendedTime){ if(time(NULL) >= GetMercInfo().SuspendedTime){
GetMercInfo().SuspendedTime = 0; SendMercSuspendResponsePacket(0);
SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime);
p_timers.Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS));
} }
} }
} }
@ -5596,12 +5601,13 @@ void Client::SpawnMercOnZone()
if(database.LoadMercInfo(this)) { if(database.LoadMercInfo(this)) {
Merc* merc = Merc::LoadMerc(this, &zone->merc_templates[GetMercInfo().MercTemplateID], 0, true); Merc* merc = Merc::LoadMerc(this, &zone->merc_templates[GetMercInfo().MercTemplateID], 0, true);
SpawnMerc(merc, false); SpawnMerc(merc, false);
SendMercTimerPacket(merc->GetID(), 5, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
} }
} }
else else
{ {
// Send Mercenary Status/Timer packet // Send Mercenary Status/Timer packet
SendMercTimerPacket(0, 1, GetMercInfo().SuspendedTime, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); SendMercTimerPacket(0, 1, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
SendMercPersonalInfo(); SendMercPersonalInfo();
@ -5640,19 +5646,19 @@ bool Merc::Suspend() {
/*if(HasGroup()) { /*if(HasGroup()) {
RemoveMercFromGroup(this, GetGroup()); RemoveMercFromGroup(this, GetGroup());
}*/ }*/
Save();
mercOwner->GetMercInfo().IsSuspended = true; mercOwner->GetMercInfo().IsSuspended = true;
mercOwner->GetMercInfo().SuspendedTime = time(NULL) + RuleI(Mercs, SuspendIntervalS); mercOwner->GetMercInfo().SuspendedTime = time(NULL) + RuleI(Mercs, SuspendIntervalS);
mercOwner->GetMercInfo().MercTimerRemaining = mercOwner->GetMercTimer().GetRemainingTime(); mercOwner->GetMercInfo().MercTimerRemaining = mercOwner->GetMercTimer()->GetRemainingTime();
mercOwner->GetMercInfo().Stance = GetStance(); mercOwner->GetMercInfo().Stance = GetStance();
mercOwner->GetMercTimer().Disable(); Save();
mercOwner->GetMercTimer()->Disable();
//mercOwner->UpdateMercTimer(); //mercOwner->UpdateMercTimer();
mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime); mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime);
Depop(); Depop();
mercOwner->SendMercTimerPacket(0, 1, mercOwner->GetMercInfo().SuspendedTime, mercOwner->GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
return true; return true;
} }
@ -5675,15 +5681,13 @@ bool Merc::Unsuspend(bool setMaxStats) {
mercOwner->GetMercInfo().mercid = GetMercID(); mercOwner->GetMercInfo().mercid = GetMercID();
mercOwner->GetMercInfo().IsSuspended = false; mercOwner->GetMercInfo().IsSuspended = false;
mercOwner->GetMercInfo().SuspendedTime = 0;
mercOwner->SendMercenaryUnsuspendPacket(0); mercOwner->SendMercenaryUnsuspendPacket(0);
mercOwner->SendMercenaryUnknownPacket(1); mercOwner->SendMercenaryUnknownPacket(1);
mercOwner->GetMercInfo().SuspendedTime = 0;
mercOwner->SendMercTimerPacket(GetID(), mercState, suspendedTime, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); mercOwner->GetMercTimer()->Start(RuleI(Mercs, UpkeepIntervalMS));
mercOwner->GetMercTimer()->SetTimer(mercOwner->GetMercInfo().MercTimerRemaining);
mercOwner->GetMercTimer().Start(mercOwner->GetMercInfo().MercTimerRemaining); mercOwner->SendMercTimerPacket(GetID(), mercState, suspendedTime, mercOwner->GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS));
if(!mercOwner->GetPTimers().Expired(&database, pTimerMercSuspend, false)) if(!mercOwner->GetPTimers().Expired(&database, pTimerMercSuspend, false))
mercOwner->GetPTimers().Clear(&database, pTimerMercSuspend); mercOwner->GetPTimers().Clear(&database, pTimerMercSuspend);
@ -5756,7 +5760,6 @@ bool Merc::Dismiss(){
return false; return false;
mercOwner->SendClearMercInfo(); mercOwner->SendClearMercInfo();
mercOwner->SendMercTimerPacket(GetID(), 5, 0, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS));
//SetMercEntityID(0); //SetMercEntityID(0);
@ -5923,7 +5926,6 @@ void Client::SetMerc(Merc* newmerc) {
GetMercInfo().SuspendedTime = 0; GetMercInfo().SuspendedTime = 0;
GetMercInfo().Gender = 0; GetMercInfo().Gender = 0;
GetMercInfo().State = 0; GetMercInfo().State = 0;
GetMercInfo().MercTimerRemaining = 0;
memset(GetMercInfo().merc_name, 0, 64); memset(GetMercInfo().merc_name, 0, 64);
memset(GetEPP().merc_name, 0, 64); memset(GetEPP().merc_name, 0, 64);
} else { } else {
@ -5940,7 +5942,6 @@ void Client::SetMerc(Merc* newmerc) {
GetMercInfo().SuspendedTime = 0; GetMercInfo().SuspendedTime = 0;
GetMercInfo().Gender = newmerc->GetGender(); GetMercInfo().Gender = newmerc->GetGender();
//GetMercInfo().State = newmerc->GetStance(); //GetMercInfo().State = newmerc->GetStance();
GetMercInfo().MercTimerRemaining = 0;
} }
} }
@ -5982,18 +5983,14 @@ void Client::SendMercSuspendResponsePacket(uint32 suspended_time) {
void Client::SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspended_time, int32 update_interval, int32 unk01) { void Client::SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspended_time, int32 update_interval, int32 unk01) {
if (GetClientVersion() == EQClientSoD) {
update_interval = GetMercInfo().MercTimerRemaining;
}
// Send Mercenary Status/Timer packet // Send Mercenary Status/Timer packet
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryTimer, sizeof(MercenaryStatus_Struct)); EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryTimer, sizeof(MercenaryStatus_Struct));
MercenaryStatus_Struct* mss = (MercenaryStatus_Struct*)outapp->pBuffer; MercenaryStatus_Struct* mss = (MercenaryStatus_Struct*)outapp->pBuffer;
mss->MercEntityID = entity_id; // Seen 0 (no merc spawned) or unknown value when merc is spawned mss->MercEntityID = entity_id; // Seen 0 (no merc spawned) or unknown value when merc is spawned
mss->UpdateInterval = update_interval; // Seen 900000 - 15 minutes in ms
mss->MercUnk01 = unk01; // Seen 180000 - 3 minutes in ms - Used for the unsuspend button refresh timer
mss->MercState = merc_state; // Seen 5 (normal) or 1 (suspended) mss->MercState = merc_state; // Seen 5 (normal) or 1 (suspended)
mss->SuspendedTime = suspended_time; // Seen 0 for not suspended or Unix Timestamp for suspended merc mss->SuspendedTime = suspended_time; // Seen 0 for not suspended or Unix Timestamp for suspended merc
mss->UpdateInterval = update_interval; // Seen 900000 - 15 minutes in ms
mss->MercUnk01 = unk01; // Seen 180000 - 3 minutes in ms - Used for the unsuspend button refresh timer
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
} }