Inheritance: ICritterState
Beispiel #1
0
 static public IObservable <T> BlockReenter <T>(this IObservable <T> self)
 {
     return(Observable.Create <T>(observer =>
     {
         var entered = new EnterState {
             Entered = false
         };
         return self.Subscribe(value =>
         {
             //UnityEngine.Debug.Log(string.Format("BlockReenter: {0}, {1}", entered.GetHashCode(), entered.Entered));
             if (!entered.Entered)
             {
                 entered.Entered = true;
                 try
                 {
                     observer.OnNext(value);
                 }
                 finally
                 {
                     entered.Entered = false;
                 }
             }
         });
     }));
 }
Beispiel #2
0
    protected void StateAdd_Click(object sender, System.EventArgs e)
    {
        EnterState.Validate();
        InvalidState.Validate();

        if (!EnterState.IsValid || !InvalidState.IsValid)
        {
            return;
        }

        DataRow newrow = StateProvincesSet.Tables["StateProvinces"].NewRow();

        newrow["StateProvince"] = NewState.Text;
        try
        {
            newrow["CountryID"] = Convert.ToInt32(CountryList.SelectedValue);

            StateProvincesSet.Tables["StateProvinces"].Rows.Add(newrow);

            //lock (CommonFunctions.Connection)
            StateProvincesAdapter.Update(StateProvincesSet);

            Finish();
        }
        catch (Exception)
        {
        }
    }
Beispiel #3
0
    public void ExitCarAnimEvent()
    {
        enterState = EnterState.outside;

        animator.runtimeAnimatorController = initialActorRuntimeController;
        TurnOnCollisionAnimEvent();
    }
Beispiel #4
0
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释

        /// <summary>
        /// 开始运行
        /// </summary>
        public void Start()
        {
            if (disposed) return;
            if (EnterState == null) throw new Exception("EnterState Is Null");
            enable = true;
            EnterState.OnEnter();
            CurrentState = EnterState;
        }
Beispiel #5
0
 public FiniteStateMachine(ExplicitState initialState)
 {
     initialState.StateMachine = this;
     InitialState = CurrentState = initialState;
     OnEnterState();
     EnterState?.Invoke();
     CurrentState.OnEnter();
 }
Beispiel #6
0
 public void Add(T state, EnterState enter, UpdateState update, ExitState exit)
 {
     states.Add(state, new State
     {
         Enter  = enter,
         Update = update,
         Exit   = exit
     });
 }
        // -- //

        public State(StateMachine stateMachine, string name, EnterState enter, UpdateState update, FixedUpdateState fixedUpdate, ExitState exit)
        {
            this.stateMachine = stateMachine;
            this.name         = name;
            this.enter        = enter;
            this.update       = update;
            this.fixedUpdate  = fixedUpdate;
            this.exit         = exit;
        }
Beispiel #8
0
        public bool addEnterState(string name, EnterState state)
        {
            if (state == null)
            {
                return(false);
            }

            if (m_enterStates.ContainsKey(name))
            {
                return(false);
            }
            m_enterStates[name] = state;
            return(true);
        }
        // -- //

        public State AddState(string name, EnterState enter = null,
                              UpdateState update            = null, FixedUpdateState fixedUpdate = null,
                              ExitState exit = null
                              )
        {
            State newState = new State(this, name, enter, update, fixedUpdate, exit);

            if (currentState == null)
            {
                currentState = newState;
            }

            states.Add(name, newState);

            return(newState);
        }
Beispiel #10
0
 // Cancel inner activity and mark as done unless already leaving or done
 protected void Done(Actor self)
 {
     if (nextState == EnterState.Done)
     {
         return;
     }
     nextState = EnterState.Done;
     if (inner == this)
     {
         inner = null;
     }
     else if (inner != null)
     {
         inner.Cancel(self);
     }
 }
    private void Awake()
    {
        wanderState = new WanderState (this); // huntStart = new HuntState (this); May replace with this
        idleState = new IdleState (this); // huntStart = new HuntState (this); May replace with this
        forageState = new ForageState (this);
        flightState = new FlightState (this);
        pursuitState = new PursuitState (this);
        exitState = new ExitState (this);
        enterState = new EnterState (this);
        navMeshAgent = GetComponent<NavMeshAgent>();

        navMeshAgent.enabled = true;
        // navMeshObstacle.enabled = false;

        navMeshRadius = navMeshAgent.radius;

        navMeshAgent.avoidancePriority = Random.Range(0, 100);  // Randomly set the avoidance priority
    }
Beispiel #12
0
 protected override Validation <string, SitAction> CreateService(
     string key, string displayName, ILoggerFactory loggerFactory)
 {
     return
         (from animation in Prelude.Optional(Animation)
          .ToValidation("Animation was not specified.")
          from statesPath in StatesPath.TrimToOption()
          .ToValidation("States path was not specified.")
          from subStatesPath in SubStatesPath.TrimToOption()
          .ToValidation("Sub-states path was not specified.")
          from idleState in IdleState.TrimToOption()
          .ToValidation("Idle state value was not specified.")
          from enterState in EnterState.TrimToOption()
          .ToValidation("Enter state value was not specified.")
          from state in State.TrimToOption()
          .ToValidation("State path was not specified.")
          from exitState in ExitState.TrimToOption()
          .ToValidation("Exit state value was not specified.")
          from enterAnimatorPath in EnterAnimatorPath.TrimToOption()
          .ToValidation("Enter animator path was not specified.")
          from animatorPath in AnimatorPath.TrimToOption()
          .ToValidation("Animator path was not specified.")
          from exitAnimatorPath in ExitAnimatorPath.TrimToOption()
          .ToValidation("Exit animator path was not specified.")
          select new SitAction(
              key,
              displayName,
              animation,
              statesPath,
              subStatesPath,
              idleState,
              enterState,
              state,
              exitState,
              enterAnimatorPath,
              animatorPath,
              exitAnimatorPath,
              Active,
              loggerFactory)
     {
         SittingDownAnimation = SittingDownAnimation,
         GettingUpAnimation = GettingUpAnimation
     });
 }
Beispiel #13
0
    private void MakeFSM()
    {
        IdleAState idle = new IdleAState(this);
        idle.AddTransition(Transition.FoundMove, StateID.LookA);
        idle.AddTransition(Transition.EnterLevel, StateID.EnterA);
        idle.AddTransition(Transition.IdleDeath, StateID.EnemyDeadA);
        idle.AddTransition(Transition.LaserCollide, StateID.LaserDeadA);
        idle.AddTransition(Transition.CrossTankIdle, StateID.TrapDeadA);

        LookAState look = new LookAState(this);
        look.AddTransition(Transition.EnemyFound, StateID.EnemyDeadA);
        look.AddTransition(Transition.PathFound, StateID.WalkA);
        look.AddTransition(Transition.TrapFound, StateID.TrapDeadA);
        look.AddTransition(Transition.GoalFound, StateID.WinA);

        WalkAState walk = new WalkAState(this);
        walk.AddTransition(Transition.FinishedWalk, StateID.IdleA);
        walk.AddTransition(Transition.EnemyCollide, StateID.EnemyDeadA);
        walk.AddTransition(Transition.SecondMove, StateID.LookA);
        walk.AddTransition(Transition.CrossTank, StateID.TrapDeadA);

        WinAState win = new WinAState(this);
        win.AddTransition(Transition.EnemyCollide1, StateID.EnemyDeadA);

        TrapDeadAState trap = new TrapDeadAState(this);

        EnemyDeadAState enemy = new EnemyDeadAState(this);

        LaserDeadAState laser = new LaserDeadAState(this);

        EnterState enter = new EnterState(this);
        enter.AddTransition(Transition.FinishedEnter, StateID.IdleA);

        fsm = new FSMSystem();
        fsm.AddState(idle);
        fsm.AddState(enter);
        fsm.AddState(look);
        fsm.AddState(walk);
        fsm.AddState(win);
        fsm.AddState(trap);
        fsm.AddState(enemy);
        fsm.AddState(laser);
    }
Beispiel #14
0
 // Abort entering and/or leave if necessary
 protected virtual void AbortOrExit(Actor self)
 {
     if (nextState == EnterState.Done)
     {
         return;
     }
     nextState = isEnteringOrInside ? EnterState.Exiting : EnterState.Done;
     if (inner == this)
     {
         inner = null;
     }
     else if (inner != null)
     {
         inner.Cancel(self);
     }
     if (isEnteringOrInside)
     {
         Unreserve(self, true);
     }
 }
        public State To(string name, Condition switchCondition,
                        EnterState enter             = null, UpdateState update = null,
                        FixedUpdateState fixedUpdate = null, ExitState exit     = null
                        )
        {
            State stateToAdd = stateMachine.GetState(name);

            if (stateToAdd == null)
            {
                stateToAdd = stateMachine.AddState(name, enter, update, fixedUpdate, exit);
            }

            StateOutput output = new StateOutput();

            output.condition = switchCondition;
            output.toState   = stateToAdd;

            outputStates.Add(output);

            return(output.toState);
        }
        public AnyState AnyState(string name, Condition switchCondition,
                                 EnterState enter             = null, UpdateState update = null,
                                 FixedUpdateState fixedUpdate = null, ExitState exit     = null
                                 )
        {
            AnyState stateToAdd = GetState(name) as AnyState;

            if (stateToAdd == null)
            {
                stateToAdd = new AnyState(this, name, enter, update, fixedUpdate, exit);
            }

            StateOutput output = new StateOutput();

            output.condition = switchCondition;
            output.toState   = stateToAdd;

            anyStates.Add(output);
            states.Add(name, stateToAdd);

            return(stateToAdd);
        }
Beispiel #17
0
        public void Transition(ExplicitState toState)
        {
            if (CurrentState == toState)
            {
                return;
            }

            if (toState == null)
            {
                throw new ArgumentNullException("toState");
            }

            OnExitState();
            ExitState?.Invoke();
            CurrentState.OnExit();

            CurrentState = toState;

            OnEnterState();
            EnterState?.Invoke();
            CurrentState.OnEnter();
        }
        // -- //

        public AnyState(StateMachine stateMachine, string name, EnterState enter, UpdateState update, FixedUpdateState fixedUpdate, ExitState exit)
            : base(stateMachine, name, enter, update, fixedUpdate, exit)
        {
        }
Beispiel #19
0
 public static void NotifyEnterState(GameState state)
 {
     EnterState?.Invoke(state);
 }
Beispiel #20
0
 public void EnterCarAnimEvent()
 {
     enterState       = EnterState.inside;
     transform.parent = car;
     Physics.IgnoreCollision(this.gameObject.GetComponent <Collider>(), carCol);
 }
Beispiel #21
0
        EnterState FindAndTransitionToNextState(Actor self)
        {
            switch (nextState)
            {
            case EnterState.ApproachingOrEntering:

                // Reserve to enter or approach
                isEnteringOrInside = false;
                switch (TryReserveElseTryAlternateReserve(self))
                {
                case ReserveStatus.None:
                    return(EnterState.Done);                                    // No available target -> abort to next activity

                case ReserveStatus.TooFar:
                    inner = move.MoveToTarget(self, targetCenter ? Target.FromPos(target.CenterPosition) : target);                                     // Approach
                    return(EnterState.ApproachingOrEntering);

                case ReserveStatus.Pending:
                    return(EnterState.ApproachingOrEntering);                                    // Retry next tick

                case ReserveStatus.Ready:
                    break;                                     // Reserved target -> start entering target
                }

                // Entering
                isEnteringOrInside = true;
                savedPos           = self.CenterPosition;               // Save position of self, before entering, for returning on exit

                inner = move.MoveIntoTarget(self, target);              // Enter

                if (inner != null)
                {
                    nextState = EnterState.Inside;                             // Should be inside once inner activity is null
                    return(EnterState.ApproachingOrEntering);
                }

                // Can enter but there is no activity for it, so go inside without one
                goto case EnterState.Inside;

            case EnterState.Inside:
                // Might as well teleport into target if there is no MoveIntoTarget activity
                if (nextState == EnterState.ApproachingOrEntering)
                {
                    nextState = EnterState.Inside;
                }

                // Otherwise, try to recover from moving target
                else if (target.CenterPosition != self.CenterPosition)
                {
                    nextState = EnterState.ApproachingOrEntering;
                    Unreserve(self, false);
                    if (Reserve(self) == ReserveStatus.Ready)
                    {
                        inner = move.MoveIntoTarget(self, target);                                 // Enter
                        if (inner != null)
                        {
                            return(EnterState.ApproachingOrEntering);
                        }

                        nextState = EnterState.ApproachingOrEntering;
                        goto case EnterState.ApproachingOrEntering;
                    }

                    nextState          = EnterState.ApproachingOrEntering;
                    isEnteringOrInside = false;
                    inner = move.MoveIntoWorld(self, self.World.Map.CellContaining(savedPos));

                    return(EnterState.ApproachingOrEntering);
                }

                OnInside(self);

                if (enterBehaviour == EnterBehaviour.Suicide)
                {
                    self.Kill(self);
                }
                else if (enterBehaviour == EnterBehaviour.Dispose)
                {
                    self.Dispose();
                }

                // Return if Abort(Actor) or Done(self) was called from OnInside.
                if (nextState >= EnterState.Exiting)
                {
                    return(EnterState.Inside);
                }

                inner     = this;                     // Start inside activity
                nextState = EnterState.Exiting;       // Exit once inner activity is null (unless Done(self) is called)
                return(EnterState.Inside);

            // TODO: Handle target moved while inside or always call done for movable targets and use a separate exit activity
            case EnterState.Exiting:
                inner = move.MoveIntoWorld(self, self.World.Map.CellContaining(savedPos));

                // If not successfully exiting, retry on next tick
                if (inner == null)
                {
                    return(EnterState.Exiting);
                }
                isEnteringOrInside = false;
                nextState          = EnterState.Done;
                return(EnterState.Exiting);

            case EnterState.Done:
                return(EnterState.Done);
            }

            return(EnterState.Done);            // dummy to quiet dumb compiler
        }
Beispiel #22
0
        void HandleAreaTrigger(AreaTriggerPkt packet)
        {
            Player player = GetPlayer();

            if (player.IsInFlight())
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' (GUID: {1}) in flight, ignore Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            AreaTriggerRecord atEntry = CliDB.AreaTriggerStorage.LookupByKey(packet.AreaTriggerID);

            if (atEntry == null)
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' (GUID: {1}) send unknown (by DBC) Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (packet.Entered && !player.IsInAreaTriggerRadius(atEntry))
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTrigger: Player '{0}' ({1}) too far, ignore Area Trigger ID: {2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (player.IsDebugAreaTriggers)
            {
                player.SendSysMessage(packet.Entered ? CypherStrings.DebugAreatriggerEntered : CypherStrings.DebugAreatriggerLeft, packet.AreaTriggerID);
            }

            if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
            {
                return;
            }

            if (player.IsAlive())
            {
                List <uint> quests = Global.ObjectMgr.GetQuestsForAreaTrigger(packet.AreaTriggerID);
                if (quests != null)
                {
                    foreach (uint questId in quests)
                    {
                        Quest qInfo = Global.ObjectMgr.GetQuestTemplate(questId);
                        if (qInfo != null && player.GetQuestStatus(questId) == QuestStatus.Incomplete)
                        {
                            foreach (QuestObjective obj in qInfo.Objectives)
                            {
                                if (obj.Type == QuestObjectiveType.AreaTrigger && !player.IsQuestObjectiveComplete(obj))
                                {
                                    player.SetQuestObjectiveData(obj, 1);
                                    player.SendQuestUpdateAddCreditSimple(obj);
                                    break;
                                }
                            }

                            if (player.CanCompleteQuest(questId))
                            {
                                player.CompleteQuest(questId);
                            }
                        }
                    }
                }
            }

            if (Global.ObjectMgr.IsTavernAreaTrigger(packet.AreaTriggerID))
            {
                // set resting flag we are in the inn
                player.GetRestMgr().SetRestFlag(RestFlag.Tavern, atEntry.Id);

                if (Global.WorldMgr.IsFFAPvPRealm())
                {
                    player.RemovePvpFlag(UnitPVPStateFlags.FFAPvp);
                }

                return;
            }
            Battleground bg = player.GetBattleground();

            if (bg)
            {
                bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
            }

            OutdoorPvP pvp = player.GetOutdoorPvP();

            if (pvp != null)
            {
                if (pvp.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered))
                {
                    return;
                }
            }

            AreaTriggerStruct at = Global.ObjectMgr.GetAreaTrigger(packet.AreaTriggerID);

            if (at == null)
            {
                return;
            }

            bool teleported = false;

            if (player.GetMapId() != at.target_mapId)
            {
                EnterState denyReason = Global.MapMgr.PlayerCannotEnter(at.target_mapId, player, false);
                if (denyReason != 0)
                {
                    bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
                    switch (denyReason)
                    {
                    case EnterState.CannotEnterNoEntry:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter map with id {1} which has no entry", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterUninstancedDungeon:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter dungeon map {1} but no instance template was found", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterDifficultyUnavailable:
                    {
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter instance map {1} but the requested difficulty was not found", player.GetName(), at.target_mapId);
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            player.SendTransferAborted(entry.Id, TransferAbortReason.Difficulty, (byte)player.GetDifficultyID(entry));
                        }
                    }
                    break;

                    case EnterState.CannotEnterNotInRaid:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' must be in a raid group to enter map {1}", player.GetName(), at.target_mapId);
                        player.SendRaidGroupOnlyMessage(RaidGroupReason.Only, 0);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterCorpseInDifferentInstance:
                        player.SendPacket(new AreaTriggerNoCorpse());
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterInstanceBindMismatch:
                    {
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            string mapName = entry.MapName[player.GetSession().GetSessionDbcLocale()];
                            Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map '{1}' because their permanent bind is incompatible with their group's", player.GetName(), mapName);
                            // is there a special opcode for this?
                            // @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc)
                            player.SendSysMessage(CypherStrings.InstanceBindMismatch, mapName);
                        }
                        reviveAtTrigger = true;
                    }
                    break;

                    case EnterState.CannotEnterTooManyInstances:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.TooManyInstances);
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map {1} because he has exceeded the maximum number of instances per hour.", player.GetName(), at.target_mapId);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterMaxPlayers:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.MaxPlayers);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterZoneInCombat:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
                        reviveAtTrigger = true;
                        break;

                    default:
                        break;
                    }

                    if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
                    {
                        if (!player.IsAlive() && player.HasCorpse())
                        {
                            if (player.GetCorpseLocation().GetMapId() == at.target_mapId)
                            {
                                player.ResurrectPlayer(0.5f);
                                player.SpawnCorpseBones();
                            }
                        }
                    }

                    return;
                }

                Group group = player.GetGroup();
                if (group)
                {
                    if (group.IsLFGGroup() && player.GetMap().IsDungeon())
                    {
                        teleported = player.TeleportToBGEntryPoint();
                    }
                }
            }

            if (!teleported)
            {
                WorldSafeLocsEntry entranceLocation = null;
                InstanceSave       instanceSave     = player.GetInstanceSave(at.target_mapId);
                if (instanceSave != null)
                {
                    // Check if we can contact the instancescript of the instance for an updated entrance location
                    Map map = Global.MapMgr.FindMap(at.target_mapId, player.GetInstanceSave(at.target_mapId).GetInstanceId());
                    if (map)
                    {
                        InstanceMap instanceMap = map.ToInstanceMap();
                        if (instanceMap != null)
                        {
                            InstanceScript instanceScript = instanceMap.GetInstanceScript();
                            if (instanceScript != null)
                            {
                                entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceScript.GetEntranceLocation());
                            }
                        }
                    }

                    // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
                    if (entranceLocation == null)
                    {
                        entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceSave.GetEntranceLocation());
                    }
                }

                if (entranceLocation != null)
                {
                    player.TeleportTo(entranceLocation.Loc, TeleportToOptions.NotLeaveTransport);
                }
                else
                {
                    player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport);
                }
            }
        }
Beispiel #23
0
        public EnterState PlayerCannotEnter(uint mapid, Player player, bool loginCheck = false)
        {
            MapRecord entry = CliDB.MapStorage.LookupByKey(mapid);

            if (entry == null)
            {
                return(EnterState.CannotEnterNoEntry);
            }

            if (!entry.IsDungeon())
            {
                return(EnterState.CanEnter);
            }

            InstanceTemplate instance = Global.ObjectMgr.GetInstanceTemplate(mapid);

            if (instance == null)
            {
                return(EnterState.CannotEnterUninstancedDungeon);
            }

            Difficulty targetDifficulty = player.GetDifficultyID(entry);
            // Get the highest available difficulty if current setting is higher than the instance allows
            MapDifficultyRecord mapDiff = Global.DB2Mgr.GetDownscaledMapDifficultyData(entry.Id, ref targetDifficulty);

            if (mapDiff == null)
            {
                return(EnterState.CannotEnterDifficultyUnavailable);
            }

            //Bypass checks for GMs
            if (player.IsGameMaster())
            {
                return(EnterState.CanEnter);
            }

            string mapName = entry.MapName[Global.WorldMgr.GetDefaultDbcLocale()];

            Group group = player.GetGroup();

            if (entry.IsRaid() && entry.Expansion() >= (Expansion)WorldConfig.GetIntValue(WorldCfg.Expansion)) // can only enter in a raid group but raids from old expansion don't need a group
            {
                if ((!group || !group.IsRaidGroup()) && WorldConfig.GetBoolValue(WorldCfg.InstanceIgnoreRaid))
                {
                    return(EnterState.CannotEnterNotInRaid);
                }
            }

            if (!player.IsAlive())
            {
                if (player.HasCorpse())
                {
                    // let enter in ghost mode in instance that connected to inner instance with corpse
                    uint corpseMap = player.GetCorpseLocation().GetMapId();
                    do
                    {
                        if (corpseMap == mapid)
                        {
                            break;
                        }

                        InstanceTemplate corpseInstance = Global.ObjectMgr.GetInstanceTemplate(corpseMap);
                        corpseMap = corpseInstance != null ? corpseInstance.Parent : 0;
                    } while (corpseMap != 0);

                    if (corpseMap == 0)
                    {
                        return(EnterState.CannotEnterCorpseInDifferentInstance);
                    }

                    Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' has corpse in instance '{1}' and can enter.", player.GetName(), mapName);
                }
                else
                {
                    Log.outDebug(LogFilter.Maps, "Map.CanPlayerEnter - player '{0}' is dead but does not have a corpse!", player.GetName());
                }
            }

            //Get instance where player's group is bound & its map
            if (!loginCheck && group)
            {
                InstanceBind boundInstance = group.GetBoundInstance(entry);
                if (boundInstance != null && boundInstance.save != null)
                {
                    Map boundMap = FindMap(mapid, boundInstance.save.GetInstanceId());
                    if (boundMap != null)
                    {
                        EnterState denyReason = boundMap.CannotEnter(player);
                        if (denyReason != 0)
                        {
                            return(denyReason);
                        }
                    }
                }
            }
            // players are only allowed to enter 10 instances per hour
            if (entry.IsDungeon() && (player.GetGroup() == null || (player.GetGroup() != null && !player.GetGroup().IsLFGGroup())))
            {
                uint         instaceIdToCheck = 0;
                InstanceSave save             = player.GetInstanceSave(mapid);
                if (save != null)
                {
                    instaceIdToCheck = save.GetInstanceId();
                }

                // instanceId can never be 0 - will not be found
                if (!player.CheckInstanceCount(instaceIdToCheck) && !player.IsDead())
                {
                    return(EnterState.CannotEnterTooManyInstances);
                }
            }

            //Other requirements
            if (player.Satisfy(Global.ObjectMgr.GetAccessRequirement(mapid, targetDifficulty), mapid, true))
            {
                return(EnterState.CanEnter);
            }
            else
            {
                return(EnterState.CannotEnterUnspecifiedReason);
            }
        }
Beispiel #24
0
        public override bool Tick(Actor self)
        {
            // Update our view of the target
            bool targetIsHiddenActor;

            target = target.Recalculate(self.Owner, out targetIsHiddenActor);
            if (!targetIsHiddenActor && target.Type == TargetType.Actor)
            {
                lastVisibleTarget = Target.FromTargetPositions(target);
            }

            var oldUseLastVisibleTarget = useLastVisibleTarget;

            useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self);

            // Cancel immediately if the target died while we were entering it
            if (!IsCanceling && useLastVisibleTarget && lastState == EnterState.Entering)
            {
                Cancel(self, true);
            }

            TickInner(self, target, useLastVisibleTarget);

            // We need to wait for movement to finish before transitioning to
            // the next state or next activity
            if (!TickChild(self))
            {
                return(false);
            }

            // Note that lastState refers to what we have just *finished* doing
            switch (lastState)
            {
            case EnterState.Approaching:
            {
                // NOTE: We can safely cancel in this case because we know the
                // actor has finished any in-progress move activities
                if (IsCanceling)
                {
                    return(true);
                }

                // Lost track of the target
                if (useLastVisibleTarget && lastVisibleTarget.Type == TargetType.Invalid)
                {
                    return(true);
                }

                // We are not next to the target - lets fix that
                if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target))
                {
                    // Target lines are managed by this trait, so we do not pass targetLineColor
                    var initialTargetPosition = (useLastVisibleTarget ? lastVisibleTarget : target).CenterPosition;
                    QueueChild(move.MoveToTarget(self, target, initialTargetPosition));
                    return(false);
                }

                // We are next to where we thought the target should be, but it isn't here
                // There's not much more we can do here
                if (useLastVisibleTarget || target.Type != TargetType.Actor)
                {
                    return(true);
                }

                // Are we ready to move into the target?
                if (TryStartEnter(self, target.Actor))
                {
                    lastState = EnterState.Entering;
                    QueueChild(move.MoveIntoTarget(self, target));
                    return(false);
                }

                // Subclasses can cancel the activity during TryStartEnter
                // Return immediately to avoid an extra tick's delay
                if (IsCanceling)
                {
                    return(true);
                }

                return(false);
            }

            case EnterState.Entering:
            {
                // Check that we reached the requested position
                var targetPos = target.Positions.PositionClosestTo(self.CenterPosition);
                if (!IsCanceling && self.CenterPosition == targetPos && target.Type == TargetType.Actor)
                {
                    OnEnterComplete(self, target.Actor);
                }

                lastState = EnterState.Exiting;
                return(false);
            }

            case EnterState.Exiting:
            {
                QueueChild(move.ReturnToCell(self));
                lastState = EnterState.Finished;
                return(false);
            }
            }

            return(true);
        }