public void SetMinion(Minion minion, bool apply) { Log.outDebug(LogFilter.Unit, "SetMinion {0} for {1}, apply {2}", minion.GetEntry(), GetEntry(), apply); if (apply) { if (!minion.GetOwnerGUID().IsEmpty()) { Log.outFatal(LogFilter.Unit, "SetMinion: Minion {0} is not the minion of owner {1}", minion.GetEntry(), GetEntry()); return; } minion.SetOwnerGUID(GetGUID()); m_Controlled.Add(minion); if (IsTypeId(TypeId.Player)) { minion.m_ControlledByPlayer = true; minion.SetFlag(UnitFields.Flags, UnitFlags.PvpAttackable); } // Can only have one pet. If a new one is summoned, dismiss the old one. if (minion.IsGuardianPet()) { Guardian oldPet = GetGuardianPet(); if (oldPet) { if (oldPet != minion && (oldPet.IsPet() || minion.IsPet() || oldPet.GetEntry() != minion.GetEntry())) { // remove existing minion pet if (oldPet.IsPet()) { ((Pet)oldPet).Remove(PetSaveMode.AsCurrent); } else { oldPet.UnSummon(); } SetPetGUID(minion.GetGUID()); SetMinionGUID(ObjectGuid.Empty); } } else { SetPetGUID(minion.GetGUID()); SetMinionGUID(ObjectGuid.Empty); } } if (minion.HasUnitTypeMask(UnitTypeMask.Guardian)) { AddGuidValue(UnitFields.Summon, minion.GetGUID()); } if (minion.m_Properties != null && minion.m_Properties.Type == SummonType.Minipet) { SetCritterGUID(minion.GetGUID()); if (GetTypeId() == TypeId.Player) { minion.SetGuidValue(UnitFields.BattlePetCompanionGuid, GetGuidValue(PlayerFields.SummonedBattlePetId)); } } // PvP, FFAPvP minion.SetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, GetByteValue(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag)); // FIXME: hack, speed must be set only at follow if (IsTypeId(TypeId.Player) && minion.IsPet()) { for (UnitMoveType i = 0; i < UnitMoveType.Max; ++i) { minion.SetSpeedRate(i, m_speed_rate[(int)i]); } } // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.GetUInt32Value(UnitFields.CreatedBySpell)); if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent()) { GetSpellHistory().StartCooldown(spellInfo, 0, null, true); } } else { if (minion.GetOwnerGUID() != GetGUID()) { Log.outFatal(LogFilter.Unit, "SetMinion: Minion {0} is not the minion of owner {1}", minion.GetEntry(), GetEntry()); return; } m_Controlled.Remove(minion); if (minion.m_Properties != null && minion.m_Properties.Type == SummonType.Minipet) { if (GetCritterGUID() == minion.GetGUID()) { SetCritterGUID(ObjectGuid.Empty); } } if (minion.IsGuardianPet()) { if (GetPetGUID() == minion.GetGUID()) { SetPetGUID(ObjectGuid.Empty); } } else if (minion.IsTotem()) { // All summoned by totem minions must disappear when it is removed. SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell()); if (spInfo != null) { foreach (SpellEffectInfo effect in spInfo.GetEffectsForDifficulty(Difficulty.None)) { if (effect == null || effect.Effect != SpellEffectName.Summon) { continue; } RemoveAllMinionsByEntry((uint)effect.MiscValue); } } } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.GetUInt32Value(UnitFields.CreatedBySpell)); // Remove infinity cooldown if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent()) { GetSpellHistory().SendCooldownEvent(spellInfo); } if (RemoveGuidValue(UnitFields.Summon, minion.GetGUID())) { // Check if there is another minion foreach (var unit in m_Controlled) { // do not use this check, creature do not have charm guid if (GetGUID() == unit.GetCharmerGUID()) { continue; } Contract.Assert(unit.GetOwnerGUID() == GetGUID()); if (unit.GetOwnerGUID() != GetGUID()) { Contract.Assert(false); } Contract.Assert(unit.IsTypeId(TypeId.Unit)); if (!unit.HasUnitTypeMask(UnitTypeMask.Guardian)) { continue; } if (AddGuidValue(UnitFields.Summon, unit.GetGUID())) { // show another pet bar if there is no charm bar if (IsTypeId(TypeId.Player) && GetCharmGUID().IsEmpty()) { if (unit.IsPet()) { ToPlayer().PetSpellInitialize(); } else { ToPlayer().CharmSpellInitialize(); } } } break; } } } }
public TempSummon SummonPassenger(uint entry, Position pos, TempSummonType summonType, SummonPropertiesRecord properties = null, uint duration = 0, Unit summoner = null, uint spellId = 0, uint vehId = 0) { Map map = GetMap(); if (map == null) { return(null); } UnitTypeMask mask = UnitTypeMask.Summon; if (properties != null) { switch (properties.Control) { case SummonCategory.Pet: mask = UnitTypeMask.Guardian; break; case SummonCategory.Puppet: mask = UnitTypeMask.Puppet; break; case SummonCategory.Vehicle: mask = UnitTypeMask.Minion; break; case SummonCategory.Wild: case SummonCategory.Ally: case SummonCategory.Unk: { switch (properties.Title) { case SummonType.Minion: case SummonType.Guardian: case SummonType.Guardian2: mask = UnitTypeMask.Guardian; break; case SummonType.Totem: case SummonType.LightWell: mask = UnitTypeMask.Totem; break; case SummonType.Vehicle: case SummonType.Vehicle2: mask = UnitTypeMask.Summon; break; case SummonType.Minipet: mask = UnitTypeMask.Minion; break; default: if (properties.Flags.HasAnyFlag(SummonPropFlags.Unk10)) // Mirror Image, Summon Gargoyle { mask = UnitTypeMask.Guardian; } break; } break; } default: return(null); } } TempSummon summon = null; switch (mask) { case UnitTypeMask.Summon: summon = new TempSummon(properties, summoner, false); break; case UnitTypeMask.Guardian: summon = new Guardian(properties, summoner, false); break; case UnitTypeMask.Puppet: summon = new Puppet(properties, summoner); break; case UnitTypeMask.Totem: summon = new Totem(properties, summoner); break; case UnitTypeMask.Minion: summon = new Minion(properties, summoner, false); break; } float x, y, z, o; pos.GetPosition(out x, out y, out z, out o); CalculatePassengerPosition(ref x, ref y, ref z, ref o); if (!summon.Create(map.GenerateLowGuid(HighGuid.Creature), map, entry, x, y, z, o, null, vehId)) { return(null); } PhasingHandler.InheritPhaseShift(summon, summoner ? (WorldObject)summoner : this); summon.SetUInt32Value(UnitFields.CreatedBySpell, spellId); summon.SetTransport(this); summon.m_movementInfo.transport.guid = GetGUID(); summon.m_movementInfo.transport.pos.Relocate(pos); summon.Relocate(x, y, z, o); summon.SetHomePosition(x, y, z, o); summon.SetTransportHomePosition(pos); // @HACK - transport models are not added to map's dynamic LoS calculations // because the current GameObjectModel cannot be moved without recreating summon.AddUnitState(UnitState.IgnorePathfinding); summon.InitStats(duration); if (!map.AddToMap(summon)) { return(null); } _staticPassengers.Add(summon); summon.InitSummon(); summon.SetTempSummonType(summonType); return(summon); }
public void SetMinion(Minion minion, bool apply) { Log.outDebug(LogFilter.Unit, "SetMinion {0} for {1}, apply {2}", minion.GetEntry(), GetEntry(), apply); if (apply) { if (!minion.GetOwnerGUID().IsEmpty()) { Log.outFatal(LogFilter.Unit, "SetMinion: Minion {0} is not the minion of owner {1}", minion.GetEntry(), GetEntry()); return; } minion.SetOwnerGUID(GetGUID()); if (!m_Controlled.Contains(minion)) { m_Controlled.Add(minion); } if (IsTypeId(TypeId.Player)) { minion.m_ControlledByPlayer = true; minion.AddUnitFlag(UnitFlags.PlayerControlled); } // Can only have one pet. If a new one is summoned, dismiss the old one. if (minion.IsGuardianPet()) { Guardian oldPet = GetGuardianPet(); if (oldPet) { if (oldPet != minion && (oldPet.IsPet() || minion.IsPet() || oldPet.GetEntry() != minion.GetEntry())) { // remove existing minion pet if (oldPet.IsPet()) { ((Pet)oldPet).Remove(PetSaveMode.AsCurrent); } else { oldPet.UnSummon(); } SetPetGUID(minion.GetGUID()); SetMinionGUID(ObjectGuid.Empty); } } else { SetPetGUID(minion.GetGUID()); SetMinionGUID(ObjectGuid.Empty); } } if (minion.HasUnitTypeMask(UnitTypeMask.Guardian)) { if (GetMinionGUID().IsEmpty()) { SetMinionGUID(minion.GetGUID()); } } var properties = minion.m_Properties; if (properties != null && properties.Title == SummonTitle.Companion) { SetCritterGUID(minion.GetGUID()); Player thisPlayer = ToPlayer(); if (thisPlayer != null) { if (properties.GetFlags().HasFlag(SummonPropertiesFlags.SummonFromBattlePetJournal)) { var pet = thisPlayer.GetSession().GetBattlePetMgr().GetPet(thisPlayer.GetSummonedBattlePetGUID()); if (pet != null) { minion.SetBattlePetCompanionGUID(thisPlayer.GetSummonedBattlePetGUID()); minion.SetBattlePetCompanionNameTimestamp((uint)pet.NameTimestamp); minion.SetWildBattlePetLevel(pet.PacketInfo.Level); uint display = pet.PacketInfo.DisplayID; if (display != 0) { minion.SetDisplayId(display); minion.SetNativeDisplayId(display); } } } } } // PvP, FFAPvP minion.SetPvpFlags(GetPvpFlags()); // FIXME: hack, speed must be set only at follow if (IsTypeId(TypeId.Player) && minion.IsPet()) { for (UnitMoveType i = 0; i < UnitMoveType.Max; ++i) { minion.SetSpeedRate(i, m_speed_rate[(int)i]); } } // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell, GetMap().GetDifficultyID()); if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent()) { GetSpellHistory().StartCooldown(spellInfo, 0, null, true); } } else { if (minion.GetOwnerGUID() != GetGUID()) { Log.outFatal(LogFilter.Unit, "SetMinion: Minion {0} is not the minion of owner {1}", minion.GetEntry(), GetEntry()); return; } m_Controlled.Remove(minion); if (minion.m_Properties != null && minion.m_Properties.Title == SummonTitle.Companion) { if (GetCritterGUID() == minion.GetGUID()) { SetCritterGUID(ObjectGuid.Empty); } } if (minion.IsGuardianPet()) { if (GetPetGUID() == minion.GetGUID()) { SetPetGUID(ObjectGuid.Empty); } } else if (minion.IsTotem()) { // All summoned by totem minions must disappear when it is removed. SpellInfo spInfo = Global.SpellMgr.GetSpellInfo(minion.ToTotem().GetSpell(), GetMap().GetDifficultyID()); if (spInfo != null) { foreach (var spellEffectInfo in spInfo.GetEffects()) { if (spellEffectInfo == null || !spellEffectInfo.IsEffect(SpellEffectName.Summon)) { continue; } RemoveAllMinionsByEntry((uint)spellEffectInfo.MiscValue); } } } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(minion.m_unitData.CreatedBySpell, GetMap().GetDifficultyID()); // Remove infinity cooldown if (spellInfo != null && spellInfo.IsCooldownStartedOnEvent()) { GetSpellHistory().SendCooldownEvent(spellInfo); } if (GetMinionGUID() == minion.GetGUID()) { SetMinionGUID(ObjectGuid.Empty); // Check if there is another minion foreach (var unit in m_Controlled) { // do not use this check, creature do not have charm guid if (GetGUID() == unit.GetCharmerGUID()) { continue; } Cypher.Assert(unit.GetOwnerGUID() == GetGUID()); if (unit.GetOwnerGUID() != GetGUID()) { Cypher.Assert(false); } Cypher.Assert(unit.IsTypeId(TypeId.Unit)); if (!unit.HasUnitTypeMask(UnitTypeMask.Guardian)) { continue; } SetMinionGUID(unit.GetGUID()); // show another pet bar if there is no charm bar if (GetTypeId() == TypeId.Player && GetCharmedGUID().IsEmpty()) { if (unit.IsPet()) { ToPlayer().PetSpellInitialize(); } else { ToPlayer().CharmSpellInitialize(); } } break; } } } UpdatePetCombatState(); }