/// <summary>
        /// Gets a random armor material based on player level.
        /// </summary>
        /// <param name="playerLevel">Player level.</param>
        /// <returns>ArmorMaterialTypes.</returns>
        public static ArmorMaterialTypes RandomArmorMaterial(int playerLevel)
        {
            // Random armor material
            int roll = Dice100.Roll();

            if (roll >= 70)
            {
                if (roll >= 90)
                {
                    WeaponMaterialTypes plateMaterial = RandomMaterial(playerLevel);
                    return((ArmorMaterialTypes)(0x0200 + plateMaterial));
                }
                else
                {
                    return(ArmorMaterialTypes.Chain);
                }
            }
            else
            {
                return(ArmorMaterialTypes.Leather);
            }
        }
        /// <summary>
        /// Updates enemy state based on current settings.
        /// Called automatially by SetEnemyType().
        /// This should be called after changing enemy state (e.g. from in code or in editor).
        /// </summary>
        private void ApplyEnemyState()
        {
            // Get state animations
            summary.StateAnims = GetStateAnims(summary.EnemyState);
            if (summary.EnemyState == MobileStates.PrimaryAttack)
            {
                int random = Dice100.Roll();

                if (random <= summary.Enemy.ChanceForAttack2)
                {
                    summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames2;
                }
                else
                {
                    random -= summary.Enemy.ChanceForAttack2;
                    if (random <= summary.Enemy.ChanceForAttack3)
                    {
                        summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames3;
                    }
                    else
                    {
                        random -= summary.Enemy.ChanceForAttack3;
                        if (random <= summary.Enemy.ChanceForAttack4)
                        {
                            summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames4;
                        }
                        else
                        {
                            random -= summary.Enemy.ChanceForAttack4;
                            if (random <= summary.Enemy.ChanceForAttack5)
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames5;
                            }
                            else
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames;
                            }
                        }
                    }
                }

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.RangedAttack1 || summary.EnemyState == MobileStates.RangedAttack2)
            {
                summary.StateAnimFrames = summary.Enemy.RangedAttackAnimFrames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.Spell)
            {
                summary.StateAnimFrames = summary.Enemy.SpellAnimFrames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.SeducerTransform1)
            {
                // Switch to flying sprite alignment while crouched and growing wings
                summary.Enemy.Behaviour = MobileBehaviour.Flying;
                summary.StateAnimFrames = summary.Enemy.SeducerTransform1Frames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.SeducerTransform2)
            {
                // Switch to grounded sprite alignment while standing and spreading wings
                summary.Enemy.Behaviour = MobileBehaviour.General;
                summary.StateAnimFrames = summary.Enemy.SeducerTransform2Frames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.StateAnims == null)
            {
                // Log error message
                DaggerfallUnity.LogMessage(string.Format("DaggerfalMobileUnit: Enemy does not have animation for {0} state. Defaulting to Idle state.", summary.EnemyState.ToString()), true);

                // Set back to idle (which every enemy has in one form or another)
                summary.EnemyState = MobileStates.Idle;
                summary.StateAnims = GetStateAnims(summary.EnemyState);
            }

            // One of the frost daedra's sets of attack frames starts with the hit frame (-1), so we need to check for that right away before updating orientation.
            if (currentFrame == -1 && summary.EnemyState == MobileStates.PrimaryAttack)
            {
                doMeleeDamage = true;
                if (frameIterator < summary.StateAnimFrames.Length)
                {
                    currentFrame = summary.StateAnimFrames[frameIterator++];
                }
            }

            // Orient enemy relative to camera
            UpdateOrientation();
        }
Beispiel #3
0
        private void DebateLie_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton)
        {
            sender.CloseWindow();
            int playerSkill = 0;

            if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Debate)
            {
                playerSkill = playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.Etiquette);
                playerEntity.TallySkill(DFCareer.Skills.Etiquette, 1);
            }
            else
            {
                playerSkill = playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.Streetwise);
                playerEntity.TallySkill(DFCareer.Skills.Streetwise, 1);
            }

            int chanceToGoFree = playerEntity.RegionData[regionIndex].LegalRep +
                                 (playerSkill + playerEntity.Stats.GetLiveStatValue(DFCareer.Stats.Personality)) / 2;

            if (chanceToGoFree > 95)
            {
                chanceToGoFree = 95;
            }
            else if (chanceToGoFree < 5)
            {
                chanceToGoFree = 5;
            }

            if (Dice100.FailedRoll(chanceToGoFree))
            {
                // Banishment
                if (punishmentType == 0)
                {
                    state = 4;
                }
                // Execution
                else if (punishmentType == 1)
                {
                    state = 5;
                }
                // Prison/Fine
                else
                {
                    int roll = playerEntity.RegionData[regionIndex].LegalRep + Dice100.Roll();
                    if (roll < 25)
                    {
                        fine *= 2;
                    }
                    else if (roll > 75)
                    {
                        fine >>= 1;
                    }

                    state = 2;
                }
            }
            else
            {
                DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, this, false, 149);
                messageBox.SetTextTokens(DaggerfallUnity.Instance.TextProvider.GetRSCTokens(courtTextFreeToGo));
                messageBox.ScreenDimColor = new Color32(0, 0, 0, 0);
                messageBox.ParentPanel.VerticalAlignment = VerticalAlignment.Bottom;
                messageBox.ClickAnywhereToClose          = true;
                messageBox.AllowCancel = false;
                uiManager.PushWindow(messageBox);

                // Oversight in classic: Does not refill vital signs when releasing in this case, so player is left with 1 health.
                // Also does not repair reputation.
                playerEntity.FillVitalSigns();
                playerEntity.RaiseReputationForDoingSentence();
                state = 6;
            }
            Update();
        }
        private void ConfirmSummon_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton)
        {
            sender.CloseWindow();
            if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Yes)
            {
                PlayerEntity playerEntity = GameManager.Instance.PlayerEntity;
                int          summonCost   = FormulaHelper.CalculateDaedraSummoningCost(summonerFactionData.rep);

                if (playerEntity.GetGoldAmount() >= summonCost)
                {
                    playerEntity.DeductGoldAmount(summonCost);

                    WeatherManager weatherManager = GameManager.Instance.WeatherManager;

                    // Sheogorath has a 5% (15% if stormy) chance to replace selected daedra.
                    int sheoChance = (weatherManager.IsStorming) ? 15 : 5;
                    if (Dice100.Roll() <= sheoChance)
                    {
                        daedraToSummon = daedraData[8];
                    }

                    // Default 30% bonus is only applicable to some Daedra in specific weather conditions.
                    int bonus = 0;
                    if (daedraToSummon.bonusCond == Weather.WeatherType.Rain && weatherManager.IsRaining ||
                        daedraToSummon.bonusCond == Weather.WeatherType.Thunder && weatherManager.IsStorming ||
                        daedraToSummon.bonusCond == Weather.WeatherType.None)
                    {
                        bonus = 30;
                    }

                    // Get summoning chance for selected daedra and roll.
                    int chance = FormulaHelper.CalculateDaedraSummoningChance(playerEntity.FactionData.GetReputation(daedraToSummon.factionId), bonus);
                    int roll   = Dice100.Roll();
                    Debug.LogFormat("Summoning {0} with chance = {1}%, Sheogorath chance = {2}%, roll = {3}, summoner rep = {4}, cost: {5}",
                                    daedraToSummon.vidFile.Substring(0, daedraToSummon.vidFile.Length - 4), chance, sheoChance, roll, summonerFactionData.rep, summonCost);

                    if (roll > chance)
                    {   // Daedra stood you up!
                        DaggerfallUI.MessageBox(SummonFailed, this);
                        // Spawn daedric foes if failed at a witches coven.
                        if (summonerFactionData.ggroup == (int)FactionFile.GuildGroups.Witches)
                        {
                            GameObjectHelper.CreateFoeSpawner(true, daedricFoes[Random.Range(0, 5)], Random.Range(1, 4), 4, 64);
                        }
                        return;
                    }

                    // Has this Daedra already been summoned by the player?
                    if (playerEntity.FactionData.GetFlag(daedraToSummon.factionId, FactionFile.Flags.Summoned))
                    {
                        // Close menu and push DaggerfallDaedraSummoningWindow here for video and dismissal..
                        CloseWindow();
                        uiManager.PushWindow(UIWindowFactory.GetInstanceWithArgs(UIWindowType.DaedraSummoned, new object[] { uiManager, daedraToSummon, SummonBefore, this }));
                    }
                    else
                    {   // Record the summoning.
                        playerEntity.FactionData.SetFlag(daedraToSummon.factionId, FactionFile.Flags.Summoned);

                        // Offer the quest to player.
                        offeredQuest = GameManager.Instance.QuestListsManager.GetQuest(daedraToSummon.quest, summonerFactionData.id);
                        if (offeredQuest != null)
                        {
                            // Close menu and push DaggerfallDaedraSummoningWindow here for video and custom quest offer..
                            CloseWindow();
                            uiManager.PushWindow(UIWindowFactory.GetInstanceWithArgs(UIWindowType.DaedraSummoned, new object[] { uiManager, daedraToSummon, offeredQuest }));
                        }
                    }
                }
                else
                {   // Display customised not enough gold message so players don't need to guess the cost.
                    TextFile.Token[] notEnoughGold = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(DaggerfallTradeWindow.NotEnoughGoldId);
                    TextFile.Token[] msg           = new TextFile.Token[] {
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.Text, text = TextManager.Instance.GetLocalizedText("serviceSummonCost1")
                        },
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.JustifyCenter
                        },
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.Text, text = TextManager.Instance.GetLocalizedText("serviceSummonCost2") + summonCost + TextManager.Instance.GetLocalizedText("serviceSummonCost3")
                        },
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.JustifyCenter
                        },
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.NewLine
                        },
                        notEnoughGold[0],
                        new TextFile.Token()
                        {
                            formatting = TextFile.Formatting.JustifyCenter
                        },
                    };
                    DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, uiManager.TopWindow);
                    messageBox.SetTextTokens(msg, this);
                    messageBox.ClickAnywhereToClose = false;
                    messageBox.Show();
                }
            }
        }