Пример #1
0
    public IReGoapGoal Plan(IReGoapAgent agent, IReGoapGoal blacklistGoal = null, Queue <ReGoapActionState> currentPlan = null, Action <IReGoapGoal> callback = null)
    {
        ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
        goapAgent   = agent;
        Calculated  = false;
        currentGoal = null;
        var possibleGoals = new List <IReGoapGoal>();

        foreach (var goal in goapAgent.GetGoalsSet())
        {
            if (goal == blacklistGoal)
            {
                continue;
            }
            goal.Precalculations(this);
            if (goal.IsGoalPossible()) //goal.GetPriority() > bestPriority &&
            {
                possibleGoals.Add(goal);
            }
        }
        possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

        while (possibleGoals.Count > 0)
        {
            currentGoal = possibleGoals[possibleGoals.Count - 1];
            possibleGoals.RemoveAt(possibleGoals.Count - 1);
            var goalState = currentGoal.GetGoalState();

            var leaf = (BGoapNode)astar.Run(
                new BGoapNode(this, goalState, null, null), goapAgent.GetMemory().GetWorldState(), settings.MaxIterations, settings.PlanningEarlyExit);
            if (leaf == null)
            {
                currentGoal = null;
                continue;
            }
            var path = leaf.CalculatePath();
            if (currentPlan != null && currentPlan == path)
            {
                currentGoal = null;
                break;
            }
            currentGoal.SetPlan(path);
            break;
        }
        Calculated = true;

        if (callback != null)
        {
            callback(currentGoal);
        }
        if (currentGoal != null)
        {
            ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
        }
        else
        {
            ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
        }
        return(currentGoal);
    }
Пример #2
0
        public override bool IsGoalPossible()
        {
            var state = agent.GetMemory().GetWorldState();

            if (state.HasKey($"Has Role {type}"))
            {
                return((bool)state.Get($"Has Role {type}"));
            }
            return(false);
        }
Пример #3
0
 protected override IEnumerable <BGoapState> GetPossibleGenericVariableCombinations(IReGoapAgent goapAgent)
 {
     foreach (SmartObject so in (goapAgent.GetMemory() as GoapMemory).GetAvailableSoList())
     {
         if (so is RPGSOTable)
         {
             BGoapState resultState = new BGoapState();
             resultState.Set(table, so);
             yield return(resultState);
         }
     }
 }
Пример #4
0
    protected override IEnumerable <BGoapState> GetPossibleVariableCombinations(BGoapState lockInValues, IReGoapAgent goapAgent, BGoapState genericAssignments)
    {
        if (lockInValues.HasKey(itemVariable) && lockInValues.Get(itemVariable) == null) //this should be handled by place/drop item
        {
            yield break;
        }
        if (lockInValues.HasKey(itemVariable) && lockInValues.HasKey(itemTypeVariable))          //both item type and specific item are locked in
        {
            if (lockInValues.Get(itemVariable).sourceItem == lockInValues.Get(itemTypeVariable)) //check that this combination is valid
            {
                BGoapState assignment = new BGoapState();
                assignment.Set(locationVariable, lockInValues.Get(itemVariable).positionCache);
                yield return(assignment);
            }
        }
        else if (lockInValues.HasKey(itemVariable) && lockInValues.Get(itemVariable) != null) //specific item locked in, fill in it's values
        {
            BGoapState assignment = new BGoapState();
            assignment.Set(itemTypeVariable, lockInValues.Get(itemVariable).sourceItem);
            assignment.Set(locationVariable, lockInValues.Get(itemVariable).positionCache);
            yield return(assignment);
        }
        else if (lockInValues.HasKey(itemTypeVariable))   //item type locked in, fill in all possible items

        {
            DBItem requiredItemType = lockInValues.Get(itemTypeVariable);
            foreach (InGameItem item in (goapAgent.GetMemory() as GoapMemory).GetAvailableItemList())
            {
                if (item.sourceItem == requiredItemType)
                {
                    BGoapState assignment = new BGoapState();
                    assignment.Set(itemVariable, item);
                    assignment.Set(locationVariable, item.positionCache);
                    yield return(assignment);
                }
            }
        }
        yield break;
    }
    private void UpdateGoapNodes <T, W>(IReGoapAgent <T, W> agent)
    {
        if (nodes == null)
        {
            nodes = new List <ReGoapNodeEditor>();
        }
        if (agentHelper == null || agent == null || !agent.IsActive() || agent.GetMemory() == null)
        {
            return;
        }

        nodes.Clear();
        var width        = 300f;
        var height       = 70f;
        var nodePosition = new Vector2(0f, 60f);
        var nodeMiddleY  = new Vector2(0f, height * 0.5f);

        ReGoapNodeEditor?previousNode = null;

        foreach (var goal in agent.GetGoalsSet())
        {
            if (goal.GetGoalState() == null)
            {
                continue;
            }
            var text = string.Format("<b>GOAL</b> <i>{0}</i>\n", goal);
            foreach (var keyValue in goal.GetGoalState().GetValues())
            {
                text += string.Format("<b>'{0}'</b> = <i>'{1}'</i>", keyValue.Key, keyValue.Value);
            }
            var style = nodeStyle;
            if (agent.IsActive() && agent.GetCurrentGoal() == goal)
            {
                style = activeStyle;
            }
            var newNode = DrawGenericNode(text, width, height, style, ref nodePosition);
            if (previousNode.HasValue)
            {
                var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f);
                var endPosition   = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f);
                Handles.DrawLine(startPosition, endPosition);
            }
            previousNode = newNode;
        }
        previousNode = null;

        nodePosition = new Vector2(0f, nodePosition.y + height + 10);
        height       = 66;
        var maxHeight = height;

        var emptyGoal = agent.InstantiateNewState();
        GoapActionStackData <T, W> stackData;

        stackData.agent        = agent;
        stackData.currentState = agent.GetMemory().GetWorldState();
        stackData.goalState    = emptyGoal;
        stackData.next         = null;
        stackData.settings     = null;

        foreach (var action in agent.GetActionsSet())
        {
            var curHeight = height;
            var text      = string.Format("<b>POSS.ACTION</b> <i>{0}</i>\n", action.GetName());
            text += "-<b>preconditions</b>-\n";
            var preconditionsDifferences = agent.InstantiateNewState();
            var preconditions            = action.GetPreconditions(stackData);
            if (preconditions == null)
            {
                continue;
            }
            preconditions.MissingDifference(stackData.currentState, ref preconditionsDifferences);
            foreach (var preconditionPair in preconditions.GetValues())
            {
                curHeight += 13;
                var color = "#004d00";
                if (preconditionsDifferences.GetValues().ContainsKey(preconditionPair.Key))
                {
                    color = "#800000";
                }
                text += string.Format("<color={2}>'<b>{0}</b>' = '<i>{1}</i>'</color>\n", preconditionPair.Key, preconditionPair.Value, color);
            }
            preconditionsDifferences.Recycle();

            text += "-<b>effects</b>-\n";
            foreach (var effectPair in action.GetEffects(stackData).GetValues())
            {
                curHeight += 13;
                text      += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", effectPair.Key, effectPair.Value);
            }
            curHeight += 13;
            var proceduralCheck = action.CheckProceduralCondition(stackData);
            text += string.Format("<color={0}>-<b>proceduralCondition</b>: {1}</color>\n", proceduralCheck ? "#004d00" : "#800000", proceduralCheck);

            maxHeight = Mathf.Max(maxHeight, curHeight);

            nodeMiddleY = new Vector2(0f, curHeight * 0.5f);
            var newNode = DrawGenericNode(text, width, curHeight, possibleActionStyle, ref nodePosition);
            if (previousNode.HasValue)
            {
                var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f);
                var endPosition   = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f);
                Handles.DrawLine(startPosition, endPosition);
            }
            previousNode = newNode;
        }
        previousNode = null;

        nodePosition.x  = 0;
        nodePosition.y += maxHeight + 10;
        height          = 40;
        nodeMiddleY     = new Vector2(0f, height * 0.5f);
        if (agent.GetCurrentGoal() != null)
        {
            foreach (var action in agent.GetStartingPlan().ToArray())
            {
                var style = actionNodeStyle;
                if (action.Action.IsActive())
                {
                    style = activeActionNodeStyle;
                }
                var text = string.Format("<b>ACTION</b> <i>{0}</i>\n", action.Action.GetName());

                var newNode = DrawGenericNode(text, width, height, style, ref nodePosition);
                if (previousNode.HasValue)
                {
                    var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f);
                    var endPosition   = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f);
                    Handles.DrawLine(startPosition, endPosition);
                }
                previousNode = newNode;
            }
        }

        if (agent.GetMemory() != null)
        {
            nodePosition = new Vector2(0, nodePosition.y + height + 10);
            width        = 500;
            height       = 40;
            nodeMiddleY  = new Vector2(0f, height * 0.5f);
            var nodeText = "<b>WORLD STATE</b>\n";
            foreach (var pair in agent.GetMemory().GetWorldState().GetValues())
            {
                nodeText += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", pair.Key, pair.Value);
                height   += 13;
            }
            DrawGenericNode(nodeText, width, height, worldStateStyle, ref nodePosition);
        }
    }
Пример #6
0
        public IReGoapGoal <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal = null, Queue <ReGoapActionState <T, W> > currentPlan = null, Action <IReGoapGoal <T, W> > callback = null)
        {
            if (ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full)
            {
                ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
            }
            goapAgent   = agent;
            Calculated  = false;
            currentGoal = null;
            var possibleGoals = new List <IReGoapGoal <T, W> >();

            foreach (var goal in goapAgent.GetGoalsSet())
            {
                if (goal == blacklistGoal)
                {
                    continue;
                }
                goal.Precalculations(this);
                if (goal.IsGoalPossible())
                {
                    possibleGoals.Add(goal);
                }
            }
            possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

            var currentState = agent.GetMemory().GetWorldState();

            while (possibleGoals.Count > 0)
            {
                currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);
                var goalState = currentGoal.GetGoalState();

                // can't work with dynamic actions, of course
                if (!settings.UsingDynamicActions)
                {
                    var wantedGoalCheck = currentGoal.GetGoalState();
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = goapAgent;
                    stackData.currentState = currentState;
                    stackData.goalState    = goalState;
                    stackData.next         = null;
                    stackData.settings     = null;
                    // we check if the goal can be archived through actions first, so we don't brute force it with A* if we can't
                    foreach (var action in goapAgent.GetActionsSet())
                    {
                        action.Precalculations(stackData);
                        if (!action.CheckProceduralCondition(stackData))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(stackData), ref wantedGoalCheck);
                    }
                    // finally push the current world state
                    var current = wantedGoalCheck;
                    wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                    current.MissingDifference(GetCurrentAgent().GetMemory().GetWorldState(), ref wantedGoalCheck);
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                goalState = goalState.Clone();
                var leaf = (ReGoapNode <T, W>)astar.Run(
                    ReGoapNode <T, W> .Instantiate(this, goalState, null, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit, debugPlan: settings.DebugPlan);
                if (leaf == null)
                {
                    currentGoal = null;
                    continue;
                }

                var result = leaf.CalculatePath();
                if (currentPlan != null && currentPlan == result)
                {
                    currentGoal = null;
                    break;
                }
                if (result.Count == 0)
                {
                    currentGoal = null;
                    continue;
                }
                currentGoal.SetPlan(result);
                break;
            }
            Calculated = true;

            if (callback != null)
            {
                callback(currentGoal);
            }
            if (currentGoal != null)
            {
                ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
                if (ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full)
                {
                    int i = 0;
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = agent;
                    stackData.currentState = currentState;
                    stackData.goalState    = currentGoal.GetGoalState();
                    stackData.next         = null;
                    foreach (var action in currentGoal.GetPlan())
                    {
                        stackData.settings = action.Settings;
                        ReGoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action.ToString(stackData)));
                    }
                }
            }
            else
            {
                ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }
            return(currentGoal);
        }
Пример #7
0
    private void UpdateGoapNodes(GameObject gameObj)
    {
        if (agent == null || !agent.IsActive() || agent.GetMemory() == null)
        {
            return;
        }

        if (nodes == null)
        {
            nodes = new List <ReGoapNodeEditor>();
        }
        nodes.Clear();
        var width        = 250f;
        var height       = 70f;
        var nodePosition = Vector2.zero;

        foreach (var goal in gameObj.GetComponents <IReGoapGoal>())
        {
            if (goal.GetGoalState() == null)
            {
                continue;
            }
            var text = string.Format("<b>GOAL</b> <i>{0}</i>\n", goal);
            foreach (var keyValue in goal.GetGoalState().GetValues())
            {
                text += string.Format("<b>'{0}'</b> = <i>'{1}'</i>", keyValue.Key, keyValue.Value);
            }
            var style = nodeStyle;
            if (agent.IsActive() && agent.GetCurrentGoal() == goal)
            {
                style = activeStyle;
            }
            DrawGenericNode(text, width, height, style, ref nodePosition);
        }

        nodePosition = new Vector2(0f, nodePosition.y + height + 10);
        height       = 66;
        var maxHeight  = height;
        var worldState = agent.GetMemory().GetWorldState();

        foreach (var action in agent.GetActionsSet())
        {
            var curHeight = height;
            var text      = string.Format("<b>POSS.ACTION</b> <i>{0}</i>\n", action.GetName());
            text += "-<b>preconditions</b>-\n";
            ReGoapState preconditionsDifferences = new ReGoapState();
            var         preconditions            = action.GetPreconditions(null);
            if (preconditions == null)
            {
                continue;
            }
            preconditions.MissingDifference(worldState, ref preconditionsDifferences);
            foreach (var preconditionPair in preconditions.GetValues())
            {
                curHeight += 13;
                var color = "#004d00";
                if (preconditionsDifferences.GetValues().ContainsKey(preconditionPair.Key))
                {
                    color = "#800000";
                }
                text += string.Format("<color={2}>'<b>{0}</b>' = '<i>{1}</i>'</color>\n", preconditionPair.Key, preconditionPair.Value, color);
            }
            text += "-<b>effects</b>-\n";
            foreach (var effectPair in action.GetEffects(null).GetValues())
            {
                curHeight += 13;
                text      += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", effectPair.Key, effectPair.Value);
            }
            curHeight += 13;
            var proceduralCheck = action.CheckProceduralCondition(agent, null);
            text += string.Format("<color={0}>-<b>proceduralCondition</b>: {1}</color>\n", proceduralCheck ? "#004d00" : "#800000", proceduralCheck);

            maxHeight = Mathf.Max(maxHeight, curHeight);
            DrawGenericNode(text, width, curHeight, possibleActionStyle, ref nodePosition);
        }
        nodePosition.x  = 0;
        nodePosition.y += maxHeight + 10;
        height          = 40;
        if (agent.GetCurrentGoal() != null)
        {
            foreach (var action in agent.GetStartingPlan().ToArray())
            {
                var style = actionNodeStyle;
                if (action.Action.IsActive())
                {
                    style = activeActionNodeStyle;
                }
                var text = string.Format("<b>ACTION</b> <i>{0}</i>\n", action.Action.GetName());
                DrawGenericNode(text, width, height, style, ref nodePosition);
            }
        }

        if (agent.GetMemory() != null)
        {
            nodePosition = new Vector2(0, nodePosition.y + height + 10);
            width        = 500;
            height       = 40;
            var nodeText = "<b>WORLD STATE</b>\n";
            foreach (var pair in agent.GetMemory().GetWorldState().GetValues())
            {
                nodeText += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", pair.Key, pair.Value);
                height   += 13;
            }
            DrawGenericNode(nodeText, width, height, worldStateStyle, ref nodePosition);
        }
    }