Esempio n. 1
0
        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;
                    }
                }
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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();
        }