예제 #1
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            bool hasAssignment = this.CurrentAssignment != null;
            bool hasOtherAssignment = this.CurrentAssignment == null && this.Worker.HasAction;

            if (priority == ActionPriority.High)
            {
                if (m_priorityAction)
                    return this.CurrentAssignment;

                return this.CurrentAssignment;
            }
            else if (priority == ActionPriority.Idle)
            {
                if (hasOtherAssignment)
                    return null;

                if (m_priorityAction)
                    return this.CurrentAssignment;

                if (hasAssignment)
                    return this.CurrentAssignment;

                return new Dwarrowdelf.Jobs.Assignments.RandomMoveAssignment(null);
            }
            else
            {
                throw new Exception();
            }
        }
예제 #2
0
        IAssignment CreateSleepAssignmentIfNeeded(ILivingObject worker, ActionPriority priority)
        {
            if (priority == ActionPriority.High && worker.Exhaustion < 500)
            {
                return(null);
            }

            if (priority == ActionPriority.Idle && worker.Exhaustion < 100)
            {
                return(null);
            }

            var env = worker.Environment;

            var ob = env.Contents
                     .OfType <IItemObject>()
                     .Where(o => o.ItemID == ItemID.Bed)
                     .Where(o => o.IsReserved == false && o.IsInstalled)
                     .OrderBy(o => (o.Location - worker.Location).ManhattanLength)
                     .Where(o => AStar.CanReach(env, worker.Location, o.Location, DirectionSet.Exact))
                     .FirstOrDefault();

            if (ob != null)
            {
                m_priorityAction = true;
                var job = new MoveSleepAssignment(this, ob);
                ob.ReservedBy = this;
                return(job);
            }

            return(null);
        }
예제 #3
0
 public DeferredAction(UnityEngine.Object sender, Action action, ActionPriority priority = 2)
 {
     this.sender   = sender;
     this.action   = action;
     this.priority = priority;
     this.Idle     = true;
 }
예제 #4
0
        GameAction IAI.DecideAction(ActionPriority priority)
        {
            if (this.Worker.HasAction)
            {
                if (this.Worker.ActionPriority > priority)
                {
                    return(this.Worker.CurrentAction);
                }

                if (m_currentAction != null && this.Worker.CurrentAction.GUID == m_currentAction.GUID)
                {
                    return(this.Worker.CurrentAction);
                }
            }

            if (m_actions.Count == 0)
            {
                if (this.Worker.CurrentAction != null)
                {
                    return(this.Worker.CurrentAction);
                }

                return(null);
            }

            m_currentAction = m_actions[0];

            var actionID = m_actionIDCounter++;

            m_currentAction.GUID = new ActionGUID(m_playerID, actionID);

            return(m_currentAction);
        }
예제 #5
0
        void SetCurrentAssignment(IAssignment assignment, ActionPriority priority)
        {
            if (m_currentAssignment == assignment && m_currentPriority == priority)
            {
                return;
            }

            if (m_currentAssignment != null)
            {
                m_currentAssignment.StatusChanged -= OnJobStatusChanged;
            }

            m_currentAssignment = assignment;
            m_currentPriority   = priority;

            if (m_currentAssignment != null)
            {
                m_currentAssignment.StatusChanged += OnJobStatusChanged;
            }

            if (AssignmentChanged != null)
            {
                AssignmentChanged(assignment);
            }
        }
예제 #6
0
 public DeferredAction(Object sender, Action action, ActionPriority priority = ActionPriority.Medium)
 {
     this.sender   = sender;
     this.action   = action;
     this.priority = priority;
     this.Idle     = true;
 }
예제 #7
0
        public void StartAction(GameAction action, ActionPriority priority)
        {
            D("DoAction: {0}", action);

            Debug.Assert(!this.HasAction);
            Debug.Assert(priority != ActionPriority.Undefined);
            Debug.Assert(action.GUID.IsNull == false);

            this.CurrentAction    = action;
            this.ActionPriority   = priority;
            this.ActionTotalTicks = 0;
            this.ActionTicksUsed  = 0;

            var e = new ActionStartEvent()
            {
                Action   = action,
                Priority = priority,
            };

            if (m_ai != null)
            {
                m_ai.ActionStarted(e);
            }

            var c = new ActionStartedChange(this)
            {
                ActionStartEvent = e,
            };

            this.World.AddChange(c);
        }
 public ActionListElement(Action action, ActionPriority priority, object owner, bool isExpensiveOperation)
 {
     Action = action;
     Priority = priority;
     Owner = owner;
     IsExpensiveOperation = isExpensiveOperation;
 }
예제 #9
0
        void DecideAction(ActionPriority priority)
        {
            var action = m_ai.DecideAction(priority);

            if (action != this.CurrentAction)
            {
                // XXX Our AIs don't currently cancel their own actions, so have an assert here for now
                Debug.Assert(action != null);

                if (this.HasAction)
                {
                    if (action != null && this.ActionPriority > priority)
                    {
                        throw new Exception();
                    }

                    CancelAction();
                }

                if (action != null)
                {
                    StartAction(action, priority);
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Action object represents an action performed by something (player, npc, room, etc) on another something (player, npc, room, etc)
 /// </summary>
 /// <param name="sender">The entity performing the object, usually a player entering a command</param>
 /// <param name="action">The ActionType is the Enum that cooresponds to the Action, (A ChangeAction object will have ActionType.CHANGE)</param>
 /// <param name="element">The receiving end of the action, the target element</param>
 /// <param name="elementName">The name of the target GameElement (Player, npc, channel etc)</param>
 /// <param name="priority">The priority of this action (not currently implemented)</param>
 public ActionObject(string sender, ActionType action, ElementType element, string elementName, ActionPriority priority)
 {
     Sender      = sender;
     ActionType  = action;
     ElementType = element;
     ElementName = elementName;
     Priority    = priority;
 }
예제 #11
0
 public bool Remove(T action, ActionPriority priority = ActionPriority.regular)
 {
     if (action == null)
     {
         throw ExceptionHelper.Invalid(nameof(action), null, InvalidType.isNull);
     }
     return(GetDelegatesList(priority, false)?.RemoveIgnoreOrder(action) == true);
 }
예제 #12
0
 public void AddAction(ActionBase action, ActionPriority priority = ActionPriority.Normal)
 {
     if (action == null)
     {
         throw new ArgumentNullException(nameof(action));
     }
     actions.Add(new ActionWithPriorityWrapper(action, priority));
 }
예제 #13
0
 public static AsyncActionUpdate Create(PlaceholderAction placeholder, ActionPriority priority, Func <ActionUpdateResult> task)
 {
     return(new AsyncActionUpdate(placeholder, priority,
                                  Task.Run <ActionUpdateResult>(() =>
     {
         return task();
     })
                                  ));
 }
예제 #14
0
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            switch (this.State)
            {
            case DwarfState.Working:
            {
                Debug.Assert(m_target == null);

                m_target = AIHelpers.FindNearestEnemy(this.Worker, LivingCategory.Monster);

                if (m_target == null)
                {
                    // continue doing work

                    if (this.CurrentAssignment != null)
                    {
                        return(this.CurrentAssignment);
                    }

                    return(this.JobManager.FindAssignment(this.Worker));
                }

                this.State = DwarfState.Fighting;

                trace.TraceInformation("Found target: {0}", m_target);

                if (this.CurrentAssignment == null || (this.CurrentAssignment is AttackAssignment) == false)
                {
                    trace.TraceInformation("Start attacking: {0}", m_target);

                    var assignment = new AttackAssignment(this, m_target);
                    return(assignment);
                }
                else
                {
                    trace.TraceInformation("Continue attacking: {0}", m_target);
                    return(this.CurrentAssignment);
                }
            }

            case DwarfState.Fighting:
                if (m_target.IsDestructed)
                {
                    return(null);
                }

                Debug.Assert(this.CurrentAssignment != null);

                trace.TraceInformation("Continue attacking: {0}", m_target);

                return(this.CurrentAssignment);

            default:
                throw new Exception();
            }
        }
예제 #15
0
    /*
     *  @brief	優先度を参照して変更するか決める
     */
    public bool    runFromPrority(ActionId in_id, object in_obj)
    {
        ActionPriority priority = ActionPriority.eNORMAL;

        if (m_runAction != null)
        {
            priority = m_runAction.priority;
        }

        return(run(in_id, in_obj, priority));
    }
예제 #16
0
 public void Add(T action, ActionPriority priority = ActionPriority.regular)
 {
     if (action != null)
     {
         GetDelegatesList(priority, true).Add(action);
     }
     else
     {
         throw ExceptionHelper.Invalid(nameof(action), null, InvalidType.isNull);
     }
 }
예제 #17
0
    /*
     *  @brief	指定したアクション実行
     */
    private bool    run(ActionId in_id, object in_obj, ActionPriority in_priority)
    {
        if ((m_runAction != null) && (m_runAction.id == in_id))
        {
            //	同じアクションは実行できない
            //		Debug.Log("error: running: " + m_runAction + " = " + in_id);
            return(false);
        }

        bool       bRun   = false;
        BaseAction action = null;

        foreach (ActionList.DataAction dataAct in m_actionlist.dataList)
        {
            action = dataAct.action;
            if ((action != null) && (action.id == in_id))
            {
                break;
            }
        }

        if ((action != null) && (action.isAction(ref m_player)))
        {
            bRun = true;
            if (m_runAction != null)
            {
                //	変更アクションの優先度が実行アクションの優先度未満だと実行できない
                if (in_priority <= action.priority)
                {
                    m_runAction.finalize();
                }
                else
                {
                    bRun = false;
                }
            }

            if (bRun == true)
            {
                if (action.initialize(ref m_player, in_obj))
                {
                    m_runAction = action;
                    //			Debug.Log ("change action: " + action);

                    return(true);
                }
            }
        }

        //	Debug.Log ("error: runAction= " + in_id);

        return(false);
    }
예제 #18
0
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            switch (this.State)
            {
                case DwarfState.Working:
                    {
                        Debug.Assert(m_target == null);

                        m_target = AIHelpers.FindNearestEnemy(this.Worker, LivingCategory.Monster);

                        if (m_target == null)
                        {
                            // continue doing work

                            if (this.CurrentAssignment != null)
                                return this.CurrentAssignment;

                            return this.JobManager.FindAssignment(this.Worker);
                        }

                        this.State = DwarfState.Fighting;

                        trace.TraceInformation("Found target: {0}", m_target);

                        if (this.CurrentAssignment == null || (this.CurrentAssignment is AttackAssignment) == false)
                        {
                            trace.TraceInformation("Start attacking: {0}", m_target);

                            var assignment = new AttackAssignment(this, m_target);
                            return assignment;
                        }
                        else
                        {
                            trace.TraceInformation("Continue attacking: {0}", m_target);
                            return this.CurrentAssignment;
                        }
                    }

                case DwarfState.Fighting:
                    if (m_target.IsDestructed)
                        return null;

                    Debug.Assert(this.CurrentAssignment != null);

                    trace.TraceInformation("Continue attacking: {0}", m_target);

                    return this.CurrentAssignment;

                default:
                    throw new Exception();
            }
        }
예제 #19
0
        protected List <T> GetDelegatesList(ActionPriority priority, bool generate)
        {
            switch (priority)
            {
            case ActionPriority.primary: return(GetList(ref primaryActions));

            case ActionPriority.regular: return(GetList(ref regularActions));

            case ActionPriority.delayed: return(GetList(ref delayedActions));
            }

            throw ExceptionHelper.Invalid(nameof(priority), priority, InvalidType.unexpected);
            List <T> GetList(ref List <T> list) => generate && list == null ? list = new List <T>() : list;
        }
예제 #20
0
        private AsyncActionUpdate(PlaceholderAction placeholder, ActionPriority priority, Task <ActionUpdateResult> updateTask)
        {
            if (placeholder == null)
            {
                throw new ArgumentNullException(nameof(placeholder));
            }

            Priority    = priority;
            Placeholder = placeholder;
            UpdateTask  = updateTask;
            if (UpdateTask.Status == TaskStatus.Created)
            {
                UpdateTask.Start();
            }
        }
예제 #21
0
 public UserAction(string name, ActionPriority priority, Button button, List <Button> combos, int comboGoal, System.Action doAction, float pressDuration = defaultDuration)
 {
     this.name        = name;
     this.priority    = priority;
     this.button      = button;
     this.combos      = combos;
     this.comboGoal   = comboGoal;
     this.actualCombo = 0;
     if (this.combos != null)
     {
         this.comboBuffer = new List <Button>(combos);
     }
     this.pressDuration  = pressDuration;
     this.actualDuration = 0f;
     this.doAction       = doAction;
     this.progression    = 0f;
 }
예제 #22
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            if (priority == ActionPriority.Idle)
            {
                return(this.CurrentAssignment);
            }

            if (m_target == null)
            {
                m_target = AIHelpers.FindNearestEnemy(this.Worker, LivingCategory.Civilized);

                if (m_target == null)
                {
                    // continue patrolling
                    if (this.CurrentAssignment == null || (this.CurrentAssignment is RandomMoveAssignment) == false)
                    {
                        trace.TraceInformation("Start random move");
                        return(new RandomMoveAssignment(null));
                    }
                    else
                    {
                        trace.TraceVerbose("Continue patrolling");
                        return(this.CurrentAssignment);
                    }
                }

                trace.TraceInformation("Found target: {0}", m_target);
            }

            Debug.Assert(m_target != null);

            if (this.CurrentAssignment == null || (this.CurrentAssignment is AttackAssignment) == false)
            {
                trace.TraceInformation("Start attacking: {0}", m_target);

                var assignment = new AttackAssignment(this, m_target);
                return(assignment);
            }
            else
            {
                trace.TraceInformation("Continue attacking: {0}", m_target);
                return(this.CurrentAssignment);
            }
        }
예제 #23
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            if (priority == ActionPriority.Idle)
                return this.CurrentAssignment;

            if (m_target == null)
            {
                m_target = AIHelpers.FindNearestEnemy(this.Worker, LivingCategory.Civilized);

                if (m_target == null)
                {
                    // continue patrolling
                    if (this.CurrentAssignment == null || (this.CurrentAssignment is RandomMoveAssignment) == false)
                    {
                        trace.TraceInformation("Start random move");
                        return new RandomMoveAssignment(null);
                    }
                    else
                    {
                        trace.TraceVerbose("Continue patrolling");
                        return this.CurrentAssignment;
                    }
                }

                trace.TraceInformation("Found target: {0}", m_target);
            }

            Debug.Assert(m_target != null);

            if (this.CurrentAssignment == null || (this.CurrentAssignment is AttackAssignment) == false)
            {
                trace.TraceInformation("Start attacking: {0}", m_target);

                var assignment = new AttackAssignment(this, m_target);
                return assignment;
            }
            else
            {
                trace.TraceInformation("Continue attacking: {0}", m_target);
                return this.CurrentAssignment;
            }
        }
예제 #24
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            bool hasAssignment      = this.CurrentAssignment != null;
            bool hasOtherAssignment = this.CurrentAssignment == null && this.Worker.HasAction;

            if (priority == ActionPriority.High)
            {
                if (m_priorityAction)
                {
                    return(this.CurrentAssignment);
                }

                return(this.CurrentAssignment);
            }
            else if (priority == ActionPriority.Idle)
            {
                if (hasOtherAssignment)
                {
                    return(null);
                }

                if (m_priorityAction)
                {
                    return(this.CurrentAssignment);
                }

                if (hasAssignment)
                {
                    return(this.CurrentAssignment);
                }

                return(new Dwarrowdelf.Jobs.Assignments.RandomMoveAssignment(null));
            }
            else
            {
                throw new Exception();
            }
        }
예제 #25
0
 public void StartAction(GameAction action, ActionPriority priority)
 {
     StartAction(action, priority, 0);
 }
예제 #26
0
        /// <summary>
        /// return new or current GameAction, possibly overriding the current action, or null to abort the current action
        /// </summary>
        /// <param name="priority"></param>
        /// <returns></returns>
        public GameAction DecideAction(ActionPriority priority)
        {
            trace.TraceVerbose("DecideAction({0}): Worker.Action = {1}, CurrentAssignment {2}, CurrentAssignment.Action = {3}",
                priority,
                this.Worker.HasAction ? this.Worker.CurrentAction.ToString() : "<none>",
                this.HasAssignment ? this.CurrentAssignment.ToString() : "<none>",
                this.HasAssignment && this.CurrentAssignment.CurrentAction != null ? this.CurrentAssignment.CurrentAction.ToString() : "<none>");

            // ActionStarted/Progress/Done events should keep us in sync. Verify it here.
            Debug.Assert(
                // Either we are not doing an assignment...
                (this.HasAssignment == false) ||

                // ... or if we are, and it doesn't have an action, the worker shouldn't be doing anything either...
                (this.HasAssignment &&
                this.CurrentAssignment.CurrentAction == null &&
                this.Worker.CurrentAction == null) ||

                // .. or if it has an action, the worker should be doing that action.
                (this.HasAssignment &&
                this.CurrentAssignment.CurrentAction != null &&
                this.CurrentAssignment.CurrentAction.MagicNumber == this.Worker.CurrentAction.MagicNumber));

            if (this.Worker.HasAction && this.Worker.ActionPriority > priority)
            {
                trace.TraceVerbose("DecideAction: worker already doing higher priority action");
                return this.Worker.CurrentAction;
            }

            var assignment = GetNewOrCurrentAssignment(priority);

            var oldAssignment = this.CurrentAssignment;

            if (assignment == null)
            {
                trace.TraceVerbose("DecideAction: No assignment");

                if (oldAssignment == null)
                    return this.Worker.CurrentAction;

                trace.TraceVerbose("DecideAction: Aborting current assignment {0}", oldAssignment);
                oldAssignment.Abort();

                ClearCurrentAssignment();

                return null;
            }

            // are we doing this assignment for another priority level?
            if (assignment == oldAssignment && this.CurrentPriority != priority)
            {
                Debug.Assert(assignment == oldAssignment);
                Debug.Assert(assignment.Worker == this.Worker);
                trace.TraceVerbose("DecideAction: Already doing an assignment for different priority level");
                return this.Worker.CurrentAction;
            }

            // new assignment?
            if (assignment != oldAssignment)
            {
                trace.TraceVerbose("DecideAction: New assignment {0}", assignment);

                Debug.Assert(assignment.IsAssigned == false);

                assignment.Assign(this.Worker);
                Debug.Assert(assignment.Status == JobStatus.Ok);

                if (oldAssignment != null)
                {
                    trace.TraceVerbose("DecideAction: Aborting current assignment {0}", oldAssignment);
                    oldAssignment.Abort();
                }

                SetCurrentAssignment(assignment, priority);
            }

            Debug.Assert(this.CurrentAssignment == assignment);

            // are we already doing an action for this assignment?
            if (assignment.CurrentAction != null)
            {
                trace.TraceVerbose("DecideAction: already doing an action");
                //Debug.Assert(assignment.CurrentAction == this.Worker.CurrentAction);
                return this.Worker.CurrentAction;
            }

            var state = assignment.PrepareNextAction();

            if (state == JobStatus.Ok)
            {
                var action = assignment.CurrentAction;
                if (action == null)
                    throw new Exception();

                m_magicNumber++;
                if (m_magicNumber == 0)
                    m_magicNumber++;

                action.MagicNumber = m_magicNumber | (m_id << 16);

                trace.TraceVerbose("DecideAction: new action {0}", action);
                return action;
            }

            trace.TraceVerbose("DecideAction: failed to start new action", state, assignment);

            return this.Worker.CurrentAction;
        }
예제 #27
0
        public void StartAction(GameAction action, ActionPriority priority)
        {
            D("DoAction: {0}", action);

            Debug.Assert(!this.HasAction);
            Debug.Assert(priority != ActionPriority.Undefined);
            Debug.Assert(action.GUID.IsNull == false);

            this.CurrentAction = action;
            this.ActionPriority = priority;
            this.ActionTotalTicks = 0;
            this.ActionTicksUsed = 0;

            var e = new ActionStartEvent()
            {
                Action = action,
                Priority = priority,
            };

            if (m_ai != null)
                m_ai.ActionStarted(e);

            var c = new ActionStartedChange(this)
            {
                ActionStartEvent = e,
            };

            this.World.AddChange(c);
        }
예제 #28
0
        public Models.Action UpdateAction(int actionId, string parties, string description, string comment, ActionPriority priority, ActionStatus status = ActionStatus.Open)
        {
            RequireMemberAccess();
            var action = GetAction(actionId);

            if (action == null)
            {
                throw new ClientException("the specified action is not exist");
            }
            else if (action.Uid != _currentUser.Id && !_currentUser.IsAdmin)
            {
                throw new ClientException("you cannot edit other's action");
            }

            if (string.IsNullOrWhiteSpace(description))
            {
                throw new ClientException("description must not be blank");
            }

            using (var _dbContext = new DailyReportsContext())
            {
                action             = _dbContext.Actions.Where(x => x.Id == actionId).FirstOrDefault();
                action.Parties     = parties;
                action.Description = description;
                action.Comment     = comment;
                action.Priority    = priority;
                action.Status      = status;
                action.Update      = DateTime.UtcNow;
                _dbContext.SaveChanges();

                return(action);
            }
        }
예제 #29
0
 public DieAction(ActionId in_id, ActionPriority in_priority)
     : base(in_id, in_priority)
 {
 }
예제 #30
0
 /// <summary>
 /// return new or current assignment, or null to cancel current assignment, or do nothing if no current assignment
 /// </summary>
 /// <param name="priority"></param>
 /// <returns></returns>
 protected abstract IAssignment GetNewOrCurrentAssignment(ActionPriority priority);
예제 #31
0
        public Models.Action AddAction(int projectId, string parties, string description, string comment, ActionPriority priority, ActionStatus status = ActionStatus.Open)
        {
            RequireMemberAccess();
            var user = GetUser(_currentUser.Id);

            if (user == null)
            {
                throw new ClientException("the specified user is not a member");
            }
            var project = GetProject(projectId);

            if (project == null)
            {
                throw new ClientException("the specified project is not exist");
            }
            if (string.IsNullOrWhiteSpace(description))
            {
                throw new ClientException("description must not be blank");
            }

            using (var _dbContext = new DailyReportsContext())
            {
                var action = _dbContext.Actions.Add(new Models.Action()
                {
                    Uid         = _currentUser.Id,
                    ProjectId   = projectId,
                    Parties     = parties,
                    Description = description,
                    Create      = DateTime.UtcNow,
                    Comment     = comment,
                    Priority    = priority,
                    Status      = status
                });
                _dbContext.SaveChanges();

                return(action);
            }
        }
예제 #32
0
        void SetCurrentAssignment(IAssignment assignment, ActionPriority priority)
        {
            if (m_currentAssignment == assignment && m_currentPriority == priority)
                return;

            if (m_currentAssignment != null)
                m_currentAssignment.StatusChanged -= OnJobStatusChanged;

            m_currentAssignment = assignment;
            m_currentPriority = priority;

            if (m_currentAssignment != null)
                m_currentAssignment.StatusChanged += OnJobStatusChanged;

            if (AssignmentChanged != null)
                AssignmentChanged(assignment);
        }
예제 #33
0
        public void Add(Action action, ActionPriority priority, object owner, bool isExpensiveOperation=false)
        {
            lock (lockObj)
            {
                _actionList.Add(new ActionListElement(action, priority, owner, isExpensiveOperation));
            }

#if !WP7
            if (!_actionExecutingRunningNow)
            {
                ProcessAllActionList(_manager);
            }
#endif
        }
예제 #34
0
 public BaseAction(ActionId in_id, ActionPriority in_priority)
 {
     m_id       = in_id;
     mb_update  = false;
     m_priority = in_priority;
 }
예제 #35
0
 public NormalDmgAction(ActionId in_id, ActionPriority in_priority)
     : base(in_id, in_priority)
 {
 }
예제 #36
0
        public void StartAction(GameAction action, ActionPriority priority, int userID)
        {
            D("DoAction: {0}, uid: {1}", action, userID);

            Debug.Assert(!this.HasAction);
            Debug.Assert(priority != ActionPriority.Undefined);
            Debug.Assert(action.MagicNumber != 0);

            this.CurrentAction = action;
            this.ActionPriority = priority;
            this.ActionTotalTicks = 0;
            this.ActionTicksUsed = 0;
            this.ActionUserID = userID;

            var e = new ActionStartEvent()
            {
                Action = action,
                Priority = priority,
                UserID = userID,
            };

            if (m_ai != null)
                m_ai.ActionStarted(e);

            var c = new ActionStartedChange(this)
            {
                ActionStartEvent = e,
            };

            this.World.AddChange(c);
        }
예제 #37
0
 /// <summary>
 /// return new or current assignment, or null to cancel current assignment, or do nothing if no current assignment
 /// </summary>
 /// <param name="priority"></param>
 /// <returns></returns>
 protected abstract IAssignment GetNewOrCurrentAssignment(ActionPriority priority);
예제 #38
0
        /// <summary>
        /// return new or current GameAction, possibly overriding the current action, or null to abort the current action
        /// </summary>
        /// <param name="priority"></param>
        /// <returns></returns>
        public GameAction DecideAction(ActionPriority priority)
        {
            trace.TraceVerbose("DecideAction({0}): Worker.Action = {1}, CurrentAssignment {2}, CurrentAssignment.Action = {3}",
                               priority,
                               this.Worker.HasAction ? this.Worker.CurrentAction.ToString() : "<none>",
                               this.HasAssignment ? this.CurrentAssignment.ToString() : "<none>",
                               this.HasAssignment && this.CurrentAssignment.CurrentAction != null ? this.CurrentAssignment.CurrentAction.ToString() : "<none>");

            // ActionStarted/Progress/Done events should keep us in sync. Verify it here.
            Debug.Assert(
                // Either we are not doing an assignment...
                (this.HasAssignment == false) ||

                // ... or if we are, and it doesn't have an action, the worker shouldn't be doing anything either...
                (this.HasAssignment &&
                 this.CurrentAssignment.CurrentAction == null &&
                 this.Worker.CurrentAction == null) ||

                // .. or if it has an action, the worker should be doing that action.
                (this.HasAssignment &&
                 this.CurrentAssignment.CurrentAction != null &&
                 this.CurrentAssignment.CurrentAction.GUID == this.Worker.CurrentAction.GUID));

            if (this.Worker.HasAction && this.Worker.ActionPriority > priority)
            {
                trace.TraceVerbose("DecideAction: worker already doing higher priority action");
                return(this.Worker.CurrentAction);
            }

            var assignment = GetNewOrCurrentAssignment(priority);

            var oldAssignment = this.CurrentAssignment;

            if (assignment == null)
            {
                trace.TraceVerbose("DecideAction: No assignment");

                if (oldAssignment == null)
                {
                    return(this.Worker.CurrentAction);
                }

                trace.TraceVerbose("DecideAction: Aborting current assignment {0}", oldAssignment);
                oldAssignment.Abort();

                ClearCurrentAssignment();

                return(null);
            }

            // are we doing this assignment for another priority level?
            if (assignment == oldAssignment && this.CurrentPriority != priority)
            {
                Debug.Assert(assignment == oldAssignment);
                Debug.Assert(assignment.Worker == this.Worker);
                trace.TraceVerbose("DecideAction: Already doing an assignment for different priority level");
                return(this.Worker.CurrentAction);
            }

            // new assignment?
            if (assignment != oldAssignment)
            {
                trace.TraceVerbose("DecideAction: New assignment {0}", assignment);

                Debug.Assert(assignment.IsAssigned == false);

                assignment.Assign(this.Worker);
                Debug.Assert(assignment.Status == JobStatus.Ok);

                if (oldAssignment != null)
                {
                    trace.TraceVerbose("DecideAction: Aborting current assignment {0}", oldAssignment);
                    oldAssignment.Abort();
                }

                SetCurrentAssignment(assignment, priority);
            }

            Debug.Assert(this.CurrentAssignment == assignment);

            // are we already doing an action for this assignment?
            if (assignment.CurrentAction != null)
            {
                trace.TraceVerbose("DecideAction: already doing an action");
                //Debug.Assert(assignment.CurrentAction == this.Worker.CurrentAction);
                return(this.Worker.CurrentAction);
            }


            var state = assignment.PrepareNextAction();

            if (state == JobStatus.Ok)
            {
                var action = assignment.CurrentAction;
                if (action == null)
                {
                    throw new Exception();
                }

                int actionID = m_actionIDCounter++;

                action.GUID = new ActionGUID(m_playerID, actionID);

                trace.TraceVerbose("DecideAction: new action {0}", action);
                return(action);
            }

            trace.TraceVerbose("DecideAction: failed to start new action", state, assignment);

            return(this.Worker.CurrentAction);
        }
예제 #39
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            if (priority == ActionPriority.High)
                return this.CurrentAssignment;

            var worker = this.Worker;

            bool hasAssignment = this.CurrentAssignment != null;
            bool hasOtherAssignment = this.CurrentAssignment == null && this.Worker.HasAction;

            if (hasOtherAssignment)
                return null;

            switch (this.State)
            {
                case HervivoreAIState.Grazing:
                    {
                        var enemies = AIHelpers.FindEnemies(worker, LivingCategory.Carnivore | LivingCategory.Civilized | LivingCategory.Monster);

                        if (enemies.Any())
                        {
                            var fleeVector = GetFleeVector(enemies);

                            trace.TraceInformation("Changing to Flee state, v = {0}", fleeVector);

                            this.State = HervivoreAIState.Fleeing;
                            m_fleeFinishedTick = worker.World.TickNumber + FLEE_TIME;
                            m_fleeAssignment = new FleeMoveAssignment(this);
                            m_fleeAssignment.SetFleeVector(fleeVector);
                            return m_fleeAssignment;
                        }

                        if (hasAssignment)
                            return this.CurrentAssignment;

                        return new Dwarrowdelf.Jobs.Assignments.GrazeMoveAssignment(this, this.Group);
                    }

                case HervivoreAIState.Fleeing:
                    {
                        var enemies = AIHelpers.FindEnemies(worker, LivingCategory.Carnivore | LivingCategory.Civilized | LivingCategory.Monster);

                        if (enemies.Any())
                        {
                            var fleeVector = GetFleeVector(enemies);

                            trace.TraceInformation("Updating fleevector: {0}", fleeVector);

                            m_fleeFinishedTick = worker.World.TickNumber + FLEE_TIME;

                            m_fleeAssignment.SetFleeVector(fleeVector);
                            return m_fleeAssignment;
                        }
                        else if (worker.World.TickNumber < m_fleeFinishedTick)
                        {
                            trace.TraceInformation("Continue fleeing");
                            return m_fleeAssignment;
                        }
                        else
                        {
                            m_fleeAssignment.Abort();

                            trace.TraceInformation("Changing to Graze state");

                            this.State = HervivoreAIState.Grazing;
                            return new Dwarrowdelf.Jobs.Assignments.GrazeMoveAssignment(this, this.Group);
                        }
                    }

                default:
                    throw new Exception();
            }
        }
예제 #40
0
        GameAction IAI.DecideAction(ActionPriority priority)
        {
            if (this.Worker.HasAction)
            {
                if (this.Worker.ActionPriority > priority)
                    return this.Worker.CurrentAction;

                if (m_currentAction != null && this.Worker.CurrentAction.MagicNumber == m_currentAction.MagicNumber)
                    return this.Worker.CurrentAction;
            }

            if (m_actions.Count == 0)
            {
                if (this.Worker.CurrentAction != null)
                    return this.Worker.CurrentAction;

                return null;
            }

            m_currentAction = m_actions[0];

            m_magicNumber++;
            if (m_magicNumber == 0)
                m_magicNumber++;

            m_currentAction.MagicNumber = m_magicNumber | (m_id << 16);

            return m_currentAction;
        }
예제 #41
0
        void DecideAction(ActionPriority priority)
        {
            var action = m_ai.DecideAction(priority);

            if (action != this.CurrentAction)
            {
                // XXX Our AIs don't currently cancel their own actions, so have an assert here for now
                Debug.Assert(action != null);

                if (this.HasAction)
                {
                    if (action != null && this.ActionPriority > priority)
                        throw new Exception();

                    CancelAction();
                }

                if (action != null)
                    StartAction(action, priority);
            }
        }
예제 #42
0
        // return new or current assignment, or null to cancel current assignment, or do nothing is no current assignment
        protected override IAssignment GetNewOrCurrentAssignment(ActionPriority priority)
        {
            var worker = this.Worker;

            bool hasAssignment = this.HasAssignment;
            bool hasOtherAssignment = (this.HasAssignment == false) && this.Worker.HasAction;

            if (priority == ActionPriority.High)
            {
                if (m_priorityAction)
                    return this.CurrentAssignment;

                var assignment = CreateEatAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                assignment = CreateDrinkAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                assignment = CreateSleepAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                return this.CurrentAssignment;
            }
            else if (priority == ActionPriority.Idle)
            {
                if (hasOtherAssignment)
                    return null;

                if (m_priorityAction)
                    return this.CurrentAssignment;

                var assignment = CreateEatAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                assignment = CreateDrinkAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                assignment = CreateSleepAssignmentIfNeeded(worker, priority);
                if (assignment != null)
                    return assignment;

                // loiter around

                if (m_envObserver.Contains(worker.Location))
                {
                    if (hasAssignment && this.CurrentAssignment is RandomMoveAssignment)
                        return this.CurrentAssignment;
                    else
                        return new RandomMoveAssignment(this);
                }
                else
                {
                    var c = m_envObserver.Center;

                    if (hasAssignment && c.HasValue && this.CurrentAssignment is MoveAssignment)
                        return this.CurrentAssignment;
                    else
                    {
                        if (c.HasValue)
                            return new MoveAssignment(this, worker.Environment, c.Value, DirectionSet.Planar | DirectionSet.Exact);
                        else
                            return new RandomMoveAssignment(this);
                    }
                }
            }
            else
            {
                throw new Exception();
            }
        }
예제 #43
0
        IAssignment CreateSleepAssignmentIfNeeded(ILivingObject worker, ActionPriority priority)
        {
            if (priority == ActionPriority.High && worker.Exhaustion < 500)
                return null;

            if (priority == ActionPriority.Idle && worker.Exhaustion < 100)
                return null;

            var env = worker.Environment;

            var ob = env.Contents
                .OfType<IItemObject>()
                .Where(o => o.ItemID == ItemID.Bed)
                .Where(o => o.IsReserved == false && o.IsInstalled)
                .OrderBy(o => (o.Location - worker.Location).ManhattanLength)
                .Where(o => AStar.CanReach(env, worker.Location, o.Location, DirectionSet.Exact))
                .FirstOrDefault();

            if (ob != null)
            {
                m_priorityAction = true;
                var job = new MoveSleepAssignment(this, ob);
                ob.ReservedBy = this;
                return job;
            }

            return null;
        }
예제 #44
0
 public static void Invoke(Object sender, Action action, ActionPriority priority = ActionPriority.Medium)
 {
     new DeferredAction(sender, action, priority).Invoke();
 }
예제 #45
0
 public ExecutorAction(Delegate method, ActionPriority priority, object[] args)
 {
     this.method   = method;
     this.priority = priority;
     this.args     = args;
 }
예제 #46
0
        GameAction IAI.DecideAction(ActionPriority priority)
        {
            if (this.Worker.HasAction)
            {
                if (this.Worker.ActionPriority > priority)
                    return this.Worker.CurrentAction;

                if (m_currentAction != null && this.Worker.CurrentAction.GUID == m_currentAction.GUID)
                    return this.Worker.CurrentAction;
            }

            if (m_actions.Count == 0)
            {
                if (this.Worker.CurrentAction != null)
                    return this.Worker.CurrentAction;

                return null;
            }

            m_currentAction = m_actions[0];

            var actionID = m_actionIDCounter++;
            m_currentAction.GUID = new ActionGUID(m_playerID, actionID);

            return m_currentAction;
        }
예제 #47
0
 public IDispatcherTimer CreateDispatcherTimer(ActionPriority priority)
 {
     return(new WindowsDispatcherTimer((DispatcherPriority)priority));
 }
예제 #48
0
 public ActionListElement(Action action, ActionPriority priority, object owner)
 {
     Action = action;
     Priority = priority;
     Owner = owner;
 }