/// <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(); }
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(); } } }