public void AddQuest(GOAP_Quest quest) { GameObject g = Instantiate(questPanelPrefab, questsParent); g.GetComponent <QuestContentPanel>().SetContent("Quest " + quest.id, quest.ToLongString(), "Owner: " + quest.Owner.Character.characterData.characterName + "\nRequired: " + quest.RequiredStates.ToString() + "\n\nReward: " + quest.Reward); panels.Add(quest.id, g); }
public void AddQuest(GOAP_Quest quest) { quests.Add(quest.id, quest); if (addQuestEvent != null) { addQuestEvent.Invoke(quest); } }
public void TradeQuestItems(GOAP_Agent agent) { GOAP_Quest q = GOAP_QuestBoard.instance.quests[questID]; foreach (GOAP_Worldstate questState in q.RequiredStates) { if (questState.key == WorldStateKey.eHasItem) { otherAgent.Character.UpdateInventory((ItemType)questState.value, true); agent.Character.UpdateInventory((ItemType)questState.value, false); } } }
public override bool Perform(GOAP_Agent agent, float deltaTime) { if (isStartingWork) { Debug.Log("<color=#0000cc><b>PERFORMING</b>: " + agent.Character.characterData.characterName + "</color>: PostQuest(" + questData.RequiredToString() + ")"); agent.View.PrintMessage(ActionID); } UpdateWorkTime(deltaTime); if (completed) { GOAP_Quest q = new GOAP_Quest(questData); agent.postedQuestIDs.Add(q.id); questID = q.id; GOAP_QuestBoard.instance.AddQuest(q); } return(completed); }
/// <summary> /// Checks the questboard for any quests that have not yet been attempted by the agent before /// </summary> /// <returns></returns> public GOAP_Quest CheckForQuests() { if (GOAP_QuestBoard.instance.quests.Count == 0) { checkedQuestIds.Clear(); return(null); } GOAP_Quest result = null; //First go through all questIds we have tried to plan for before and see if they are even still available //I use a quick check here, that only deletes ids that are lower than the lowest quest on the board //This is basically just garbagecollection int minKey = GOAP_QuestBoard.instance.quests.First().Key; for (int i = 0; i < checkedQuestIds.Count; i++) { //The lowest quest has the lowest id if (minKey > checkedQuestIds[i]) { checkedQuestIds.Remove(checkedQuestIds[i]); } } foreach (KeyValuePair <int, GOAP_Quest> quest in GOAP_QuestBoard.instance.quests) { //if we don't own this quest, lets try to plan for it if (quest.Value.Owner != this && !checkedQuestIds.Contains(quest.Value.id)) { result = quest.Value; break; } } if (result != null) { Debug.Log("<color=#0000cc>" + character.characterData.characterName + "</color> chose to plan for Quest " + result.id); checkedQuestIds.Add(result.id); activeGoal.AddRange(result.RequiredStates); } else { } return(result); }
/// <summary> /// Cancel the actionqueue and forget the plan /// </summary> public void CancelPlan() { if (activeQuest != null) { checkedQuestIds.Remove(activeQuest.id); } else { //if this was a personal goal, remove it from the checked list if (activeGoal.Count == 1) { checkedCharacterGoals.Remove(activeGoal[0]); } } activeQuest = null; activeGoal.Clear(); activePlanInfo = null; activeAction = null; currentActions.Clear(); actionCompleted = true; ChangeState(FSM_State.IDLE); return; }
private void PerformUpdate(float deltaTime) { //Get the next currentAction if (actionCompleted) { if (currentActions.Count > 1 || (currentActions.Count > 0 && activeAction == null)) { //Remove the old active action if (activeAction != null) { currentActions.Dequeue(); } //Get the new active action activeAction = currentActions.Peek(); actionCompleted = false; } else { activeAction = null; } } if (activeAction != null) { if (activeQuest != null) { if (!GOAP_QuestBoard.instance.quests.ContainsKey(activeQuest.id)) { Character.Log("<color=#0000cc>" + Character.characterData.characterName + "</color> can't complete quest, already finished"); CancelPlan(); return; } } if (activeAction.CheckRequirements(this)) { if (activeAction.SatisfyWorldstates.Count > 0 && IsSatisfiedInCurrentWorldstate(activeAction.SatisfyWorldstates)) { actionCompleted = true; Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color> didn't need to perform <color=#cc0000>" + activeAction.ActionID + "</color> anymore."); } else { if (!activeAction.IsInRange(this)) { View.PrintMessage("MoveTo " + activeAction.ActionID); ChangeState(FSM_State.MOVETO); return; } else { actionCompleted = activeAction.Perform(this, deltaTime); View.VisualizeAction(activeAction); } } } else { Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color> cannot perform <color=#cc0000>" + activeAction.ActionID + "</color> anymore."); Replan(); } } else { //if this was a personal goal, remove it from the checked list if (activeQuest != null) { activeQuest = null; } else { if (activeGoal.Count == 1) { checkedCharacterGoals.Remove(activeGoal[0]); } } Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color> has completed his action queue for Goal " + planMemory[(int)activePlanInfo].goalInfo); activeGoal.Clear(); activePlanInfo = null; ChangeState(FSM_State.IDLE); return; } }
private void PlanningUpdate(float deltaTime) { View.PrintMessage("Planning"); #region cleanup Useless Quests //First check if any of the posted quests are already done so they can be removed List <int> alreadySolvedQuests = new List <int>(); for (int i = 0; i < postedQuestIDs.Count; i++) { if (IsSatisfiedInCurrentWorldstate(GOAP_QuestBoard.instance.quests[postedQuestIDs[i]].RequiredStates)) { Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color>s Quest " + postedQuestIDs[i] + " was already solved."); alreadySolvedQuests.Add(postedQuestIDs[i]); } } for (int i = 0; i < alreadySolvedQuests.Count; i++) { GOAP_QuestBoard.instance.CompleteQuest(alreadySolvedQuests[i]); } #endregion //Actual planning: if (activeGoal.Count > 0) { Queue <GOAP_Action> newPlan; //Fetch a new Plan from the planner planMemory.Add(new PlanInfo(PrintGoal(), Character.characterData.characterName)); newPlan = GOAP_Planner.Plan(this, activeGoal, currentWorldstates, character.characterData.availableActions); timeSincePlanned = 0.0f; if (newPlan != null) { //do what the plan says! currentActions = newPlan; actionCompleted = true; planMemory[planMemory.Count - 1].ApprovePlan(planMemory.Count - 1, PrintActionQueue()); activePlanInfo = planMemory.Count - 1; if (activePlanInfo == -1) { Debug.LogError(character.characterData.characterName + " ActivePlanIndex: -1"); } ChangeState(FSM_State.PERFORMACTION); return; } else { planMemory.RemoveAt(planMemory.Count - 1); //try again? or something... Debug.Log("No plan?"); if (activeQuest != null) { activeQuest = null; activeGoal.Clear(); ChangeState(FSM_State.IDLE); return; } } } else { //Before checking goals, check if any of your quests have been completed if (completedQuestIDs.Count > 0) { //choose the first one and go int id = completedQuestIDs[0]; if (questPlans.ContainsKey(id)) { currentActions = new Queue <GOAP_Action>(questPlans[id].ToArray()); Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color> has completed Quest " + id + " to finish. It includes " + currentActions.Count + " actions and starts with " + currentActions.Peek()); questPlans.Remove(id); Character.Log("<color=#0000cc>" + character.characterData.characterName + "</color> removes questplan" + id); ChangeState(FSM_State.PERFORMACTION); return; } else { string msg = ""; foreach (int key in questPlans.Keys) { msg += key + ","; } Debug.LogError("<color=#0000cc>" + character.characterData.characterName + "</color> tried to continue Quest " + id + " but didnt find a corresponding plan.\nExisting plans:" + msg); completedQuestIDs.Remove(id); ChangeState(FSM_State.IDLE); return; } } else { if (postedQuestIDs.Count == 0) { checkedCharacterGoals.Clear(); } ChooseGoal(); if (activeGoal.Count == 0) { ChangeState(FSM_State.IDLE); return; } } } }