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);
+56 -41
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,40 +494,42 @@ 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 (spellInfo != null) if (!((act_state == ActiveStates.Enabled || act_state == ActiveStates.Disabled || act_state == ActiveStates.Passive) && spell_id != 0 && !petControlled.HasSpell(spell_id)))
{ {
//sign for autocast SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, petControlled.GetMap().GetDifficultyID());
if (act_state == ActiveStates.Enabled) if (spellInfo != null)
{ {
if (pet.GetTypeId() == TypeId.Unit && pet.IsPet()) //sign for autocast
((Pet)pet).ToggleAutocast(spellInfo, true); if (act_state == ActiveStates.Enabled)
else
{ {
foreach (var unit in GetPlayer().m_Controlled) if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet())
if (unit.GetEntry() == pet.GetEntry()) ((Pet)petControlled).ToggleAutocast(spellInfo, true);
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, true); else
{
foreach (var unit in GetPlayer().m_Controlled)
if (unit.GetEntry() == petControlled.GetEntry())
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, true);
}
}
//sign for no/turn off autocast
else if (act_state == ActiveStates.Disabled)
{
if (petControlled.GetTypeId() == TypeId.Unit && petControlled.IsPet())
petControlled.ToPet().ToggleAutocast(spellInfo, false);
else
{
foreach (var unit in GetPlayer().m_Controlled)
if (unit.GetEntry() == petControlled.GetEntry())
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, false);
}
} }
} }
//sign for no/turn off autocast
else if (act_state == ActiveStates.Disabled)
{
if (pet.GetTypeId() == TypeId.Unit && pet.IsPet())
pet.ToPet().ToggleAutocast(spellInfo, false);
else
{
foreach (var unit in GetPlayer().m_Controlled)
if (unit.GetEntry() == pet.GetEntry())
unit.GetCharmInfo().ToggleCreatureAutocast(spellInfo, false);
}
}
}
charmInfo.SetActionBar((byte)position, spell_id, act_state); charmInfo.SetActionBar((byte)position, spell_id, act_state);
}
} }
} }
@@ -623,23 +630,31 @@ namespace Game
return; return;
} }
// do not add not learned spells/ passive spells List<Unit> pets = new();
if (!pet.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable()) foreach (Unit controlled in _player.m_Controlled)
return; if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive())
pets.Add(controlled);
CharmInfo charmInfo = pet.GetCharmInfo(); foreach (Unit petControlled in pets)
if (charmInfo == null)
{ {
Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", pet.GetGUID().ToString()); // do not add not learned spells/ passive spells
return; if (!petControlled.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable())
return;
CharmInfo charmInfo = petControlled.GetCharmInfo();
if (charmInfo == null)
{
Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", petControlled.GetGUID().ToString());
return;
}
if (petControlled.IsPet())
petControlled.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled);
else
charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled);
} }
if (pet.IsPet())
pet.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled);
else
charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled);
} }
[WorldPacketHandler(ClientOpcodes.PetCastSpell, Processing = PacketProcessing.Inplace)] [WorldPacketHandler(ClientOpcodes.PetCastSpell, Processing = PacketProcessing.Inplace)]