From 29f7bc7a9c60aee06d5d871addda69dc72681279 Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 31 Aug 2020 13:39:42 -0400 Subject: [PATCH 1/7] Fix bugged pet window sit button and pet sit based regen. --- zone/attack.cpp | 28 ++++++++++++++++++++++++++++ zone/client_packet.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/zone/attack.cpp b/zone/attack.cpp index 86c326e53..951d922ed 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3445,6 +3445,22 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const // emote goes with every one ... even npcs entity_list.MessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName()); } + + // If a client pet is damaged while sitting, stand, fix sit button, + // and remove sitting regen. Removes bug where client clicks sit + // during battle and gains pet hp-regen and bugs the sit button. + if (IsPet()) { + Mob *owner = this->GetOwner(); + if (owner && owner->IsClient()) { + if (GetPetOrder() == SPO_Sit) { + SetPetOrder(SPO_Follow); + } + // fix GUI sit button to be unpressed and stop sitting regen + owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0); + SetAppearance(eaStanding); + } + } + } //end `if there is some damage being done and theres anattacker person involved` Mob *pet = GetPet(); @@ -3455,6 +3471,18 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const { if (!pet->IsHeld()) { LogAggro("Sending pet [{}] into battle due to attack", pet->GetName()); + if (IsClient()) { + // if pet was sitting his new mode is follow + // following after the battle (live verified) + if (pet->GetPetOrder() == SPO_Sit) { + pet->SetPetOrder(SPO_Follow); + } + + // fix GUI sit button to be unpressed and stop sitting regen + this->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0); + pet->SetAppearance(eaStanding); + } + pet->AddToHateList(attacker, 1, 0, true, false, false, spell_id); pet->SetTarget(attacker); MessageString(Chat::NPCQuestSay, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 47066a5aa..33a47c3a4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -10069,6 +10069,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetRegroup(false); SetPetCommandState(PET_BUTTON_REGROUP, 0); } + + // fix GUI sit button to be unpressed and stop sitting regen + SetPetCommandState(PET_BUTTON_SIT, 0); + mypet->SetAppearance(eaStanding); + zone->AddAggroMob(); // classic acts like qattack int hate = 1; @@ -10110,6 +10115,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetRegroup(false); SetPetCommandState(PET_BUTTON_REGROUP, 0); } + + // fix GUI sit button to be unpressed and stop sitting regen + SetPetCommandState(PET_BUTTON_SIT, 0); + mypet->SetAppearance(eaStanding); + zone->AddAggroMob(); mypet->AddToHateList(GetTarget(), 1, 0, true, false, false, SPELL_UNKNOWN, true); MessageString(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); @@ -10170,6 +10180,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->IsNPC()) { + + // Set Sit button to unpressed - send stand anim/end hpregen + SetPetCommandState(PET_BUTTON_SIT, 0); + mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + mypet->SayString(this, Chat::PetResponse, PET_GUARDINGLIFE); mypet->SetPetOrder(SPO_Guard); mypet->CastToNPC()->SaveGuardSpot(mypet->GetPosition()); @@ -10189,7 +10204,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SayString(this, Chat::PetResponse, PET_FOLLOWING); mypet->SetPetOrder(SPO_Follow); + + // fix GUI sit button to be unpressed - send stand anim/end hpregen + SetPetCommandState(PET_BUTTON_SIT, 0); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10232,7 +10251,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SayString(this, Chat::PetResponse, PET_GUARDME_STRING); mypet->SetPetOrder(SPO_Follow); + + // Set Sit button to unpressed - send stand anim/end hpregen + SetPetCommandState(PET_BUTTON_SIT, 0); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); + if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10267,6 +10290,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); + SetPetCommandState(PET_BUTTON_SIT, 0); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); } @@ -10277,6 +10301,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); + SetPetCommandState(PET_BUTTON_SIT, 1); mypet->SetPetOrder(SPO_Sit); mypet->SetRunAnimSpeed(0); if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet From 56afa0404bf236415f93bcf4cd79c84ea856f4ce Mon Sep 17 00:00:00 2001 From: Noudess Date: Wed, 2 Sep 2020 12:50:11 -0400 Subject: [PATCH 2/7] Updates to fix taunt button on PET UI to match live behavior. --- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + utils/sql/git/required/2020_09_02_pet_taunting.sql | 1 + zone/client.cpp | 6 +++++- zone/client_packet.cpp | 7 ++++++- zone/pets.cpp | 2 +- zone/spell_effects.cpp | 7 +++++-- zone/zonedb.cpp | 14 ++++++++------ zone/zonedb.h | 1 + 9 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 utils/sql/git/required/2020_09_02_pet_taunting.sql diff --git a/common/version.h b/common/version.h index a481fd1f4..e524afb01 100644 --- a/common/version.h +++ b/common/version.h @@ -34,7 +34,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9156 +#define CURRENT_BINARY_DATABASE_VERSION 9157 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9027 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 58cb8930f..63af98bbd 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -410,6 +410,7 @@ 9154|2020_04_11_expansions_content_filters.sql|SHOW COLUMNS from `zone` LIKE 'min_expansion'|empty| 9155|2020_08_15_lootdrop_level_filtering.sql|SHOW COLUMNS from `lootdrop_entries` LIKE 'trivial_min_level'|empty| 9156|2020_08_16_virtual_zonepoints.sql|SHOW COLUMNS from `zone_points` LIKE 'is_virtual'|empty| +9157|2020_09_02_pet_taunting.sql|SHOW COLUMNS from `character_pet_info` LIKE 'taunting'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2020_09_02_pet_taunting.sql b/utils/sql/git/required/2020_09_02_pet_taunting.sql new file mode 100644 index 000000000..f4de1138f --- /dev/null +++ b/utils/sql/git/required/2020_09_02_pet_taunting.sql @@ -0,0 +1 @@ +ALTER TABLE `character_pet_info` ADD COLUMN `taunting` tinyint(1) NOT NULL DEFAULT '1' COMMENT ''; diff --git a/zone/client.cpp b/zone/client.cpp index a413c7899..fdc75cfe6 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -687,6 +687,7 @@ bool Client::Save(uint8 iCommitNow) { pet->GetPetState(m_petinfo.Buffs, m_petinfo.Items, m_petinfo.Name); m_petinfo.petpower = pet->GetPetPower(); m_petinfo.size = pet->GetSize(); + m_petinfo.taunting = pet->CastToNPC()->IsTaunting(); } else { memset(&m_petinfo, 0, sizeof(struct PetInfo)); } @@ -5642,6 +5643,8 @@ void Client::SuspendMinion() CurrentPet->SetMana(m_suspendedminion.Mana); + CurrentPet->SetTaunting(m_suspendedminion.taunting); + MessageString(Chat::Magenta, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName()); memset(&m_suspendedminion, 0, sizeof(struct PetInfo)); @@ -5653,7 +5656,8 @@ void Client::SuspendMinion() SetPetCommandState(PET_BUTTON_REGROUP, 0); SetPetCommandState(PET_BUTTON_FOLLOW, 1); SetPetCommandState(PET_BUTTON_GUARD, 0); - SetPetCommandState(PET_BUTTON_TAUNT, 1); + // Taunt saved on client side for logging on with pet + // In our db for when we zone. SetPetCommandState(PET_BUTTON_HOLD, 0); SetPetCommandState(PET_BUTTON_GHOLD, 0); SetPetCommandState(PET_BUTTON_FOCUS, 0); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 33a47c3a4..bfb9fd90c 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -904,7 +904,8 @@ void Client::CompleteConnect() SetPetCommandState(PET_BUTTON_REGROUP, 0); SetPetCommandState(PET_BUTTON_FOLLOW, 1); SetPetCommandState(PET_BUTTON_GUARD, 0); - SetPetCommandState(PET_BUTTON_TAUNT, 1); + // Taunt saved on client side for logging on with pet + // In our db for when we zone. SetPetCommandState(PET_BUTTON_HOLD, 0); SetPetCommandState(PET_BUTTON_GHOLD, 0); SetPetCommandState(PET_BUTTON_FOCUS, 0); @@ -1631,6 +1632,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) pet->CalcBonuses(); pet->SetHP(m_petinfo.HP); pet->SetMana(m_petinfo.Mana); + // 1st login, client takes care of this from button status + if (!firstlogon) { + pet->SetTaunting(m_petinfo.taunting); + } } m_petinfo.SpellID = 0; } diff --git a/zone/pets.cpp b/zone/pets.cpp index baaa779f0..dd66fccad 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -433,7 +433,7 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po petpower = power; SetOwnerID(owner->GetID()); SetPetSpellID(spell_id); - taunting = true; + taunting = false; // Class should use npc constructor to set light properties } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 2eb17eb29..8c3599aca 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1245,7 +1245,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove MakePet(spell_id, spell.teleport_zone); // TODO: we need to sync the states for these clients ... // Will fix buttons for now - if (IsClient()) { + Mob *pet=GetPet(); + if (IsClient() && pet) { auto c = CastToClient(); if (c->ClientVersionBit() & EQ::versions::maskUFAndLater) { c->SetPetCommandState(PET_BUTTON_SIT, 0); @@ -1253,7 +1254,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove c->SetPetCommandState(PET_BUTTON_REGROUP, 0); c->SetPetCommandState(PET_BUTTON_FOLLOW, 1); c->SetPetCommandState(PET_BUTTON_GUARD, 0); - c->SetPetCommandState(PET_BUTTON_TAUNT, 1); + // Creating pet from spell - taunt always false + // If suspended pet - that will be restore there + // If logging in, client will send toggle c->SetPetCommandState(PET_BUTTON_HOLD, 0); c->SetPetCommandState(PET_BUTTON_GHOLD, 0); c->SetPetCommandState(PET_BUTTON_FOCUS, 0); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index ad29b10dc..bc1b542dd 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3788,13 +3788,14 @@ void ZoneDatabase::SavePetInfo(Client *client) continue; query = StringFormat("INSERT INTO `character_pet_info` " - "(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`) " - "VALUES (%u, %u, '%s', %i, %u, %u, %u, %f) " + "(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`, `taunting`) " + "VALUES (%u, %u, '%s', %i, %u, %u, %u, %f, %u) " "ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, " - "`hp` = %u, `mana` = %u, `size` = %f", + "`hp` = %u, `mana` = %u, `size` = %f, `taunting` = %u", client->CharacterID(), pet, petinfo->Name, petinfo->petpower, petinfo->SpellID, - petinfo->HP, petinfo->Mana, petinfo->size, // and now the ON DUPLICATE ENTRIES - petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size); + petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0, + // and now the ON DUPLICATE ENTRIES + petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size, (petinfo->taunting) ? 1 : 0); results = database.QueryDatabase(query); if (!results.Success()) return; @@ -3866,7 +3867,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) memset(suspended, 0, sizeof(PetInfo)); std::string query = StringFormat("SELECT `pet`, `petname`, `petpower`, `spell_id`, " - "`hp`, `mana`, `size` FROM `character_pet_info` " + "`hp`, `mana`, `size` , `taunting` FROM `character_pet_info` " "WHERE `char_id` = %u", client->CharacterID()); auto results = database.QueryDatabase(query); @@ -3891,6 +3892,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) pi->HP = atoul(row[4]); pi->Mana = atoul(row[5]); pi->size = atof(row[6]); + pi->taunting = (bool) atoi(row[7]); } query = StringFormat("SELECT `pet`, `slot`, `spell_id`, `caster_level`, `castername`, " diff --git a/zone/zonedb.h b/zone/zonedb.h index f3766c05c..bb6311eb0 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -155,6 +155,7 @@ struct PetInfo { SpellBuff_Struct Buffs[PET_BUFF_COUNT]; uint32 Items[EQ::invslot::EQUIPMENT_COUNT]; char Name[64]; + bool taunting; }; struct ZoneSpellsBlocked { From 96fb156c4718003002ccb9a8cc5576a627b59c6a Mon Sep 17 00:00:00 2001 From: Noudess Date: Wed, 2 Sep 2020 14:50:51 -0400 Subject: [PATCH 3/7] Change Older clients to not use persistant taunt button & default to taunt on. --- zone/client_packet.cpp | 9 ++++++--- zone/pets.cpp | 13 ++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index bfb9fd90c..316c08cd9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1632,9 +1632,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) pet->CalcBonuses(); pet->SetHP(m_petinfo.HP); pet->SetMana(m_petinfo.Mana); - // 1st login, client takes care of this from button status - if (!firstlogon) { - pet->SetTaunting(m_petinfo.taunting); + + // Taunt persists when zoning on newer clients, overwrite default. + if (m_ClientVersionBit & EQ::versions::maskUFAndLater) { + if (!firstlogon) { + pet->SetTaunting(m_petinfo.taunting); + } } } m_petinfo.SpellID = 0; diff --git a/zone/pets.cpp b/zone/pets.cpp index dd66fccad..a8b69f77f 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -433,7 +433,18 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po petpower = power; SetOwnerID(owner->GetID()); SetPetSpellID(spell_id); - taunting = false; + + bool non_persistant_pet_states_client = false; + + // Deault to on in older clients, off in new clients that control state. + if (owner && owner->IsClient()) { + if (!(owner->CastToClient()->ClientVersionBit() & EQ::versions::maskUFAndLater)) { + LogError("Titanium"); + non_persistant_pet_states_client = true; + } + + taunting = non_persistant_pet_states_client; + } // Class should use npc constructor to set light properties } From d5451c5d7719b1b54141383faedf0a29f911f2a9 Mon Sep 17 00:00:00 2001 From: Noudess Date: Wed, 2 Sep 2020 14:56:12 -0400 Subject: [PATCH 4/7] Remove left over logging. --- zone/pets.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/zone/pets.cpp b/zone/pets.cpp index a8b69f77f..d16334645 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -439,7 +439,6 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po // Deault to on in older clients, off in new clients that control state. if (owner && owner->IsClient()) { if (!(owner->CastToClient()->ClientVersionBit() & EQ::versions::maskUFAndLater)) { - LogError("Titanium"); non_persistant_pet_states_client = true; } From ff6de1938bdffd87068cd7532c72f83d326d3aea Mon Sep 17 00:00:00 2001 From: Noudess Date: Thu, 3 Sep 2020 15:38:35 -0400 Subject: [PATCH 5/7] Change older clients to default to taunting=true only for taunt eligble pets. --- zone/pets.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/zone/pets.cpp b/zone/pets.cpp index d16334645..734be3ef4 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -434,15 +434,19 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po SetOwnerID(owner->GetID()); SetPetSpellID(spell_id); - bool non_persistant_pet_states_client = false; + // All pets start at false on newer clients. The client + // turns it on and tracks the state. + taunting=false; - // Deault to on in older clients, off in new clients that control state. + // Older clients didn't track state, and default taunting is on (per @mackal) + // Familiar and animation pets don't get taunt until an AA. if (owner && owner->IsClient()) { if (!(owner->CastToClient()->ClientVersionBit() & EQ::versions::maskUFAndLater)) { - non_persistant_pet_states_client = true; + if ((typeofpet != petFamiliar && typeofpet != petAnimation) || + GetAA(aaAnimationEmpathy) >= 3) { + taunting=true; + } } - - taunting = non_persistant_pet_states_client; } // Class should use npc constructor to set light properties From cd2b2c3c19a555b919a670f56acbc3950ba1dc9b Mon Sep 17 00:00:00 2001 From: Noudess Date: Tue, 8 Sep 2020 16:48:09 -0400 Subject: [PATCH 6/7] Fix indentation. --- zone/attack.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 951d922ed..1d780a27e 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3455,9 +3455,9 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const if (GetPetOrder() == SPO_Sit) { SetPetOrder(SPO_Follow); } - // fix GUI sit button to be unpressed and stop sitting regen - owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0); - SetAppearance(eaStanding); + // fix GUI sit button to be unpressed and stop sitting regen + owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0); + SetAppearance(eaStanding); } } From 05dfe748d38c7187b9b076e58a9dcd13172e27a7 Mon Sep 17 00:00:00 2001 From: Noudess Date: Tue, 8 Sep 2020 19:10:48 -0400 Subject: [PATCH 7/7] Use aabonuses.PetCommands instead of checking AA level --- zone/pets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/pets.cpp b/zone/pets.cpp index 734be3ef4..e88f0f246 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -443,7 +443,7 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po if (owner && owner->IsClient()) { if (!(owner->CastToClient()->ClientVersionBit() & EQ::versions::maskUFAndLater)) { if ((typeofpet != petFamiliar && typeofpet != petAnimation) || - GetAA(aaAnimationEmpathy) >= 3) { + aabonuses.PetCommands[PET_TAUNT]) { taunting=true; } }