Пример #1
0
    public void ChangeCurrentWorldState(GOAP_Worldstate newState)
    {
        if (currentWorldstates.ContainsKey(newState))
        {
            if (newState.type == WorldStateType.UNIQUE)
            {
                currentWorldstates.Remove(newState); //this should find the state based on the key only
                currentWorldstates.Add(newState);
                Debug.Log(Character.characterData.characterName + " <color=#cc0000>Updated state:</color> " + newState.ToString());
            }
            else
            {
                if (!currentWorldstates.ContainsExactly(newState))
                {
                    Character.Log(Character.characterData.characterName + " <color=#cc0000>Add state:</color> " + newState.ToString());
                    currentWorldstates.Add(newState);
                }
            }
        }

        //Otherwise, if the newstate is not contained in the currentworldstate, add it
        else
        {
            Character.Log(Character.characterData.characterName + " <color=#cc0000>Add state:</color> " + newState.ToString());
            currentWorldstates.Add(newState);
        }
    }
Пример #2
0
    /// <summary>
    /// This action chooses a goal from among the personal goals after checking if there are completed quests to finish first
    /// </summary>
    public void ChooseGoal()
    {
        activeGoal.Clear();
        string msg = "<color=#0000cc><b>CHECKING GOALS</b>:" + character.characterData.characterName + "</color>\n";

        //Check goals top to bottom, to see which need to be fulfilled
        for (int i = 0; i < character.characterData.goals.Count; i++)
        {
            GOAP_Worldstate goal = character.characterData.goals[i];

            //Check if the goal is already satisfied
            if (!GOAP_Planner.IsGoalSatisfied(currentWorldstates, goal))
            {
                //And if it has been checked before
                if (!checkedCharacterGoals.ContainsExactly(goal))
                {
                    checkedCharacterGoals.Add(character.characterData.goals[i]);
                    activeGoal.Add(goal);
                    msg += character.characterData.goals[i].key + ":" + character.characterData.goals[i].value + " not yet satisfied\n";
                    break;
                }
                else
                {
                    msg += character.characterData.goals[i].key + ":" + character.characterData.goals[i].value + " not yet satisfied, but was already checked\n";
                }
            }
            else
            {
                if (checkedCharacterGoals.ContainsExactly(character.characterData.goals[i]))
                {
                    checkedCharacterGoals.Remove(character.characterData.goals[i]);
                }
                msg += character.characterData.goals[i].key + ":" + character.characterData.goals[i].value + " already satisfied\n";
            }
        }
        Character.Log(msg);

        timeSincePlanned = 0.0f;
    }
Пример #3
0
    /// <summary>
    /// Combines current and goal worldstate
    /// </summary>
    /// <param name="currentWorldState"></param>
    /// <param name="goalWorldState"></param>
    /// <returns></returns>
    private static Node GetGoalNode(List_GOAP_Worldstate currentWorldState, List_GOAP_Worldstate goalWorldState)
    {
        List_GOAP_Worldstate newRequired = new List_GOAP_Worldstate(goalWorldState);

        plannerLog += "Found Goal:\n";
        for (int state = 0; state < goalWorldState.Count; state++)
        {
            plannerLog += goalWorldState[state].ToString() + "\n";
            if (currentWorldState.ContainsExactly(goalWorldState[state]))
            {
                newRequired.Remove(goalWorldState[state]);
            }
        }
        plannerLog += "\n";
        return(new Node(null, newRequired, null, 0));
    }
Пример #4
0
    private static Node GetValidNeighborNode(Node activeNode, GOAP_Action action, List_GOAP_Worldstate planningWorldState, GOAP_Agent agent)
    {
        bool isUsefulAction = false;

        List_GOAP_Worldstate newRequired = new List_GOAP_Worldstate(activeNode.required);

        //Actions need to fulfill at least one required Worldstate to result in a valid neighbor
        foreach (GOAP_Worldstate state in activeNode.required)
        {
            if (action.SatisfyWorldstates.ContainsExactly(state))
            {
                if (state.key == WorldStateKey.bWasFieldTended && state.value == 0)
                {
                    Debug.LogError(action.SatisfyWorldstates.ToString());
                }
                newRequired.Remove(state);
                isUsefulAction = true;
            }
        }

        //if this action does not help the plan, return null
        if (!isUsefulAction)
        {
            return(null);
        }

        //If the actions proceduralConditions are not met, we can't perform it anyways
        //if (!action.CheckProceduralConditions(agent)) return null;

        //add the actions own required worldstates to the Node
        foreach (GOAP_Worldstate state in action.RequiredWorldstates)
        {
            if (!planningWorldState.ContainsExactly(state))
            {
                //If the state is an observable one and the agent does not have any memory of it, they just assume that it is in their favor
                if (state.IsObservableState && !agent.currentWorldstates.ContainsKey(state))
                {
                    Debug.Log("<color=#cc00cc>" + agent.Character.characterData.characterName + "</color> assumes state:" + state.ToString());
                    agent.ChangeCurrentWorldState(state);
                }
                else
                {
                    newRequired.Add(state);
                }
            }
        }

        //Apply skillmodification onto the neighbor if it is valid
        float skillModifier = 1f;

        if (action.BenefitingSkill != Skills.None)
        {
            GOAP_Skill skill = agent.Character.characterData.skills.Find(x => x.id == action.BenefitingSkill);
            if (skill != null)
            {
                //If the character is actually skilled in this action, adjust the skillmodifier
                skillModifier /= skill.level;
            }
            else
            {
                //If the character is not skilled in this action, the skillmodifier is set to 5. This only comes into play, when global knowledge planning is used.
                skillModifier = 1f;
            }
        }

        //Change the skillmodifier on the action
        action.ApplySkillModifier(skillModifier);

        return(new Node(activeNode, newRequired, action, newRequired.Count * heuristicFactor + action.ActionCost + activeNode.estimatedPathCost));
    }