Ejemplo n.º 1
0
        private bool Tick()
        {
            if (lockCount > 0)
            {
                return(false);
            }

            Actor actor = Queue[0];

            if (actor == null)
            {
                return(false);
            }

            if (currentActorRemoved)
            {
                currentActorRemoved = false;
                return(true);
            }

            while (actor.Energy > 0)
            {
                Profiler.BeginSample("Scheduler: Act()");
                currentActor = actor;
                int actionCost = actor.Act();
                currentActor = null;
                Profiler.EndSample();

                if (currentActorRemoved)
                {
                    currentActorRemoved = false;
                    return(true);
                }

                if (actionCost == 0)
                {
                    UnityEngine.Debug.LogWarning(
                        "A command with 0 energy cost was scheduled.");
                }

                SendActorDebugEvent(actor);

                // Handle asynchronous input by returning -1
                if (actionCost < 0)
                {
                    return(false);
                }

                // An action has just been done
                actor.Energy -= actionCost;
                ActionDoneEvent?.Invoke();

                Profiler.BeginSample("Scheduler: Draw Dirty");
                actor.Entity.Level.Draw(dirtyCells);
                dirtyCells.Clear();
                Profiler.EndSample();

                Profiler.BeginSample("Scheduler: Player");
                if (actor.Control == ActorControl.Player)
                {
                    FOV.RefreshFOV(player.Entity.Level, player.Entity.Cell, true);

                    float speedFactor = actor.Speed / TurnTime;
                    turnProgress += Mathf.FloorToInt(actionCost / speedFactor);
                    if (turnProgress >= TurnTime)
                    {
                        int turnsPassed = turnProgress / TurnTime;
                        turns        += turnsPassed;
                        turnProgress %= TurnTime;

                        for (int i = 0; i < turnsPassed; i++)
                        {
                            ClockTickEvent?.Invoke();
                        }

                        TimeChangeEvent?.Invoke(turns);
                    }
                    // Signals a successful player action to HUD
                    PlayerActionEvent?.Invoke(actor.Energy);
                }
                Profiler.EndSample();
                // Action may have added a lock
                if (lockCount > 0)
                {
                    return(false);
                }
            }
            // Give the actor their speed value's worth of energy back
            actor.Energy += actor.Speed;

            // Update HUD again to reflect refill
            if (actor.Control == ActorControl.Player)
            {
                PlayerActionEvent?.Invoke(actor.Energy);
            }

            Actor dequeued = Queue[0];

            Queue.RemoveAt(0);
            Queue.Add(dequeued);

            return(true);
        }
Ejemplo n.º 2
0
        private bool Tick()
        {
            if (lockCount > 0)
            {
                return(false);
            }

            Actor actor = Queue[0];

            if (actor == null)
            {
                return(false);
            }

            if (currentActorRemoved)
            {
                currentActorRemoved = false;
                return(true);
            }

            Profiler.BeginSample("Scheduler: Act");
            if (actor.Control == ActorControl.Player)
            {
                currentActor = actor;
                int actionCost = actor.Act();
                currentActor = null;

                // Handle asynchronous input by returning -1
                if (actionCost < 0)
                {
                    Profiler.EndSample();
                    return(false);
                }

                timeConsumed = actionCost;
                time        += timeConsumed;
                TimeChangeEvent?.Invoke(time, timeConsumed);
                turnProgress += Mathf.FloorToInt(actionCost);
                if (turnProgress >= TurnTime)
                {
                    int turnsPassed = turnProgress / TurnTime;
                    turnProgress %= TurnTime;

                    for (int i = 0; i < turnsPassed; i++)
                    {
                        ClockTickEvent?.Invoke();
                    }
                }
                FOV.RefreshFOV(player.Entity.Level, player.Entity.Cell, true);
            }
            else // TODO: Handle ActorControl.None
            {
                if (actor.Command == null)
                {
                    actor.Entity.GetComponent <AI>().DecideCommand();
                }

                actor.Progress += timeConsumed;
                if (actor.Progress >= actor.Threshold)
                {
                    currentActor = actor;
                    actor.Act();
                    currentActor   = null;
                    actor.Progress = 0;
                }
            }
            Profiler.EndSample();

            if (currentActorRemoved)
            {
                currentActorRemoved = false;
                return(true);
            }

            SendActorDebugEvent(actor);

            Profiler.BeginSample("Scheduler: Draw Dirty");
            RedrawDirtyCells(actor.Entity.Level);
            Profiler.EndSample();

            Actor dequeued = Queue[0];

            Queue.RemoveAt(0);
            Queue.Add(dequeued);

            return(true);
        }