Beispiel #1
0
        public void UpdateCharmAI()
        {
            switch (GetTypeId())
            {
            case TypeId.Unit:
                if (i_disabledAI != null)     // disabled AI must be primary AI
                {
                    if (!IsCharmed())
                    {
                        i_AI         = i_disabledAI;
                        i_disabledAI = null;

                        if (IsTypeId(TypeId.Unit))
                        {
                            ToCreature().GetAI().OnCharmed(false);
                        }
                    }
                }
                else
                {
                    if (IsCharmed())
                    {
                        i_disabledAI = i_AI;
                        if (IsPossessed() || IsVehicle())
                        {
                            i_AI = new PossessedAI(ToCreature());
                        }
                        else
                        {
                            i_AI = new PetAI(ToCreature());
                        }
                    }
                }
                break;

            case TypeId.Player:
            {
                if (IsCharmed())         // if we are currently being charmed, then we should apply charm AI
                {
                    i_disabledAI = i_AI;

                    UnitAI newAI = null;
                    // first, we check if the creature's own AI specifies an override playerai for its owned players
                    Unit charmer = GetCharmer();
                    if (charmer)
                    {
                        Creature creatureCharmer = charmer.ToCreature();
                        if (creatureCharmer)
                        {
                            PlayerAI charmAI = creatureCharmer.IsAIEnabled ? creatureCharmer.GetAI().GetAIForCharmedPlayer(ToPlayer()) : null;
                            if (charmAI != null)
                            {
                                newAI = charmAI;
                            }
                        }
                        else
                        {
                            Log.outError(LogFilter.Misc, "Attempt to assign charm AI to player {0} who is charmed by non-creature {1}.", GetGUID().ToString(), GetCharmerGUID().ToString());
                        }
                    }
                    if (newAI == null)         // otherwise, we default to the generic one
                    {
                        newAI = new SimpleCharmedPlayerAI(ToPlayer());
                    }
                    i_AI = newAI;
                    newAI.OnCharmed(true);
                }
                else
                {
                    if (i_AI != null)
                    {
                        // we allow the charmed PlayerAI to clean up
                        i_AI.OnCharmed(false);
                    }
                    else
                    {
                        Log.outError(LogFilter.Misc, "Attempt to remove charm AI from player {0} who doesn't currently have charm AI.", GetGUID().ToString());
                    }
                    // and restore our previous PlayerAI (if we had one)
                    i_AI         = i_disabledAI;
                    i_disabledAI = null;
                    // IsAIEnabled gets handled in the caller
                }
                break;
            }

            default:
                Log.outError(LogFilter.Misc, "Attempt to update charm AI for unit {0}, which is neither player nor creature.", GetGUID().ToString());
                break;
            }
        }
Beispiel #2
0
        public override bool Execute(ulong e_time, uint p_time)
        {
            Contract.Assert(Passenger.IsInWorld);
            Contract.Assert(Target != null && Target.GetBase().IsInWorld);
            Contract.Assert(Target.GetBase().HasAuraTypeWithCaster(AuraType.ControlVehicle, Passenger.GetGUID()));

            Target.RemovePendingEventsForSeat(Seat.Key);
            Target.RemovePendingEventsForPassenger(Passenger);

            Passenger.SetVehicle(Target);
            Seat.Value.Passenger.Guid           = Passenger.GetGUID();
            Seat.Value.Passenger.IsUnselectable = Passenger.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable);
            if (Seat.Value.SeatInfo.CanEnterOrExit())
            {
                Contract.Assert(Target.UsableSeatNum != 0);
                --Target.UsableSeatNum;
                if (Target.UsableSeatNum == 0)
                {
                    if (Target.GetBase().IsTypeId(TypeId.Player))
                    {
                        Target.GetBase().RemoveFlag64(UnitFields.NpcFlags, NPCFlags.PlayerVehicle);
                    }
                    else
                    {
                        Target.GetBase().RemoveFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick);
                    }
                }
            }

            Passenger.InterruptNonMeleeSpells(false);
            Passenger.RemoveAurasByType(AuraType.Mounted);

            VehicleSeatRecord veSeat = Seat.Value.SeatInfo;

            Player player = Passenger.ToPlayer();

            if (player != null)
            {
                // drop flag
                Battleground bg = player.GetBattleground();
                if (bg)
                {
                    bg.EventPlayerDroppedFlag(player);
                }

                player.StopCastingCharm();
                player.StopCastingBindSight();
                player.SendOnCancelExpectedVehicleRideAura();
                if (!veSeat.Flags[1].HasAnyFlag((uint)VehicleSeatFlagsB.KeepPet))
                {
                    player.UnsummonPetTemporaryIfAny();
                }
            }

            if (Seat.Value.SeatInfo.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.PassengerNotSelectable))
            {
                Passenger.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
            }

            Passenger.m_movementInfo.transport.pos.Relocate(veSeat.AttachmentOffset.X, veSeat.AttachmentOffset.Y, veSeat.AttachmentOffset.Z);
            Passenger.m_movementInfo.transport.time = 0;
            Passenger.m_movementInfo.transport.seat = Seat.Key;
            Passenger.m_movementInfo.transport.guid = Target.GetBase().GetGUID();

            if (Target.GetBase().IsTypeId(TypeId.Unit) && Passenger.IsTypeId(TypeId.Player) &&
                Seat.Value.SeatInfo.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.CanControl))
            {
                Contract.Assert(Target.GetBase().SetCharmedBy(Passenger, CharmType.Vehicle)); // SMSG_CLIENT_CONTROL
            }
            Passenger.SendClearTarget();                                                      // SMSG_BREAK_TARGET
            Passenger.SetControlled(true, UnitState.Root);                                    // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
            // also adds MOVEMENTFLAG_ROOT

            MoveSplineInit init = new MoveSplineInit(Passenger);

            init.DisableTransportPathTransformations();
            init.MoveTo(veSeat.AttachmentOffset.X, veSeat.AttachmentOffset.Y, veSeat.AttachmentOffset.Z, false, true);
            init.SetFacing(0.0f);
            init.SetTransportEnter();
            init.Launch();

            Creature creature = Target.GetBase().ToCreature();

            if (creature != null)
            {
                if (creature.IsAIEnabled)
                {
                    creature.GetAI().PassengerBoarded(Passenger, Seat.Key, true);
                }

                Global.ScriptMgr.OnAddPassenger(Target, Passenger, Seat.Key);

                // Actually quite a redundant hook. Could just use OnAddPassenger and check for unit typemask inside script.
                if (Passenger.HasUnitTypeMask(UnitTypeMask.Accessory))
                {
                    Global.ScriptMgr.OnInstallAccessory(Target, Passenger.ToCreature());
                }
            }

            return(true);
        }
Beispiel #3
0
        public void RemoveCharmedBy(Unit charmer)
        {
            if (!IsCharmed())
            {
                return;
            }

            if (!charmer)
            {
                charmer = GetCharmer();
            }
            if (charmer != GetCharmer()) // one aura overrides another?
            {
                return;
            }

            CharmType type;

            if (HasUnitState(UnitState.Possessed))
            {
                type = CharmType.Possess;
            }
            else if (charmer && charmer.IsOnVehicle(this))
            {
                type = CharmType.Vehicle;
            }
            else
            {
                type = CharmType.Charm;
            }

            CastStop();
            CombatStop(); // @todo CombatStop(true) may cause crash (interrupt spells)
            GetHostileRefManager().DeleteReferences();
            GetThreatManager().ClearAllThreat();

            if (_oldFactionId != 0)
            {
                SetFaction(_oldFactionId);
                _oldFactionId = 0;
            }
            else
            {
                RestoreFaction();
            }

            ///@todo Handle SLOT_IDLE motion resume
            GetMotionMaster().InitDefault();

            Creature creature = ToCreature();

            if (creature)
            {
                // Creature will restore its old AI on next update
                if (creature.GetAI() != null)
                {
                    creature.GetAI().OnCharmed(false);
                }

                // Vehicle should not attack its passenger after he exists the seat
                if (type != CharmType.Vehicle)
                {
                    LastCharmerGUID = charmer ? charmer.GetGUID() : ObjectGuid.Empty;
                }
            }

            // If charmer still exists
            if (!charmer)
            {
                return;
            }

            Cypher.Assert(type != CharmType.Possess || charmer.IsTypeId(TypeId.Player));
            Cypher.Assert(type != CharmType.Vehicle || (IsTypeId(TypeId.Unit) && IsVehicle()));

            charmer.SetCharm(this, false);

            Player playerCharmer = charmer.ToPlayer();

            if (playerCharmer)
            {
                switch (type)
                {
                case CharmType.Vehicle:
                    playerCharmer.SetClientControl(this, false);
                    playerCharmer.SetClientControl(charmer, true);
                    RemoveUnitFlag(UnitFlags.PlayerControlled);
                    break;

                case CharmType.Possess:
                    playerCharmer.SetClientControl(this, false);
                    playerCharmer.SetClientControl(charmer, true);
                    charmer.RemoveUnitFlag(UnitFlags.RemoveClientControl);
                    RemoveUnitFlag(UnitFlags.PlayerControlled);
                    ClearUnitState(UnitState.Possessed);
                    break;

                case CharmType.Charm:
                    if (IsTypeId(TypeId.Unit) && charmer.GetClass() == Class.Warlock)
                    {
                        CreatureTemplate cinfo = ToCreature().GetCreatureTemplate();
                        if (cinfo != null && cinfo.CreatureType == CreatureType.Demon)
                        {
                            SetClass((Class)cinfo.UnitClass);
                            if (GetCharmInfo() != null)
                            {
                                GetCharmInfo().SetPetNumber(0, true);
                            }
                            else
                            {
                                Log.outError(LogFilter.Unit, "Aura:HandleModCharm: target={0} with typeid={1} has a charm aura but no charm info!", GetGUID(), GetTypeId());
                            }
                        }
                    }
                    break;

                case CharmType.Convert:
                    break;
                }
            }

            Player player = ToPlayer();

            if (player)
            {
                if (charmer.IsTypeId(TypeId.Unit)) // charmed by a creature, this means we had PlayerAI
                {
                    NeedChangeAI = true;
                    IsAIEnabled  = false;
                }
                player.SetClientControl(this, true);
            }

            // a guardian should always have charminfo
            if (playerCharmer && this != charmer.GetFirstControlled())
            {
                playerCharmer.SendRemoveControlBar();
            }
            else if (IsTypeId(TypeId.Player) || (IsTypeId(TypeId.Unit) && !IsGuardian()))
            {
                DeleteCharmInfo();
            }
        }