Core/Entities: Handle partial state change for pets

Port From (https://github.com/TrinityCore/TrinityCore/commit/0585032c9000386846c506a360eddc09cf069afe)
This commit is contained in:
hondacrx
2021-11-15 23:12:46 -05:00
parent 2aa910e9f6
commit 333179e1e9
2 changed files with 78 additions and 41 deletions
+22
View File
@@ -321,6 +321,28 @@ namespace Game.Entities
base.RemoveFromWorld(); base.RemoveFromWorld();
} }
public override void SetDeathState(DeathState s)
{
base.SetDeathState(s);
if (s != DeathState.JustDied || !IsGuardianPet())
return;
Unit owner = GetOwner();
if (owner == null || !owner.IsPlayer() || owner.GetMinionGUID() != GetGUID())
return;
foreach (Unit controlled in owner.m_Controlled)
{
if (controlled.GetEntry() == GetEntry() && controlled.IsAlive())
{
owner.SetMinionGUID(controlled.GetGUID());
owner.SetPetGUID(controlled.GetGUID());
owner.ToPlayer().CharmSpellInitialize();
break;
}
}
}
public bool IsGuardianPet() public bool IsGuardianPet()
{ {
return IsPet() || (m_Properties != null && m_Properties.Control == SummonCategory.Pet); return IsPet() || (m_Properties != null && m_Properties.Control == SummonCategory.Pet);
+30 -15
View File
@@ -481,6 +481,11 @@ namespace Game
return; return;
} }
List<Unit> pets = new();
foreach (Unit controlled in _player.m_Controlled)
if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive())
pets.Add(controlled);
uint position = packet.Index; uint position = packet.Index;
uint actionData = packet.Action; uint actionData = packet.Action;
@@ -489,34 +494,35 @@ namespace Game
Log.outDebug(LogFilter.Network, "Player {0} has changed pet spell action. Position: {1}, Spell: {2}, State: {3}", GetPlayer().GetName(), position, spell_id, act_state); Log.outDebug(LogFilter.Network, "Player {0} has changed pet spell action. Position: {1}, Spell: {2}, State: {3}", GetPlayer().GetName(), position, spell_id, act_state);
foreach (Unit petControlled in pets)
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
if (!((act_state == ActiveStates.Enabled || act_state == ActiveStates.Disabled || act_state == ActiveStates.Passive) && spell_id != 0 && !pet.HasSpell(spell_id)))
{ {
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, pet.GetMap().GetDifficultyID()); //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
if (!((act_state == ActiveStates.Enabled || act_state == ActiveStates.Disabled || act_state == ActiveStates.Passive) && spell_id != 0 && !petControlled.HasSpell(spell_id)))
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, petControlled.GetMap().GetDifficultyID());
if (spellInfo != null) if (spellInfo != null)
{ {
//sign for autocast //sign for autocast
if (act_state == ActiveStates.Enabled) if (act_state == ActiveStates.Enabled)
{ {
if (pet.GetTypeId() == TypeId.Unit && pet.IsPet()) if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet())
((Pet)pet).ToggleAutocast(spellInfo, true); ((Pet)petControlled).ToggleAutocast(spellInfo, true);
else else
{ {
foreach (var unit in GetPlayer().m_Controlled) foreach (var unit in GetPlayer().m_Controlled)
if (unit.GetEntry() == pet.GetEntry()) if (unit.GetEntry() == petControlled.GetEntry())
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, true); unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, true);
} }
} }
//sign for no/turn off autocast //sign for no/turn off autocast
else if (act_state == ActiveStates.Disabled) else if (act_state == ActiveStates.Disabled)
{ {
if (pet.GetTypeId() == TypeId.Unit && pet.IsPet()) if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet())
pet.ToPet().ToggleAutocast(spellInfo, false); petControlled.ToPet().ToggleAutocast(spellInfo, false);
else else
{ {
foreach (var unit in GetPlayer().m_Controlled) foreach (var unit in GetPlayer().m_Controlled)
if (unit.GetEntry() == pet.GetEntry()) if (unit.GetEntry() == petControlled.GetEntry())
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, false); unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, false);
} }
} }
@@ -525,6 +531,7 @@ namespace Game
charmInfo.SetActionBar((byte)position, spell_id, act_state); charmInfo.SetActionBar((byte)position, spell_id, act_state);
} }
} }
}
[WorldPacketHandler(ClientOpcodes.PetRename)] [WorldPacketHandler(ClientOpcodes.PetRename)]
void HandlePetRename(PetRename packet) void HandlePetRename(PetRename packet)
@@ -623,24 +630,32 @@ namespace Game
return; return;
} }
List<Unit> pets = new();
foreach (Unit controlled in _player.m_Controlled)
if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive())
pets.Add(controlled);
foreach (Unit petControlled in pets)
{
// do not add not learned spells/ passive spells // do not add not learned spells/ passive spells
if (!pet.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable()) if (!petControlled.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable())
return; return;
CharmInfo charmInfo = pet.GetCharmInfo(); CharmInfo charmInfo = petControlled.GetCharmInfo();
if (charmInfo == null) if (charmInfo == null)
{ {
Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", pet.GetGUID().ToString()); Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", petControlled.GetGUID().ToString());
return; return;
} }
if (pet.IsPet()) if (petControlled.IsPet())
pet.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled); petControlled.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled);
else else
charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled); charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled); charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled);
} }
}
[WorldPacketHandler(ClientOpcodes.PetCastSpell, Processing = PacketProcessing.Inplace)] [WorldPacketHandler(ClientOpcodes.PetCastSpell, Processing = PacketProcessing.Inplace)]
void HandlePetCastSpell(PetCastSpell petCastSpell) void HandlePetCastSpell(PetCastSpell petCastSpell)