Merge pull request #1119 from noudess/master

Fix bugged pet sit button and taunt.
This commit is contained in:
Chris Miles 2020-09-19 18:48:13 -05:00 committed by GitHub
commit 5e93746e8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 99 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
ALTER TABLE `character_pet_info` ADD COLUMN `taunting` tinyint(1) NOT NULL DEFAULT '1' COMMENT '';

View File

@ -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());

View File

@ -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);

View File

@ -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,13 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
pet->CalcBonuses();
pet->SetHP(m_petinfo.HP);
pet->SetMana(m_petinfo.Mana);
// 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;
}
@ -10069,6 +10077,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 +10123,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 +10188,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 +10212,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 +10259,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 +10298,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 +10309,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

View File

@ -433,7 +433,21 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
petpower = power;
SetOwnerID(owner->GetID());
SetPetSpellID(spell_id);
taunting = true;
// All pets start at false on newer clients. The client
// turns it on and tracks the state.
taunting=false;
// 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)) {
if ((typeofpet != petFamiliar && typeofpet != petAnimation) ||
aabonuses.PetCommands[PET_TAUNT]) {
taunting=true;
}
}
}
// Class should use npc constructor to set light properties
}

View File

@ -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);

View File

@ -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`, "

View File

@ -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 {