From e9c6424cd8af3d13d693cdc9b76f2e13467ab0e9 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sat, 16 Oct 2021 18:12:25 -0400 Subject: [PATCH] Core/BattlePets: Misc fixes Port From (https://github.com/TrinityCore/TrinityCore/commit/11cc5c0d3bd46b5e68bb549625ef9ca7294deb21) --- Source/Framework/Constants/SharedConst.cs | 1 + .../Database/Databases/LoginDatabase.cs | 4 +- Source/Game/BattlePets/BattlePetManager.cs | 69 +++---- Source/Game/Entities/Object/WorldObject.cs | 186 +++++++++--------- Source/Game/Entities/Player/Player.Spells.cs | 2 +- Source/Game/Entities/Unit/Unit.cs | 7 +- Source/Game/Handlers/ItemHandler.cs | 2 +- .../Networking/Packets/BattlePetPackets.cs | 6 +- .../Game/Networking/Packets/SpellPackets.cs | 4 +- Source/Game/Spells/SpellEffects.cs | 19 +- .../auth/master/2021_10_16_00_auth.sql | 1 + 11 files changed, 151 insertions(+), 150 deletions(-) create mode 100644 sql/updates/auth/master/2021_10_16_00_auth.sql diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index 963bf7417..9197707b4 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -54,6 +54,7 @@ namespace Framework.Constants public const int DefaultMaxBattlePetsPerSpecies = 3; public const int BattlePetCageItemId = 82800; public const int DefaultSummonBattlePetSpell = 118301; + public const int SpellVisualUncagePet = 222; /// /// Lfg Const diff --git a/Source/Framework/Database/Databases/LoginDatabase.cs b/Source/Framework/Database/Databases/LoginDatabase.cs index d98b0361b..1cb306469 100644 --- a/Source/Framework/Database/Databases/LoginDatabase.cs +++ b/Source/Framework/Database/Databases/LoginDatabase.cs @@ -151,8 +151,8 @@ namespace Framework.Database PrepareStatement(LoginStatements.REP_ACCOUNT_TOYS, "REPLACE INTO battlenet_account_toys (accountId, itemId, isFavourite, hasFanfare) VALUES (?, ?, ?, ?)"); // Battle Pets - PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT bp.guid, bp.species, bp.breed, bp.level, bp.exp, bp.health, bp.quality, bp.flags, bp.name, dn.genitive, dn.dative, dn.accusative, dn.instrumental, dn.prepositional FROM battle_pets bp LEFT JOIN battle_pet_declinedname dn ON bp.guid = dn.guid WHERE bp.battlenetAccountId = ?"); - PrepareStatement(LoginStatements.INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, level, exp, health, quality, flags, name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT bp.guid, bp.species, bp.breed, bp.displayId, bp.level, bp.exp, bp.health, bp.quality, bp.flags, bp.name, dn.genitive, dn.dative, dn.accusative, dn.instrumental, dn.prepositional FROM battle_pets bp LEFT JOIN battle_pet_declinedname dn ON bp.guid = dn.guid WHERE bp.battlenetAccountId = ?"); + PrepareStatement(LoginStatements.INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, displayId, level, exp, health, quality, flags, name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); PrepareStatement(LoginStatements.DEL_BATTLE_PETS, "DELETE FROM battle_pets WHERE battlenetAccountId = ? AND guid = ?"); PrepareStatement(LoginStatements.UPD_BATTLE_PETS, "UPDATE battle_pets SET level = ?, exp = ?, health = ?, quality = ?, flags = ?, name = ? WHERE battlenetAccountId = ? AND guid = ?"); PrepareStatement(LoginStatements.SEL_BATTLE_PET_SLOTS, "SELECT id, battlePetGuid, locked FROM battle_pet_slots WHERE battlenetAccountId = ?"); diff --git a/Source/Game/BattlePets/BattlePetManager.cs b/Source/Game/BattlePets/BattlePetManager.cs index 0c9e9b314..c668cb641 100644 --- a/Source/Game/BattlePets/BattlePetManager.cs +++ b/Source/Game/BattlePets/BattlePetManager.cs @@ -151,6 +151,22 @@ namespace Game.BattlePets return _defaultQualityPerSpecies[species]; } + public static uint SelectPetDisplay(BattlePetSpeciesRecord speciesEntry) + { + CreatureTemplate creatureTemplate = Global.ObjectMgr.GetCreatureTemplate(speciesEntry.CreatureID); + if (creatureTemplate != null) + { + if (!speciesEntry.GetFlags().HasFlag(BattlePetSpeciesFlags.RandomDisplay)) + { + CreatureModel creatureModel = creatureTemplate.GetRandomValidModel(); + if (creatureModel != null) + return creatureModel.CreatureDisplayID; + } + } + + return 0; + } + public void LoadFromDB(SQLResult petsResult, SQLResult slotsResult) { if (!petsResult.IsEmpty()) @@ -172,19 +188,20 @@ namespace Game.BattlePets pet.PacketInfo.Guid = ObjectGuid.Create(HighGuid.BattlePet, petsResult.Read(0)); pet.PacketInfo.Species = species; pet.PacketInfo.Breed = petsResult.Read(2); - pet.PacketInfo.Level = petsResult.Read(3); - pet.PacketInfo.Exp = petsResult.Read(4); - pet.PacketInfo.Health = petsResult.Read(5); - pet.PacketInfo.Quality = petsResult.Read(6); - pet.PacketInfo.Flags = petsResult.Read(7); - pet.PacketInfo.Name = petsResult.Read(8); + pet.PacketInfo.DisplayID = petsResult.Read(3); + pet.PacketInfo.Level = petsResult.Read(4); + pet.PacketInfo.Exp = petsResult.Read(5); + pet.PacketInfo.Health = petsResult.Read(6); + pet.PacketInfo.Quality = petsResult.Read(7); + pet.PacketInfo.Flags = petsResult.Read(8); + pet.PacketInfo.Name = petsResult.Read(9); pet.PacketInfo.CreatureID = speciesEntry.CreatureID; - if (!petsResult.IsNull(9)) + if (!petsResult.IsNull(10)) { pet.DeclinedName = new(); for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) - pet.DeclinedName.name[i] = petsResult.Read(9 + i); + pet.DeclinedName.name[i] = petsResult.Read(10 + i); } pet.SaveInfo = BattlePetSaveInfo.Unchanged; @@ -224,12 +241,13 @@ namespace Game.BattlePets stmt.AddValue(1, _owner.GetBattlenetAccountId()); stmt.AddValue(2, pair.Value.PacketInfo.Species); stmt.AddValue(3, pair.Value.PacketInfo.Breed); - stmt.AddValue(4, pair.Value.PacketInfo.Level); - stmt.AddValue(5, pair.Value.PacketInfo.Exp); - stmt.AddValue(6, pair.Value.PacketInfo.Health); - stmt.AddValue(7, pair.Value.PacketInfo.Quality); - stmt.AddValue(8, pair.Value.PacketInfo.Flags); - stmt.AddValue(9, pair.Value.PacketInfo.Name); + stmt.AddValue(4, pair.Value.PacketInfo.DisplayID); + stmt.AddValue(5, pair.Value.PacketInfo.Level); + stmt.AddValue(6, pair.Value.PacketInfo.Exp); + stmt.AddValue(7, pair.Value.PacketInfo.Health); + stmt.AddValue(8, pair.Value.PacketInfo.Quality); + stmt.AddValue(9, pair.Value.PacketInfo.Flags); + stmt.AddValue(10, pair.Value.PacketInfo.Name); trans.Append(stmt); if (pair.Value.DeclinedName != null) @@ -309,21 +327,7 @@ namespace Game.BattlePets return _pets.LookupByKey(guid.GetCounter()); } - public void AddPet(uint species, uint creatureId, ushort level = 1) - { - ushort breed = 3;// default B/B - BattlePetBreedQuality quality = 0; - - if (_availableBreedsPerSpecies.ContainsKey(species)) - breed = _availableBreedsPerSpecies[species].SelectRandom(); - - if (_defaultQualityPerSpecies.ContainsKey(species)) - quality = _defaultQualityPerSpecies[species]; - - AddPet(species, creatureId, breed, quality, level); - } - - public void AddPet(uint species, uint creatureId, ushort breed, BattlePetBreedQuality quality, ushort level = 1) + public void AddPet(uint species, uint display, ushort breed, BattlePetBreedQuality quality, ushort level = 1) { BattlePetSpeciesRecord battlePetSpecies = CliDB.BattlePetSpeciesStorage.LookupByKey(species); if (battlePetSpecies == null) // should never happen @@ -335,7 +339,8 @@ namespace Game.BattlePets BattlePet pet = new(); pet.PacketInfo.Guid = ObjectGuid.Create(HighGuid.BattlePet, Global.ObjectMgr.GetGenerator(HighGuid.BattlePet).Generate()); pet.PacketInfo.Species = species; - pet.PacketInfo.CreatureID = creatureId; + pet.PacketInfo.CreatureID = battlePetSpecies.CreatureID; + pet.PacketInfo.DisplayID = display; pet.PacketInfo.Level = level; pet.PacketInfo.Exp = 0; pet.PacketInfo.Flags = 0; @@ -479,7 +484,7 @@ namespace Game.BattlePets item.SetModifier(ItemModifier.BattlePetSpeciesId, pet.PacketInfo.Species); item.SetModifier(ItemModifier.BattlePetBreedData, (uint)(pet.PacketInfo.Breed | (pet.PacketInfo.Quality << 24))); item.SetModifier(ItemModifier.BattlePetLevel, pet.PacketInfo.Level); - item.SetModifier(ItemModifier.BattlePetDisplayId, pet.PacketInfo.CreatureID); + item.SetModifier(ItemModifier.BattlePetDisplayId, pet.PacketInfo.DisplayID); _owner.GetPlayer().SendNewItem(item, 1, true, false); @@ -526,8 +531,6 @@ namespace Game.BattlePets _owner.GetPlayer().SetSummonedBattlePetGUID(guid); _owner.GetPlayer().SetCurrentBattlePetBreedQuality(pet.PacketInfo.Quality); _owner.GetPlayer().CastSpell(_owner.GetPlayer(), speciesEntry.SummonSpellID != 0 ? speciesEntry.SummonSpellID : SharedConst.DefaultSummonBattlePetSpell); - - // TODO: set pet level, quality... update fields } public void DismissPet() diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 7140d60af..674ad48d0 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -613,108 +613,108 @@ namespace Game.Entities data.WriteBit(false); // HasPetBattleFullUpdate data.FlushBits(); - // if (HasLocalScriptData) - // { - // data.WriteBits(Data.length(), 7); - // data.FlushBits(); - // data.WriteString(Data); - // } + // if (HasLocalScriptData) + // { + // data.WriteBits(Data.length(), 7); + // data.FlushBits(); + // data.WriteString(Data); + // } - // if (HasPetBattleFullUpdate) - // { - // for (std::size_t i = 0; i < 2; ++i) - // { - // *data << ObjectGuid(Players[i].CharacterID); - // *data << int32(Players[i].TrapAbilityID); - // *data << int32(Players[i].TrapStatus); - // *data << uint16(Players[i].RoundTimeSecs); - // *data << int8(Players[i].FrontPet); - // *data << uint8(Players[i].InputFlags); + // if (HasPetBattleFullUpdate) + // { + // for (std::size_t i = 0; i < 2; ++i) + // { + // *data << ObjectGuid(Players[i].CharacterID); + // *data << int32(Players[i].TrapAbilityID); + // *data << int32(Players[i].TrapStatus); + // *data << uint16(Players[i].RoundTimeSecs); + // *data << int8(Players[i].FrontPet); + // *data << uint8(Players[i].InputFlags); - // data.WriteBits(Players[i].Pets.size(), 2); - // data.FlushBits(); - // for (std::size_t j = 0; j < Players[i].Pets.size(); ++j) - // { - // *data << ObjectGuid(Players[i].Pets[j].BattlePetGUID); - // *data << int32(Players[i].Pets[j].SpeciesID); - // *data << int32(Players[i].Pets[j].DisplayID); - // *data << int32(Players[i].Pets[j].CollarID); - // *data << int16(Players[i].Pets[j].Level); - // *data << int16(Players[i].Pets[j].Xp); - // *data << int32(Players[i].Pets[j].CurHealth); - // *data << int32(Players[i].Pets[j].MaxHealth); - // *data << int32(Players[i].Pets[j].Power); - // *data << int32(Players[i].Pets[j].Speed); - // *data << int32(Players[i].Pets[j].NpcTeamMemberID); - // *data << uint16(Players[i].Pets[j].BreedQuality); - // *data << uint16(Players[i].Pets[j].StatusFlags); - // *data << int8(Players[i].Pets[j].Slot); + // data.WriteBits(Players[i].Pets.size(), 2); + // data.FlushBits(); + // for (std::size_t j = 0; j < Players[i].Pets.size(); ++j) + // { + // *data << ObjectGuid(Players[i].Pets[j].BattlePetGUID); + // *data << int32(Players[i].Pets[j].SpeciesID); + // *data << int32(Players[i].Pets[j].CreatureID); + // *data << int32(Players[i].Pets[j].DisplayID); + // *data << int16(Players[i].Pets[j].Level); + // *data << int16(Players[i].Pets[j].Xp); + // *data << int32(Players[i].Pets[j].CurHealth); + // *data << int32(Players[i].Pets[j].MaxHealth); + // *data << int32(Players[i].Pets[j].Power); + // *data << int32(Players[i].Pets[j].Speed); + // *data << int32(Players[i].Pets[j].NpcTeamMemberID); + // *data << uint16(Players[i].Pets[j].BreedQuality); + // *data << uint16(Players[i].Pets[j].StatusFlags); + // *data << int8(Players[i].Pets[j].Slot); - // *data << uint(Players[i].Pets[j].Abilities.size()); - // *data << uint(Players[i].Pets[j].Auras.size()); - // *data << uint(Players[i].Pets[j].States.size()); - // for (std::size_t k = 0; k < Players[i].Pets[j].Abilities.size(); ++k) - // { - // *data << int32(Players[i].Pets[j].Abilities[k].AbilityID); - // *data << int16(Players[i].Pets[j].Abilities[k].CooldownRemaining); - // *data << int16(Players[i].Pets[j].Abilities[k].LockdownRemaining); - // *data << int8(Players[i].Pets[j].Abilities[k].AbilityIndex); - // *data << uint8(Players[i].Pets[j].Abilities[k].Pboid); - // } + // *data << uint(Players[i].Pets[j].Abilities.size()); + // *data << uint(Players[i].Pets[j].Auras.size()); + // *data << uint(Players[i].Pets[j].States.size()); + // for (std::size_t k = 0; k < Players[i].Pets[j].Abilities.size(); ++k) + // { + // *data << int32(Players[i].Pets[j].Abilities[k].AbilityID); + // *data << int16(Players[i].Pets[j].Abilities[k].CooldownRemaining); + // *data << int16(Players[i].Pets[j].Abilities[k].LockdownRemaining); + // *data << int8(Players[i].Pets[j].Abilities[k].AbilityIndex); + // *data << uint8(Players[i].Pets[j].Abilities[k].Pboid); + // } - // for (std::size_t k = 0; k < Players[i].Pets[j].Auras.size(); ++k) - // { - // *data << int32(Players[i].Pets[j].Auras[k].AbilityID); - // *data << uint(Players[i].Pets[j].Auras[k].InstanceID); - // *data << int32(Players[i].Pets[j].Auras[k].RoundsRemaining); - // *data << int32(Players[i].Pets[j].Auras[k].CurrentRound); - // *data << uint8(Players[i].Pets[j].Auras[k].CasterPBOID); - // } + // for (std::size_t k = 0; k < Players[i].Pets[j].Auras.size(); ++k) + // { + // *data << int32(Players[i].Pets[j].Auras[k].AbilityID); + // *data << uint(Players[i].Pets[j].Auras[k].InstanceID); + // *data << int32(Players[i].Pets[j].Auras[k].RoundsRemaining); + // *data << int32(Players[i].Pets[j].Auras[k].CurrentRound); + // *data << uint8(Players[i].Pets[j].Auras[k].CasterPBOID); + // } - // for (std::size_t k = 0; k < Players[i].Pets[j].States.size(); ++k) - // { - // *data << uint(Players[i].Pets[j].States[k].StateID); - // *data << int32(Players[i].Pets[j].States[k].StateValue); - // } + // for (std::size_t k = 0; k < Players[i].Pets[j].States.size(); ++k) + // { + // *data << uint(Players[i].Pets[j].States[k].StateID); + // *data << int32(Players[i].Pets[j].States[k].StateValue); + // } - // data.WriteBits(Players[i].Pets[j].CustomName.length(), 7); - // data.FlushBits(); - // data.WriteString(Players[i].Pets[j].CustomName); - // } - // } + // data.WriteBits(Players[i].Pets[j].CustomName.length(), 7); + // data.FlushBits(); + // data.WriteString(Players[i].Pets[j].CustomName); + // } + // } - // for (std::size_t i = 0; i < 3; ++i) - // { - // *data << uint(Enviros[j].Auras.size()); - // *data << uint(Enviros[j].States.size()); - // for (std::size_t j = 0; j < Enviros[j].Auras.size(); ++j) - // { - // *data << int32(Enviros[j].Auras[j].AbilityID); - // *data << uint(Enviros[j].Auras[j].InstanceID); - // *data << int32(Enviros[j].Auras[j].RoundsRemaining); - // *data << int32(Enviros[j].Auras[j].CurrentRound); - // *data << uint8(Enviros[j].Auras[j].CasterPBOID); - // } + // for (std::size_t i = 0; i < 3; ++i) + // { + // *data << uint(Enviros[j].Auras.size()); + // *data << uint(Enviros[j].States.size()); + // for (std::size_t j = 0; j < Enviros[j].Auras.size(); ++j) + // { + // *data << int32(Enviros[j].Auras[j].AbilityID); + // *data << uint(Enviros[j].Auras[j].InstanceID); + // *data << int32(Enviros[j].Auras[j].RoundsRemaining); + // *data << int32(Enviros[j].Auras[j].CurrentRound); + // *data << uint8(Enviros[j].Auras[j].CasterPBOID); + // } - // for (std::size_t j = 0; j < Enviros[j].States.size(); ++j) - // { - // *data << uint(Enviros[i].States[j].StateID); - // *data << int32(Enviros[i].States[j].StateValue); - // } - // } + // for (std::size_t j = 0; j < Enviros[j].States.size(); ++j) + // { + // *data << uint(Enviros[i].States[j].StateID); + // *data << int32(Enviros[i].States[j].StateValue); + // } + // } - // *data << uint16(WaitingForFrontPetsMaxSecs); - // *data << uint16(PvpMaxRoundTime); - // *data << int32(CurRound); - // *data << uint(NpcCreatureID); - // *data << uint(NpcDisplayID); - // *data << int8(CurPetBattleState); - // *data << uint8(ForfeitPenalty); - // *data << ObjectGuid(InitialWildPetGUID); - // data.WriteBit(IsPVP); - // data.WriteBit(CanAwardXP); - // data.FlushBits(); - // } + // *data << uint16(WaitingForFrontPetsMaxSecs); + // *data << uint16(PvpMaxRoundTime); + // *data << int32(CurRound); + // *data << uint(NpcCreatureID); + // *data << uint(NpcDisplayID); + // *data << int8(CurPetBattleState); + // *data << uint8(ForfeitPenalty); + // *data << ObjectGuid(InitialWildPetGUID); + // data.WriteBit(IsPVP); + // data.WriteBit(CanAwardXP); + // data.FlushBits(); + // } } if (flags.ActivePlayer) diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index ffdb8b4d1..e1705ac98 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -2658,7 +2658,7 @@ namespace Game.Entities { if (entry.SummonSpellID == spellId && GetSession().GetBattlePetMgr().GetPetCount(entry.Id) == 0) { - GetSession().GetBattlePetMgr().AddPet(entry.Id, entry.CreatureID, BattlePetMgr.RollPetBreed(entry.Id), BattlePetMgr.GetDefaultPetQuality(entry.Id)); + GetSession().GetBattlePetMgr().AddPet(entry.Id, BattlePetMgr.SelectPetDisplay(entry), BattlePetMgr.RollPetBreed(entry.Id), BattlePetMgr.GetDefaultPetQuality(entry.Id)); UpdateCriteria(CriteriaType.UniquePetsOwned); break; } diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index f35dcb91d..1727d4a43 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -1069,11 +1069,12 @@ namespace Game.Entities SendMessageToSet(cancelSpellVisual, true); } - public void SendPlaySpellVisual(ObjectGuid targetGuid, uint spellVisualId, uint missReason, uint reflectStatus, float travelSpeed, bool speedAsTime = false) + public void SendPlaySpellVisual(Unit target, uint spellVisualId, uint missReason, uint reflectStatus, float travelSpeed, bool speedAsTime = false) { PlaySpellVisual playSpellVisual = new(); playSpellVisual.Source = GetGUID(); - playSpellVisual.Target = targetGuid; // exclusive with TargetPosition + playSpellVisual.Target = target.GetGUID(); + playSpellVisual.TargetPosition = target.GetPosition(); playSpellVisual.SpellVisualID = spellVisualId; playSpellVisual.TravelSpeed = travelSpeed; playSpellVisual.MissReason = (ushort)missReason; @@ -1086,7 +1087,7 @@ namespace Game.Entities { PlaySpellVisual playSpellVisual = new(); playSpellVisual.Source = GetGUID(); - playSpellVisual.TargetPosition = targetPosition; // exclusive with Target + playSpellVisual.TargetPosition = targetPosition; playSpellVisual.LaunchDelay = launchDelay; playSpellVisual.SpellVisualID = spellVisualId; playSpellVisual.TravelSpeed = travelSpeed; diff --git a/Source/Game/Handlers/ItemHandler.cs b/Source/Game/Handlers/ItemHandler.cs index 278e17c8b..5f6d43fa2 100644 --- a/Source/Game/Handlers/ItemHandler.cs +++ b/Source/Game/Handlers/ItemHandler.cs @@ -1067,7 +1067,7 @@ namespace Game var entry = Global.SpellMgr.GetBattlePetSpecies(spellToLearn); if (entry != null) { - GetBattlePetMgr().AddPet(entry.Id, entry.CreatureID, BattlePetMgr.RollPetBreed(entry.Id), BattlePetMgr.GetDefaultPetQuality(entry.Id)); + GetBattlePetMgr().AddPet(entry.Id, BattlePetMgr.SelectPetDisplay(entry), BattlePetMgr.RollPetBreed(entry.Id), BattlePetMgr.GetDefaultPetQuality(entry.Id)); _player.UpdateCriteria(CriteriaType.UniquePetsOwned); } diff --git a/Source/Game/Networking/Packets/BattlePetPackets.cs b/Source/Game/Networking/Packets/BattlePetPackets.cs index 530736348..ab61a3c9f 100644 --- a/Source/Game/Networking/Packets/BattlePetPackets.cs +++ b/Source/Game/Networking/Packets/BattlePetPackets.cs @@ -243,7 +243,7 @@ namespace Game.Networking.Packets data .WritePackedGuid( Guid); data.WriteUInt32(Species); data.WriteUInt32(CreatureID); - data.WriteUInt32(CollarID); + data.WriteUInt32(DisplayID); data.WriteUInt16(Breed); data.WriteUInt16(Level); data.WriteUInt16(Exp); @@ -255,7 +255,7 @@ namespace Game.Networking.Packets data .WriteUInt8( Quality); data.WriteBits(Name.GetByteCount(), 7); data.WriteBit(OwnerInfo.HasValue); // HasOwnerInfo - data.WriteBit(Name.IsEmpty()); // NoRename + data.WriteBit(false); // NoRename data.FlushBits(); data.WriteString(Name); @@ -278,7 +278,7 @@ namespace Game.Networking.Packets public ObjectGuid Guid; public uint Species; public uint CreatureID; - public uint CollarID; + public uint DisplayID; public ushort Breed; public ushort Level; public ushort Exp; diff --git a/Source/Game/Networking/Packets/SpellPackets.cs b/Source/Game/Networking/Packets/SpellPackets.cs index 5c742ec01..381bb5274 100644 --- a/Source/Game/Networking/Packets/SpellPackets.cs +++ b/Source/Game/Networking/Packets/SpellPackets.cs @@ -744,9 +744,9 @@ namespace Game.Networking.Packets } public ObjectGuid Source; - public ObjectGuid Target; // Exclusive with TargetPosition + public ObjectGuid Target; public ObjectGuid Transport; // Used when Target = Empty && (SpellVisual::Flags & 0x400) == 0 - public Vector3 TargetPosition; // Exclusive with Target + public Vector3 TargetPosition; // Overrides missile destination for SpellVisual::SpellVisualMissileSetID public uint SpellVisualID; public float TravelSpeed; public ushort HitReason; diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index cdeefbb2a..ad3b75859 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -5454,47 +5454,42 @@ namespace Game.Spells if (!m_CastItem || !m_caster || !m_caster.IsTypeId(TypeId.Player)) return; - Player plr = m_caster.ToPlayer(); - - // are we allowed to learn battle pets without it? - /*if (plr.HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_PET_BATTLES_UNLOCKED)) - return; // send some error*/ - uint speciesId = m_CastItem.GetModifier(ItemModifier.BattlePetSpeciesId); ushort breed = (ushort)(m_CastItem.GetModifier(ItemModifier.BattlePetBreedData) & 0xFFFFFF); BattlePetBreedQuality quality = (BattlePetBreedQuality)((m_CastItem.GetModifier(ItemModifier.BattlePetBreedData) >> 24) & 0xFF); ushort level = (ushort)m_CastItem.GetModifier(ItemModifier.BattlePetLevel); - uint creatureId = m_CastItem.GetModifier(ItemModifier.BattlePetDisplayId); + uint displayId = m_CastItem.GetModifier(ItemModifier.BattlePetDisplayId); BattlePetSpeciesRecord speciesEntry = CliDB.BattlePetSpeciesStorage.LookupByKey(speciesId); if (speciesEntry == null) return; + Player plr = m_caster.ToPlayer(); BattlePetMgr battlePetMgr = plr.GetSession().GetBattlePetMgr(); if (battlePetMgr == null) return; - // TODO: This means if you put your highest lvl pet into cage, you won't be able to uncage it again which is probably wrong. - // We will need to store maxLearnedLevel somewhere to avoid this behaviour. if (battlePetMgr.GetMaxPetLevel() < level) { - battlePetMgr.SendError(BattlePetError.TooHighLevelToUncage, creatureId); // or speciesEntry.CreatureID + battlePetMgr.SendError(BattlePetError.TooHighLevelToUncage, speciesEntry.CreatureID); SendCastResult(SpellCastResult.CantAddBattlePet); return; } if (battlePetMgr.HasMaxPetCount(speciesEntry)) { - battlePetMgr.SendError(BattlePetError.CantHaveMorePetsOfThatType, creatureId); // or speciesEntry.CreatureID + battlePetMgr.SendError(BattlePetError.CantHaveMorePetsOfThatType, speciesEntry.CreatureID); SendCastResult(SpellCastResult.CantAddBattlePet); return; } - battlePetMgr.AddPet(speciesId, creatureId, breed, quality, level); + battlePetMgr.AddPet(speciesId, displayId, breed, quality, level); if (!plr.HasSpell(speciesEntry.SummonSpellID)) plr.LearnSpell(speciesEntry.SummonSpellID, false); + plr.SendPlaySpellVisual(plr, SharedConst.SpellVisualUncagePet, 0, 0, 0.0f, false); + plr.DestroyItem(m_CastItem.GetBagSlot(), m_CastItem.GetSlot(), true); m_CastItem = null; } diff --git a/sql/updates/auth/master/2021_10_16_00_auth.sql b/sql/updates/auth/master/2021_10_16_00_auth.sql new file mode 100644 index 000000000..c0dfb9a29 --- /dev/null +++ b/sql/updates/auth/master/2021_10_16_00_auth.sql @@ -0,0 +1 @@ +ALTER TABLE `battle_pets` ADD `displayId` int(11) NOT NULL DEFAULT '0' AFTER `breed`;