/// <summary> /// Uses a list of reward systems to add rewards to the quest builder /// that are commensurate with the difficulty of the quest. /// </summary> /// <param name="questBuilder">QuestBuilder to receive reward offers.</param> /// <param name="entity">Quest giver entity.</param> /// <param name="goal">Goal step (determines quest difficulty).</param> /// <param name="rewardsUIContents">Text to introduce rewards.</param> /// <param name="rewardSystems">Reward systems from which to get rewards.</param> protected virtual void AddRewards(QuestBuilder questBuilder, QuestEntity entity, PlanStep goal, List <QuestContent> rewardsUIContents, List <RewardSystem> rewardSystems) { if (QuestGenerator.detailedDebug) { Debug.Log("Quest Machine: [Generator] Checking " + rewardSystems.Count + " reward systems for " + goal.fact.count + " " + goal.fact.entityType.name + " (level " + goal.fact.entityType.level + ") on " + entity.name, entity); } questBuilder.AddOfferContents(QuestContent.CloneList <QuestContent>(rewardsUIContents).ToArray()); var pointsRemaining = goal.fact.entityType.level * goal.fact.count; for (int i = 0; i < rewardSystems.Count; i++) { var rewardSystem = rewardSystems[i]; if (rewardSystem == null) { continue; } if (UnityEngine.Random.value > rewardSystem.probability) { continue; } pointsRemaining = rewardSystem.DetermineReward(pointsRemaining, questBuilder.quest, goal.fact.entityType); if (pointsRemaining <= 0) { break; } } }
private void OnDespawned(QuestEntity entity) { if (entity != null) { entities.Remove(entity); entity.despawned -= OnDespawned; } }
public void AddEntity(QuestEntity entity) { if (entity != null && !entities.Contains(entity)) { entities.Add(entity); entity.despawned += OnDespawned; } }
public void GenerateQuest(QuestEntity entity, StringField group, DomainType domainType, WorldModel worldModel, bool requireReturnToComplete, List <QuestContent> rewardsUIContents, List <RewardSystem> rewardSystems, List <Quest> existingQuests, GeneratedQuestDelegate generatedQuest, UrgentFactSelectionMode goalSelectionMode) { if (entity == null || domainType == null || worldModel == null) { return; } coroutine = entity.StartCoroutine(GenerateQuestCoroutine(entity, group, domainType, worldModel, requireReturnToComplete, rewardsUIContents, rewardSystems, existingQuests, generatedQuest, goalSelectionMode)); }
/// <summary> /// Converts a plan generated by QuestGenerator into a quest. /// </summary> /// <param name="entity">Entity generating the quest (e.g., QuestGiver).</param> /// <param name="group">Optional quest group under which to categorize this quest.</param> /// <param name="goal">Final step to accomplish quest.</param> /// <param name="motive">Motive for the goal.</param> /// <param name="plan">Steps required to complete the goal step.</param> /// <param name="requireReturnToComplete">If true, add a quest node that requires quester to return to entity.</param> /// <param name="rewardsUIContents">UI content to show in the rewards offer section.</param> /// <param name="rewardSystems">Reward systems to use to </param> /// <returns></returns> public virtual Quest ConvertPlanToQuest(QuestEntity entity, StringField group, PlanStep goal, Motive motive, Plan plan, bool requireReturnToComplete, List <QuestContent> rewardsUIContents, List <RewardSystem> rewardSystems) { // Build title: var mainTargetEntity = goal.fact.entityType.name; var mainTargetDescriptor = goal.fact.entityType.GetDescriptor(goal.requiredCounterValue); var title = goal.action.displayName + " " + mainTargetDescriptor; var questID = title + " " + System.Guid.NewGuid(); var domainName = StringField.GetStringValue(goal.fact.domainType.displayName); // Start QuestBuilder: var questBuilder = new QuestBuilder(title, questID, title); SetMainInfo(questBuilder, questID, title, group, goal); AddTagsToDictionary(questBuilder.quest.tagDictionary, goal); // Offer: AddOfferText(questBuilder, mainTargetEntity, mainTargetDescriptor, domainName, goal, motive); var rewardsContentIndex = questBuilder.quest.offerContentList.Count; AddRewards(questBuilder, entity, goal, rewardsUIContents, rewardSystems); // Quest headings: AddQuestHeadings(questBuilder, goal); // Successful text (shown in journal / when talking again about successful quest): AddSuccessfulText(questBuilder, mainTargetEntity, mainTargetDescriptor, domainName, goal); // Add steps: var previousNode = AddSteps(questBuilder, domainName, goal, plan); // Add "return to giver" node: if (requireReturnToComplete) { previousNode = AddReturnNode(questBuilder, previousNode, entity, mainTargetEntity, mainTargetDescriptor, domainName, goal, rewardsContentIndex); } // Success node: questBuilder.AddSuccessNode(previousNode); return(questBuilder.ToQuest()); }
private IEnumerator GenerateQuestCoroutine(QuestEntity entity, StringField group, DomainType domainType, WorldModel worldModel, bool requireReturnToComplete, List <QuestContent> rewardsUIContents, List <RewardSystem> rewardSystems, List <Quest> existingQuests, GeneratedQuestDelegate generatedQuest, UrgentFactSelectionMode goalSelectionMode) { this.cancel = false; this.entity = entity; this.group = group; this.domainType = domainType; this.worldModel = worldModel; this.requireReturnToComplete = requireReturnToComplete; this.rewardsUIContents = rewardsUIContents; this.rewardSystems = rewardSystems; this.ignoreList = GenerateIgnoreList(existingQuests); this.goalSelectionMode = goalSelectionMode; masterStepList = new List <PlanStep>(); goal = null; plan = null; Quest quest = null; worldModel.observer = new Fact(domainType, entity.entityType, 1); yield return(DetermineGoal()); if (!(cancel || goal == null)) { yield return(GeneratePlan()); if (!(cancel || plan == null)) { BackfillMinimumCounterValues(); if (detailedDebug) { LogPlan(plan); } quest = planToQuestBuilder.ConvertPlanToQuest(entity, group, goal, motive, plan, requireReturnToComplete, rewardsUIContents, rewardSystems); } } generatedQuest(quest); }
/// <summary> /// Adds actions to set up the quest giver's quest indicators to the return node. /// </summary> protected virtual void AddReturnNodeIndicators(QuestBuilder questBuilder, QuestNode returnNode, List <QuestAction> actionList, QuestEntity entity) { // Indicator when active: var indicatorAction = questBuilder.CreateSetIndicatorAction(questBuilder.quest.id, entity.id, QuestIndicatorState.Talk); actionList.Add(indicatorAction); // Indicator when true: indicatorAction = questBuilder.CreateSetIndicatorAction(questBuilder.quest.id, entity.id, QuestIndicatorState.None); actionList = returnNode.GetStateInfo(QuestNodeState.True).actionList; actionList.Add(indicatorAction); }
/// <summary> /// Adds a final "return to quest giver" step. /// </summary> /// <returns>The return node.</returns> protected virtual QuestNode AddReturnNode(QuestBuilder questBuilder, QuestNode previousNode, QuestEntity entity, string mainTargetEntity, string mainTargetDescriptor, string domainName, PlanStep goal, int rewardsContentIndex = 9999) // Default to 9999 to not break any customer code using old signature. { var questGiver = entity.GetComponent <QuestGiver>(); var giverID = (questGiver != null) ? questGiver.id : ((entity != null) ? entity.displayName : null); var returnNode = questBuilder.AddDiscussQuestNode(previousNode, QuestMessageParticipant.QuestGiver, giverID); returnNode.id = new StringField("Return"); previousNode = returnNode; QuestStateInfo.ValidateStateInfoListCount(returnNode.stateInfoList); var hudText = "{Return to} " + questGiver.displayName; // Text when active: AddReturnNodeText(questBuilder, returnNode, questGiver, mainTargetEntity, mainTargetDescriptor, domainName, goal, hudText); // Add rewards content: var dialogueList = returnNode.stateInfoList[(int)QuestNodeState.Active].categorizedContentList[(int)QuestContentCategory.Dialogue]; var offerContentList = questBuilder.quest.offerContentList; for (int i = rewardsContentIndex; i < offerContentList.Count; i++) { var original = offerContentList[i]; var copy = QuestContent.Instantiate(original) as QuestContent; original.CloneSubassetsInto(copy); dialogueList.contentList.Add(copy); } var actionList = returnNode.GetStateInfo(QuestNodeState.Active).actionList; // Alert when active: AddReturnNodeAlert(questBuilder, returnNode, actionList, hudText); // Indicators: AddReturnNodeIndicators(questBuilder, returnNode, actionList, entity); return(previousNode); }
public void RemoveEntity(QuestEntity entity) { OnDespawned(entity); }