示例#1
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            results = GameManager.instance.DetermineBattleOutcome(heroes, quest);
            Debug.Log(results);
        }


        if (Input.GetKeyDown(KeyCode.A))
        {
            GameManager.instance.uiManager.UpdateCharacterWindow(heroes[0]);
        }

        if (Input.GetKeyDown(KeyCode.Q))
        {
            StartCoroutine(TestMove());
        }
    }
示例#2
0
    public QuestOutcome DetermineBattleOutcome(List <HeroPawn> heroes, QuestData quest)
    {
        // Takes in party and quest, determines battle outcomes
        QuestOutcome results = new QuestOutcome();


        // Aggregate total party
        float heroAggregateHealth  = 0;
        float heroAggregateAttack  = 0;
        float heroAggregateDefense = 0;

        foreach (HeroPawn hero in heroes)
        {
            heroAggregateAttack  += ValueBasedOnDurability(hero.heroData.attack, hero.weaponCondition);
            heroAggregateDefense += ValueBasedOnDurability(hero.heroData.defense, hero.armorCondition);
            heroAggregateHealth  += hero.heroData.health;


            // Since durability hits EVERY fight, We can reduce durability here, and save us another iteration through heroes
            hero.weaponCondition -= Random.Range(quest.minDurabilityDamage, quest.maxDurabilityDamage);
            hero.armorCondition  -= Random.Range(quest.minDurabilityDamage, quest.maxDurabilityDamage);
        }

        // Add advantages -- be sure to check for monster changes
        foreach (HeroPawn hero in heroes)
        {
            float bonusModifier = 1.0f; // Start at full bonus

            // iterate through disadvantages
            bool foundDisadvantage = false;
            foreach (Disadvantage disadvantage in hero.heroData.disadvantages)
            {
                // iterate through monsters
                foreach (MonsterData monster in quest.monsters)
                {
                    // Iterate through each monsters set of types
                    foreach (MonsterTag tag in monster.modifiers)
                    {
                        // if we find one of those types in our disadvantage, note it and quit
                        if (disadvantage.against.Contains(tag))
                        {
                            // TODO: Add event about the disadvantage
                            Debug.Log(hero.heroData.displayName + " is terrified of the " + tag.displayName + " " + monster.displayName);

                            foundDisadvantage = true;
                            break;
                        }
                    }

                    // If I found a disadvantage, I don't need to look at other monsters
                    if (foundDisadvantage)
                    {
                        break;
                    }
                }

                // If I found a disadvantage, I don't need to look at other disadvantages
                if (foundDisadvantage)
                {
                    break;
                }
            }

            // If we found a disadvantage
            if (foundDisadvantage)
            {
                // create a bonus modifier based on average relationships
                bonusModifier = bonusEffectByRelationshipAverageCurve.Evaluate(AveragePartyRelationship(heroes) / maxRelationshipLevel);
            }
            // Otherwise, our bonus modifier is still 1.0
            else
            {
                bonusModifier = 1.0f;
            }

            // iterate through advantages
            foreach (Advantage advantage in hero.heroData.advantages)
            {
                //Apply "advantage.amount * modifier* and add to aggregates
                if (advantage.statistic == Stat.Attack)
                {
                    heroAggregateAttack += advantage.bonusAmount * bonusModifier;
                    Debug.Log("The power of friendship adds " + (advantage.bonusAmount * bonusModifier) + " | " + bonusModifier + " / " + advantage.bonusAmount + " attack.");
                }
                if (advantage.statistic == Stat.Health)
                {
                    heroAggregateHealth += advantage.bonusAmount * bonusModifier;
                    Debug.Log("The power of friendship adds " + (advantage.bonusAmount * bonusModifier) + " | " + bonusModifier + " / " + advantage.bonusAmount + " health.");
                }
                if (advantage.statistic == Stat.Defense)
                {
                    heroAggregateDefense += advantage.bonusAmount * bonusModifier;
                    Debug.Log("The power of friendship adds " + (advantage.bonusAmount * bonusModifier) + " | " + bonusModifier + " / " + advantage.bonusAmount + " defense.");
                }
            }
        }

        // NOTE: DO NOT CHANGE MONSTERS. Make temp monsters and change the temp ones
        float monsterAggregateHealth  = 0;
        float monsterAggregateAttack  = 0;
        float monsterAggregateDefense = 0;

        foreach (MonsterData monster in quest.monsters)
        {
            monsterAggregateAttack  += monster.attack;
            monsterAggregateDefense += monster.defense;
            monsterAggregateHealth  += monster.health;
        }


        // Track number of rounds
        int numberOfRounds = 0;

        // As long as the monsters are alive
        while (monsterAggregateHealth > 0)
        {
            // Increase round count
            numberOfRounds++;

            // Damage monsters
            float damageDone = Mathf.Max(1, (heroAggregateAttack * Random.Range(minHeroBattleChance, maxHeroBattleChance)) - (monsterAggregateDefense * Random.Range(minMonsterBattleChance, maxMonsterBattleChance)));
            monsterAggregateHealth -= damageDone;

            Debug.Log("The party does " + damageDone + " damage. The monster party has a total of " + monsterAggregateHealth + " health left!");


            // If monster dead, break.
            if (monsterAggregateHealth <= 0)
            {
                break;
            }


            // Damage players
            damageDone           = Mathf.Max(1, (monsterAggregateAttack * Random.Range(minMonsterBattleChance, maxMonsterBattleChance)) - (heroAggregateDefense * Random.Range(minHeroBattleChance, maxHeroBattleChance)));
            heroAggregateHealth -= damageDone;

            Debug.Log("The monster party does " + damageDone + " damage. The party has a total of " + heroAggregateHealth + " health left!");


            // If players dead, break
            if (heroAggregateHealth <= 0)
            {
                break;
            }
        }

        // If monsters are dead, success.
        if (monsterAggregateHealth <= 0)
        {
            // Add gold to all players
            foreach (HeroPawn hero in heroes)
            {
                // Divide gold among heroes, leftovers are destroyed into the ether
                hero.gold += (int)(quest.goldReward / heroes.Count);

                //Update relationships
                foreach (HeroPawn otherHero in heroes)
                {
                    if (otherHero != hero)
                    {
                        // Find where they are in the main heroes list
                        int heroID = 0;
                        for (int i = 0; i < GameManager.instance.heroes.Count; i++)
                        {
                            if (otherHero != hero && otherHero == GameManager.instance.heroes[i])
                            {
                                heroID = i;
                                break;
                            }
                        }

                        hero.relationships[heroID] += increaseToRelationshipPerMission;
                        Debug.Log(hero.heroData.displayName + " and " + GameManager.instance.heroes[heroID].heroData.displayName + " high five.");
                    }
                }
            }

            // Add success events to the event list
            // TODO: Don't do one per round, that's too many. Maybe one per person.
            for (int i = 0; i < numberOfRounds; i++)
            {
                // Pick a random hero
                HeroPawn chosenOne = heroes[Random.Range(0, heroes.Count)];

                // TODO: Pick a random string from the hero's success events
                string eventString = chosenOne.name + " stabs the vile beast in the face.";

                // TODO: Add the finalized (no variables) version of that string to the list of outcome events.
                results.events.Add(eventString);
            }
        }
        // Else failed mission
        else
        {
            // No change to relationships
            // No change to gold

            // Add fail events to the event list
            // TODO: Don't do one per round, that's too many. Maybe one per person.
            for (int i = 0; i < numberOfRounds; i++)
            {
                // Pick a random hero
                HeroPawn chosenOne = heroes[Random.Range(0, heroes.Count)];

                // TODO: Pick a random string from the hero's success events
                string eventString = chosenOne.name + " stumbles.";

                // TODO: Add the finalized (no variables) version of that string to the list of outcome events.
                results.events.Add(eventString);
            }
        }

        return(results);
    }
示例#3
0
    public IEnumerator DoRunQuests()
    {
        Debug.Log("Starting to Run Quests");

        // Turn on the results screen
        uiManager.OpenWindow(uiManager.QuestOutcomeDisplay);
        uiManager.OpenWindow(uiManager.MainGameButton);

        List <QuestObject> questsToRemove = new List <QuestObject>();

        // For each quest that were available today
        foreach (QuestObject quest in shop.todaysQuests)
        {
            // If it has people assigned
            if (quest.heroes != null && quest.heroes.Count > 0)
            {
                // Disable the button
                nextStepButton.interactable = false;
                nextStepButtonText.text     = "... Fighting! ...";

                isWaitingForButton = true;

                // Calculate the results
                QuestOutcome results = DetermineBattleOutcome(quest.heroes, quest.questData);

                // TODO: coroutine to Update the quest screen to show results over time.
                uiManager.combatQuestTitleBox.text = "Results: " + quest.questData.displayName;
                uiManager.combatEventsLog.text     = "";

                foreach (string outcomeEvent in results.events)
                {
                    // Wait some time.
                    yield return(new WaitForSeconds(0.5f));

                    // Display the text
                    uiManager.combatEventsLog.text += outcomeEvent + "\n";
                }

                yield return(new WaitForSeconds(0.5f));

                if (results.success)
                {
                    uiManager.outcomeSummaryLineBox.text = "The party was victorious!";
                }
                else
                {
                    uiManager.outcomeSummaryLineBox.text = "The party was defeated!";
                }

                isWaitingForButton = true;

                nextStepButtonText.text     = "Continue";
                nextStepButton.interactable = true;
                nextStepButton.onClick.RemoveAllListeners();
                nextStepButton.onClick.AddListener(StopWaitingForButton);

                // Queue to Remove from today's quests
                questsToRemove.Add(quest);

                // Wait for button
                while (isWaitingForButton)
                {
                    yield return(null);
                }
            }
        }

        // Actually handle the removals
        foreach (QuestObject quest in questsToRemove)
        {
            shop.todaysQuests.Remove(quest);
        }

        // ACTUALLY THE END OF THE DAY
        turnsRemaining--;

        if (turnsRemaining > 0)
        {
            // TODO: SHOW THE END OF DAY IMAGE
            // Turn on the results screen
            uiManager.CloseCurrentWindow();
            uiManager.OpenWindow(uiManager.EndOfDayScreen);
            uiManager.OpenWindow(uiManager.MainGameButton);

            // TODO: Set text to say "DAYS REMAINING..." + days
            uiManager.endOfDayText.text = "Another day has ended... " + turnsRemaining + "days remain...";

            // Enable the button
            nextStepButton.interactable = true;
            nextStepButtonText.text     = "Start Next Day";

            // Wait for button
            isWaitingForButton = true;
            while (isWaitingForButton)
            {
                yield return(null);
            }

            // Turn off the end of day text
            uiManager.CloseCurrentWindow();

            // Move all characters offscreen on right side
            foreach (HeroPawn hero in heroes)
            {
                hero.transform.position = new Vector3(10, 0, 0);
            }

            // TODO: FIX THIS HARDCODING! THIS IS BAD!
            uiManager.EndOfDayScreen.SetActive(false);
            uiManager.QuestOutcomeDisplay.SetActive(false);
            uiManager.OpenWindow(uiManager.MainGameButton);

            // Start the day
            StartDay();
        }


        yield return(null);
    }