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; } } }); })); }
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) { } }
public void ExitCarAnimEvent() { enterState = EnterState.outside; animator.runtimeAnimatorController = initialActorRuntimeController; TurnOnCollisionAnimEvent(); }
#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; }
public FiniteStateMachine(ExplicitState initialState) { initialState.StateMachine = this; InitialState = CurrentState = initialState; OnEnterState(); EnterState?.Invoke(); CurrentState.OnEnter(); }
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; }
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); }
// 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 }
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 }); }
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); }
// 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); }
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) { }
public static void NotifyEnterState(GameState state) { EnterState?.Invoke(state); }
public void EnterCarAnimEvent() { enterState = EnterState.inside; transform.parent = car; Physics.IgnoreCollision(this.gameObject.GetComponent <Collider>(), carCol); }
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 }
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); } } }
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); } }
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); }