diff --git a/common/patches/RoF.cpp b/common/patches/RoF.cpp index b44cb8f37..72403850f 100644 --- a/common/patches/RoF.cpp +++ b/common/patches/RoF.cpp @@ -3015,7 +3015,7 @@ ENCODE(OP_ReadBook) { eq->window = emu->window; OUT(type); 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(); } diff --git a/zone/client.cpp b/zone/client.cpp index 425309810..2ee61bee3 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -232,6 +232,7 @@ Client::Client(EQStreamInterface* ieqs) dead_timer.Disable(); camp_timer.Disable(); autosave_timer.Disable(); + GetMercTimer()->Disable(); instalog = false; pLastUpdate = 0; pLastUpdateWZ = 0; @@ -562,8 +563,8 @@ bool Client::Save(uint8 iCommitNow) { if(GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS)) GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS); - if(merc_timer.Enabled()) { - GetMercInfo().MercTimerRemaining = merc_timer.GetRemainingTime(); + if(GetMercTimer()->Enabled()) { + GetMercInfo().MercTimerRemaining = GetMercTimer()->GetRemainingTime(); } if (GetMerc() && !dead) { diff --git a/zone/client.h b/zone/client.h index 3ff2a28f9..e4ff410aa 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1124,7 +1124,7 @@ public: void UpdateMercTimer(); void UpdateMercLevel(); void CheckMercSuspendTimer(); - Timer GetMercTimer() { return merc_timer; }; + Timer* GetMercTimer() { return &merc_timer; }; const char* GetRacePlural(Client* client); const char* GetClassPlural(Client* client); void SendWebLink(const char* website); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6cf5fe4ac..403ea11f9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -13814,7 +13814,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) } if(entityID > 0) { - SendMercTimerPacket(entityID, mercState, suspendedTime, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); + SendMercTimerPacket(entityID, mercState, suspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); } } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 87afcf62a..9d0a87b67 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -249,7 +249,7 @@ bool Client::Process() { UpdateMercTimer(); } - if(GetMercInfo().MercTemplateID != 0) + if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended) { if(p_timers.Expired(&database, pTimerMercSuspend, false)) { CheckMercSuspendTimer(); diff --git a/zone/merc.cpp b/zone/merc.cpp index e078efec4..26eebc1a9 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -5310,7 +5310,7 @@ void Client::UpdateMercTimer() if(merc && !merc->IsSuspended()) { - if(merc_timer.Check()) + if(GetMercTimer()->Check()) { uint32 upkeep = Merc::CalcUpkeepCost(merc->GetMercTemplateID(), GetLevel()); @@ -5325,8 +5325,9 @@ void Client::UpdateMercTimer() } GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS); - SendMercTimerPacket(GetMercID(), 5, 0, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); - merc_timer.Start(RuleI(Mercs, UpkeepIntervalMS)); + SendMercTimerPacket(GetMercID(), 5, 0, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); + GetMercTimer()->Start(RuleI(Mercs, UpkeepIntervalMS)); + GetMercTimer()->SetTimer(GetMercInfo().MercTimerRemaining); // Send upkeep charge message and reset the upkeep timer if (GetClientVersion() < EQClientRoF) @@ -5507,6 +5508,12 @@ bool Client::CheckCanUnsuspendMerc() { 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; } @@ -5528,9 +5535,7 @@ void Client::CheckMercSuspendTimer() { if(GetMercInfo().SuspendedTime != 0) { if(time(NULL) >= GetMercInfo().SuspendedTime){ - GetMercInfo().SuspendedTime = 0; - SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime); - p_timers.Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS)); + SendMercSuspendResponsePacket(0); } } } @@ -5596,12 +5601,13 @@ void Client::SpawnMercOnZone() if(database.LoadMercInfo(this)) { Merc* merc = Merc::LoadMerc(this, &zone->merc_templates[GetMercInfo().MercTemplateID], 0, true); SpawnMerc(merc, false); + SendMercTimerPacket(merc->GetID(), 5, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); } } else { // 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(); @@ -5640,19 +5646,19 @@ bool Merc::Suspend() { /*if(HasGroup()) { RemoveMercFromGroup(this, GetGroup()); }*/ - - Save(); - mercOwner->GetMercInfo().IsSuspended = true; 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->GetMercTimer().Disable(); + Save(); + mercOwner->GetMercTimer()->Disable(); + //mercOwner->UpdateMercTimer(); mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime); Depop(); + mercOwner->SendMercTimerPacket(0, 1, mercOwner->GetMercInfo().SuspendedTime, mercOwner->GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); return true; } @@ -5675,15 +5681,13 @@ bool Merc::Unsuspend(bool setMaxStats) { mercOwner->GetMercInfo().mercid = GetMercID(); mercOwner->GetMercInfo().IsSuspended = false; - mercOwner->GetMercInfo().SuspendedTime = 0; mercOwner->SendMercenaryUnsuspendPacket(0); mercOwner->SendMercenaryUnknownPacket(1); - - mercOwner->SendMercTimerPacket(GetID(), mercState, suspendedTime, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); - - mercOwner->GetMercTimer().Start(mercOwner->GetMercInfo().MercTimerRemaining); - + mercOwner->GetMercInfo().SuspendedTime = 0; + mercOwner->GetMercTimer()->Start(RuleI(Mercs, UpkeepIntervalMS)); + mercOwner->GetMercTimer()->SetTimer(mercOwner->GetMercInfo().MercTimerRemaining); + mercOwner->SendMercTimerPacket(GetID(), mercState, suspendedTime, mercOwner->GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); if(!mercOwner->GetPTimers().Expired(&database, pTimerMercSuspend, false)) mercOwner->GetPTimers().Clear(&database, pTimerMercSuspend); @@ -5756,7 +5760,6 @@ bool Merc::Dismiss(){ return false; mercOwner->SendClearMercInfo(); - mercOwner->SendMercTimerPacket(GetID(), 5, 0, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); //SetMercEntityID(0); @@ -5923,7 +5926,6 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().SuspendedTime = 0; GetMercInfo().Gender = 0; GetMercInfo().State = 0; - GetMercInfo().MercTimerRemaining = 0; memset(GetMercInfo().merc_name, 0, 64); memset(GetEPP().merc_name, 0, 64); } else { @@ -5940,7 +5942,6 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().SuspendedTime = 0; GetMercInfo().Gender = newmerc->GetGender(); //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) { - if (GetClientVersion() == EQClientSoD) { - update_interval = GetMercInfo().MercTimerRemaining; - } - // Send Mercenary Status/Timer packet EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryTimer, sizeof(MercenaryStatus_Struct)); MercenaryStatus_Struct* mss = (MercenaryStatus_Struct*)outapp->pBuffer; 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->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); }