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/eqlaunch/CMakeLists.txt b/eqlaunch/CMakeLists.txt index 8483b9bb0..14257fef9 100644 --- a/eqlaunch/CMakeLists.txt +++ b/eqlaunch/CMakeLists.txt @@ -13,7 +13,7 @@ SET(eqlaunch_headers ADD_EXECUTABLE(eqlaunch ${eqlaunch_sources} ${eqlaunch_headers}) -TARGET_LINK_LIBRARIES(eqlaunch Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(eqlaunch Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) diff --git a/eqlaunch/worldserver.cpp b/eqlaunch/worldserver.cpp index a3071f3df..1f314bd8f 100644 --- a/eqlaunch/worldserver.cpp +++ b/eqlaunch/worldserver.cpp @@ -126,7 +126,6 @@ void WorldServer::Process() { default: { _log(LAUNCHER__NET, "Unknown opcode 0x%x from World of len %d", pack->opcode, pack->size); - //DumpPacket(pack->pBuffer, pack->size); break; } } diff --git a/queryserv/CMakeLists.txt b/queryserv/CMakeLists.txt index 96cdaf69c..4e319ddad 100644 --- a/queryserv/CMakeLists.txt +++ b/queryserv/CMakeLists.txt @@ -19,7 +19,7 @@ ADD_EXECUTABLE(queryserv ${qserv_sources} ${qserv_headers}) ADD_DEFINITIONS(-DQSERV) -TARGET_LINK_LIBRARIES(queryserv Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(queryserv Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) diff --git a/shared_memory/CMakeLists.txt b/shared_memory/CMakeLists.txt index 74629fdd1..902ffb2ff 100644 --- a/shared_memory/CMakeLists.txt +++ b/shared_memory/CMakeLists.txt @@ -19,7 +19,7 @@ SET(shared_memory_headers ADD_EXECUTABLE(shared_memory ${shared_memory_sources} ${shared_memory_headers}) -TARGET_LINK_LIBRARIES(shared_memory Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(shared_memory Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) SET_TARGET_PROPERTIES(shared_memory PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF") diff --git a/ucs/CMakeLists.txt b/ucs/CMakeLists.txt index 6f0d023a0..1218541a3 100644 --- a/ucs/CMakeLists.txt +++ b/ucs/CMakeLists.txt @@ -21,7 +21,7 @@ ADD_EXECUTABLE(ucs ${ucs_sources} ${ucs_headers}) ADD_DEFINITIONS(-DUCS) -TARGET_LINK_LIBRARIES(ucs Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(ucs Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index f36ba87fa..768072677 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -67,7 +67,7 @@ ADD_EXECUTABLE(world ${world_sources} ${world_headers}) ADD_DEFINITIONS(-DWORLD) -TARGET_LINK_LIBRARIES(world Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(world Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index e0b0d01b6..7079942ab 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -155,7 +155,7 @@ ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers}) ADD_DEFINITIONS(-DZONE) -TARGET_LINK_LIBRARIES(zone Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) +TARGET_LINK_LIBRARIES(zone Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) SET_TARGET_PROPERTIES(zone PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF") @@ -175,4 +175,6 @@ IF(UNIX) ADD_DEFINITIONS(-fPIC) ENDIF(UNIX) +INCLUDE_DIRECTORIES(${VLD_INCLUDE_DIR}) + SET(EXECUTABLE_OUTPUT_PATH ../Bin) diff --git a/zone/MobAI.cpp b/zone/MobAI.cpp index 4bc063998..a2030aa7d 100644 --- a/zone/MobAI.cpp +++ b/zone/MobAI.cpp @@ -1721,7 +1721,7 @@ void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) { if(!CastToNPC()->GetCombatEvent() && GetHP() > 0) { parse->EventNPC(EVENT_COMBAT, CastToNPC(), attacker, "1", 0); - uint16 emoteid = CastToNPC()->GetNPCEmoteID(); + uint16 emoteid = GetEmoteID(); if(emoteid != 0) CastToNPC()->DoNPCEmote(ENTERCOMBAT,emoteid); CastToNPC()->SetCombatEvent(true); @@ -1754,11 +1754,14 @@ void Mob::AI_Event_NoLongerEngaged() { { if(CastToNPC()->GetCombatEvent() && GetHP() > 0) { - uint16 emoteid = CastToNPC()->GetNPCEmoteID(); + if(entity_list.GetNPCByID(this->GetID())) + { + uint16 emoteid = CastToNPC()->GetEmoteID(); parse->EventNPC(EVENT_COMBAT, CastToNPC(), NULL, "0", 0); if(emoteid != 0) CastToNPC()->DoNPCEmote(LEAVECOMBAT,emoteid); CastToNPC()->SetCombatEvent(false); + } } } } diff --git a/zone/attack.cpp b/zone/attack.cpp index 1d787b0e9..141aa50ec 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1451,7 +1451,7 @@ void Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ { if (killerMob->IsNPC()) { parse->EventNPC(EVENT_SLAY, killerMob->CastToNPC(), this, "", 0); - uint16 emoteid = killerMob->CastToNPC()->GetNPCEmoteID(); + uint16 emoteid = killerMob->GetEmoteID(); if(emoteid != 0) killerMob->CastToNPC()->DoNPCEmote(KILLEDPC,emoteid); killerMob->TrySpellOnKill(killed_level,spell); @@ -2209,7 +2209,7 @@ void NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ski this->CheckMinMaxLevel(killer); } entity_list.RemoveFromAutoXTargets(this); - uint16 emoteid = this->GetNPCEmoteID(); + uint16 emoteid = this->GetEmoteID(); Corpse* corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata,level>54?RuleI(NPC,MajorNPCCorpseDecayTimeMS):RuleI(NPC,MinorNPCCorpseDecayTimeMS)); entity_list.LimitRemoveNPC(this); entity_list.AddCorpse(corpse, this->GetID()); @@ -2302,13 +2302,13 @@ void NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ski if(killerMob) { Mob *oos = killerMob->GetOwnerOrSelf(); parse->EventNPC(EVENT_DEATH, this, oos, "", 0); - uint16 emoteid = this->GetNPCEmoteID(); + uint16 emoteid = this->GetEmoteID(); if(emoteid != 0) this->DoNPCEmote(ONDEATH,emoteid); if(oos->IsNPC()) { parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0); - uint16 emoteid = oos->CastToNPC()->GetNPCEmoteID(); + uint16 emoteid = oos->GetEmoteID(); if(emoteid != 0) oos->CastToNPC()->DoNPCEmote(KILLEDNPC,emoteid); killerMob->TrySpellOnKill(killed_level,spell); diff --git a/zone/client.cpp b/zone/client.cpp index 425309810..e610361d7 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) { @@ -5915,7 +5916,7 @@ void Client::CheckEmoteHail(Mob *target, const char* message) { return; } - uint16 emoteid = target->CastToNPC()->GetNPCEmoteID(); + uint16 emoteid = target->GetEmoteID(); if(emoteid != 0) target->CastToNPC()->DoNPCEmote(HAILED,emoteid); } 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..cae85336a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3540,7 +3540,6 @@ void Client::Handle_OP_WearChange(const EQApplicationPacket *app) { if (app->size != sizeof(WearChange_Struct)) { cout << "Wrong size: OP_WearChange, size=" << app->size << ", expected " << sizeof(WearChange_Struct) << endl; - DumpPacket(app); return; } @@ -3595,7 +3594,6 @@ void Client::Handle_OP_WhoAllRequest(const EQApplicationPacket *app) { if (app->size != sizeof(Who_All_Struct)) { cout << "Wrong size on OP_WhoAll. Got: " << app->size << ", Expected: " << sizeof(Who_All_Struct) << endl; - DumpPacket(app); return; } Who_All_Struct* whoall = (Who_All_Struct*) app->pBuffer; @@ -6463,7 +6461,12 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app) // Remove the merc from the old group if (GetMerc()) - GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); + { + if(GetMerc()->GetGroup()) + { + Merc::RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); + } + } Group* group = entity_list.GetGroupByClient(inviter->CastToClient()); @@ -6662,34 +6665,31 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app) group->DelMember(memberToDisband,false); Client* memberClient = memberToDisband->CastToClient(); Merc* memberMerc = memberToDisband->CastToClient()->GetMerc(); - memberMerc->RemoveMercFromGroup(memberMerc, group); + if(memberClient && memberMerc && group) + { + Merc::RemoveMercFromGroup(memberMerc, group); - if(!memberMerc->IsGrouped() && !memberClient->IsGrouped()) { - Group *g = new Group(memberClient); + if(!memberMerc->IsGrouped() && !memberClient->IsGrouped()) { + Group *g = new Group(memberClient); - if(!g) { - delete g; - g = NULL; - return; - } + entity_list.AddGroup(g); - entity_list.AddGroup(g); - - if(g->GetID() == 0) { - safe_delete(g); - return; - } - if(memberMerc->AddMercToGroup(memberMerc, g)) { - database.SetGroupLeaderName(g->GetID(), memberClient->GetName()); - g->SaveGroupLeaderAA(); - database.SetGroupID(memberClient->GetName(), g->GetID(), memberClient->CharacterID()); - database.SetGroupID(memberMerc->GetName(), g->GetID(), memberClient->CharacterID(), true); - database.RefreshGroupFromDB(memberClient); + if(g->GetID() == 0) { + safe_delete(g); + return; + } + if(Merc::AddMercToGroup(memberMerc, g)) { + database.SetGroupLeaderName(g->GetID(), memberClient->GetName()); + g->SaveGroupLeaderAA(); + database.SetGroupID(memberClient->GetName(), g->GetID(), memberClient->CharacterID()); + database.SetGroupID(memberMerc->GetName(), g->GetID(), memberClient->CharacterID(), true); + database.RefreshGroupFromDB(memberClient); + } } } } else if(memberToDisband->IsMerc()) { - memberToDisband->CastToMerc()->RemoveMercFromGroup(memberToDisband->CastToMerc(), group); + Merc::RemoveMercFromGroup(memberToDisband->CastToMerc(), group); memberToDisband->CastToMerc()->Suspend(); } } @@ -7400,6 +7400,24 @@ void Client::Handle_OP_Emote(const EQApplicationPacket *app) memcpy(out->message, name, len_name); memcpy(&out->message[len_name], in->message, len_msg); + /* + if (target && target->IsClient()) { + entity_list.QueueCloseClients(this, outapp, false, 100, target); + + cptr = outapp->pBuffer + 2; + + // not sure if live does this or not. thought it was a nice feature, but would take a lot to + // clean up grammatical and other errors. Maybe with a regex parser... + replacestr((char *)cptr, target->GetName(), "you"); + replacestr((char *)cptr, " he", " you"); + replacestr((char *)cptr, " she", " you"); + replacestr((char *)cptr, " him", " you"); + replacestr((char *)cptr, " her", " you"); + target->CastToClient()->QueuePacket(outapp); + + } + else + */ entity_list.QueueCloseClients(this, outapp, true, 100,0,true,FilterSocials); safe_delete(outapp); @@ -13814,7 +13832,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..c2c12aa0d 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -188,13 +188,14 @@ bool Client::Process() { if(linkdead_timer.Check()){ Save(); - LeaveGroup(); if (GetMerc()) { GetMerc()->Save(); - GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); + if(GetMerc()->GetGroup() != NULL) + Merc::RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); GetMerc()->Depop(); } + LeaveGroup(); Raid *myraid = entity_list.GetRaidByClient(this); if (myraid) { @@ -209,6 +210,7 @@ bool Client::Process() { if (GetMerc()) { GetMerc()->Save(); + if(GetMerc()->GetGroup() != NULL) GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); GetMerc()->Depop(); } @@ -249,7 +251,7 @@ bool Client::Process() { UpdateMercTimer(); } - if(GetMercInfo().MercTemplateID != 0) + if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended) { if(p_timers.Expired(&database, pTimerMercSuspend, false)) { CheckMercSuspendTimer(); @@ -678,6 +680,7 @@ bool Client::Process() { if (GetMerc()) { GetMerc()->Save(); + if(GetMerc()->GetGroup() != NULL) GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); GetMerc()->Depop(); } @@ -727,7 +730,8 @@ bool Client::Process() { } if (GetMerc()) { - GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); + if(GetMerc()->GetGroup() != NULL) + Merc::RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup()); GetMerc()->Depop(); } adverrorinfo = 811; @@ -1307,7 +1311,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) uint64 value = 0, amount_to_take = 0, amount_to_add = 0; int32 *from_bucket = 0, *to_bucket = 0; Mob* trader = trade->With(); - + // could just do a range, but this is clearer and explicit if ( diff --git a/zone/command.cpp b/zone/command.cpp index dce3257ee..8451d851f 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1867,7 +1867,7 @@ void command_npcstats(Client *c, const Seperator *sep) c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType()); c->Message(0, "Runspeed: %f Walkspeed: %f", c->GetTarget()->GetRunspeed(), c->GetTarget()->GetWalkspeed()); c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid()); - c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetNPCEmoteID()); + c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID()); c->GetTarget()->CastToNPC()->QueryLoot(c); } } @@ -11031,7 +11031,7 @@ void command_emoteview(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsNPC()) { int count=0; - int emoteid = c->GetTarget()->CastToNPC()->GetNPCEmoteID(); + int emoteid = c->GetTarget()->CastToNPC()->GetEmoteID(); LinkedListIterator iterator(zone->NPCEmoteList); iterator.Reset(); diff --git a/zone/doors.cpp b/zone/doors.cpp index 53315f413..c638ef746 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -148,7 +148,6 @@ void Doors::HandleClick(Client* sender, uint8 trigger) EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; - md->doorid = door_id; ///////////////////////////////////////////////////////////////// //used_pawn: Locked doors! Rogue friendly too =) diff --git a/zone/entity.cpp b/zone/entity.cpp index 393abb8ea..660db5d7d 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -621,7 +621,7 @@ void EntityList::AddNPC(NPC* npc, bool SendSpawnPacket, bool dontqueue) { npc->SetID(GetFreeID()); parse->EventNPC(EVENT_SPAWN, npc, NULL, "", 0); - uint16 emoteid = npc->GetNPCEmoteID(); + uint16 emoteid = npc->GetEmoteID(); if(emoteid != 0) npc->DoNPCEmote(ONSPAWN,emoteid); @@ -2760,6 +2760,8 @@ void EntityList::RemoveEntity(uint16 id) return; else if(entity_list.RemoveTrap(id)) return; + else if(entity_list.RemoveMerc(id)) + return; #ifdef BOTS // This block of code is necessary to clean up bot objects diff --git a/zone/merc.cpp b/zone/merc.cpp index e078efec4..7fe95e4b4 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4917,7 +4917,6 @@ void Merc::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_sk if(Suspend()) { - //todo: perl event? } } @@ -5310,7 +5309,7 @@ void Client::UpdateMercTimer() if(merc && !merc->IsSuspended()) { - if(merc_timer.Check()) + if(GetMercTimer()->Check()) { uint32 upkeep = Merc::CalcUpkeepCost(merc->GetMercTemplateID(), GetLevel()); @@ -5325,8 +5324,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 +5507,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 +5534,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 +5600,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(); @@ -5637,22 +5642,18 @@ bool Merc::Suspend() { SetSuspended(true); - /*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(); - //mercOwner->UpdateMercTimer(); + Save(); + mercOwner->GetMercTimer()->Disable(); + mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime); Depop(); + mercOwner->SendMercTimerPacket(0, 1, mercOwner->GetMercInfo().SuspendedTime, mercOwner->GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); return true; } @@ -5675,15 +5676,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 +5755,6 @@ bool Merc::Dismiss(){ return false; mercOwner->SendClearMercInfo(); - mercOwner->SendMercTimerPacket(GetID(), 5, 0, RuleI(Mercs, UpkeepIntervalMS), RuleI(Mercs, SuspendIntervalMS)); //SetMercEntityID(0); @@ -5776,11 +5774,11 @@ void Merc::Zone() { void Merc::Depop() { WipeHateList(); - + entity_list.RemoveMerc(this->GetID()); entity_list.RemoveFromHateLists(this); if(HasGroup()) - RemoveMercFromGroup(this, GetGroup()); + Merc::RemoveMercFromGroup(this, GetGroup()); if(HasPet()) { GetPet()->Depop(); @@ -5841,7 +5839,7 @@ bool Merc::AddMercToGroup(Merc* merc, Group* group) { if(merc && group) { // Remove merc from current group if any if(merc->HasGroup()) { - merc->RemoveMercFromGroup(merc, merc->GetGroup()); + Merc::RemoveMercFromGroup(merc, merc->GetGroup()); } // Add merc to this group if(group->AddMember(merc)) { @@ -5923,7 +5921,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 +5937,6 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().SuspendedTime = 0; GetMercInfo().Gender = newmerc->GetGender(); //GetMercInfo().State = newmerc->GetStance(); - GetMercInfo().MercTimerRemaining = 0; } } @@ -5982,18 +5978,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); } diff --git a/zone/mob.cpp b/zone/mob.cpp index 6c8bbc398..2d1539086 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -378,6 +378,8 @@ Mob::Mob(const char* in_name, m_DisableMelee = false; for (int i = 0; i < HIGHEST_SKILL+2; i++) { SkillDmgTaken_Mod[i] = 0; } for (int i = 0; i < HIGHEST_RESIST+2; i++) { Vulnerability_Mod[i] = 0; } + + emoteid = 0; } Mob::~Mob() @@ -1194,7 +1196,7 @@ void Mob::ShowStats(Client* client) if(n->respawn2 != 0) spawngroupid = n->respawn2->SpawnGroupID(); client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID()); - client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %f Walkspeed: %f", n->GetAccuracyRating(), n->MerchantType, n->GetNPCEmoteID(), n->GetRunspeed(), n->GetWalkspeed()); + client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %f Walkspeed: %f", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), n->GetRunspeed(), n->GetWalkspeed()); n->QueryLoot(client); } if (IsAIControlled()) { diff --git a/zone/mob.h b/zone/mob.h index 1b3407620..5f29227d5 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -784,6 +784,9 @@ public: void TarGlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid); void DelGlobal(const char *varname); + inline void SetEmoteID(uint16 emote) { emoteid = emote; } + inline uint16 GetEmoteID() { return emoteid; } + protected: void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic); static uint16 GetProcID(uint16 spell_id, uint8 effect_index); @@ -1110,6 +1113,7 @@ protected: bool m_targetable; int QGVarDuration(const char *fmt); void InsertQuestGlobal(int charid, int npcid, int zoneid, const char *name, const char *value, int expdate); + uint16 emoteid; private: void _StopSong(); //this is not what you think it is diff --git a/zone/npc.cpp b/zone/npc.cpp index b2661e931..a2c1addb1 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -350,6 +350,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float guard_y_saved = 0; guard_z_saved = 0; guard_heading_saved = 0; + SetEmoteID(d->emoteid); InitializeBuffSlots(); CalcBonuses(); } @@ -734,7 +735,7 @@ void NPC::DumpLoot(uint32 npcdump_index, ZSDump_NPC_Loot* npclootdump, uint32* N } void NPC::Depop(bool StartSpawnTimer) { - uint16 emoteid = this->GetNPCEmoteID(); + uint16 emoteid = this->GetEmoteID(); if(emoteid != 0) this->DoNPCEmote(ONDESPAWN,emoteid); p_depop = true; diff --git a/zone/npc.h b/zone/npc.h index f2fa91116..e810cfe1f 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -327,7 +327,6 @@ public: //The corpse we make can only be looted by people who got credit for the kill const bool HasPrivateCorpse() const { return NPCTypedata->private_corpse; } const bool IsUnderwaterOnly() const { return NPCTypedata->underwater; } - const uint32 GetNPCEmoteID() const { return NPCTypedata->emoteid; } const char* GetRawNPCTypeName() const { return NPCTypedata->name; } bool GetDepop() { return p_depop; } diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 56b9de4d4..efc45175f 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -2559,7 +2559,6 @@ void Client::SendTaskFailed(int TaskID, int TaskIndex) { tac->unknown5 = 0; // 0 for task complete or failed. _log(TASKS__UPDATE, "TaskFailed"); - _pkt(TASKS__PACKETS, outapp); QueuePacket(outapp); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 30851b038..0f050368d 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -517,7 +517,6 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac outp->reply_code = 0x00000000; //success for finding it... user->QueuePacket(outapp); - safe_delete(outapp); @@ -664,7 +663,6 @@ void Client::TradeskillSearchResults(const char *query, unsigned long qlen, reply->recipe_id = recipe; reply->trivial = trivial; strn0cpy(reply->recipe_name, name, sizeof(reply->recipe_name)); - FastQueuePacket(&outapp); } mysql_free_result(result);