// Calculate how much health the player should recover per hour of rest public static int CalculateHealthRecoveryRate(Entity.PlayerEntity player) { short medical = player.Skills.GetLiveSkillValue(DFCareer.Skills.Medical); int endurance = player.Stats.LiveEndurance; int maxHealth = player.MaxHealth; PlayerEnterExit playerEnterExit; playerEnterExit = GameManager.Instance.PlayerGPS.GetComponent <PlayerEnterExit>(); DFCareer.RapidHealingFlags rapidHealingFlags = player.Career.RapidHealing; short addToMedical = 60; if (rapidHealingFlags == DFCareer.RapidHealingFlags.Always) { addToMedical = 100; } else if (DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.IsDay && !playerEnterExit.IsPlayerInside) { if (rapidHealingFlags == DFCareer.RapidHealingFlags.InLight) { addToMedical = 100; } } else if (rapidHealingFlags == DFCareer.RapidHealingFlags.InDarkness) { addToMedical = 100; } medical += addToMedical; return(Mathf.Max((int)Mathf.Floor(HealingRateModifier(endurance) + medical * maxHealth / 1000), 1)); }
protected override void Setup() { // Load native texture nativeTexture = DaggerfallUI.GetTextureFromImg(nativeImgName); if (!nativeTexture) { throw new Exception("DaggerfallCourtWindow: Could not load native texture."); } // Native court panel courtPanel.HorizontalAlignment = HorizontalAlignment.Center; courtPanel.Size = TextureReplacement.GetSize(nativeTexture, nativeImgName); courtPanel.BackgroundTexture = nativeTexture; NativePanel.Components.Add(courtPanel); // Cancel any camera recoil RaiseOnCourtScreenEvent(); // Add days until freedom label daysUntilFreedomLabel = DaggerfallUI.AddTextLabel(DaggerfallUI.DefaultFont, new Vector2(156, 165), string.Empty, NativePanel); daysUntilFreedomLabel.TextColor = DaggerfallUI.DaggerfallPrisonDaysUntilFreedomColor; daysUntilFreedomLabel.ShadowColor = DaggerfallUI.DaggerfallPrisonDaysUntilFreedomShadowColor; daysUntilFreedomLabel.HorizontalAlignment = HorizontalAlignment.Center; playerEntity = GameManager.Instance.PlayerEntity; AllowCancel = false; }
public static int CalculateTradePrice(int cost, int shopQuality, bool selling) { Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; int merchant_mercantile_level = 5 * (shopQuality - 10) + 50; int merchant_personality_level = 5 * (shopQuality - 10) + 50; int delta_mercantile; int delta_personality; int amount = 0; if (selling) { delta_mercantile = (((100 - merchant_mercantile_level) << 8) / 200 + 128) * (((player.Skills.GetLiveSkillValue(DFCareer.Skills.Mercantile)) << 8) / 200 + 128) >> 8; delta_personality = (((100 - merchant_personality_level) << 8) / 200 + 128) * ((player.Stats.LivePersonality << 8) / 200 + 128) >> 8; amount = ((((179 * delta_mercantile) >> 8) + ((51 * delta_personality) >> 8)) * cost) >> 8; } else // buying { delta_mercantile = ((merchant_mercantile_level << 8) / 200 + 128) * (((100 - (player.Skills.GetLiveSkillValue(DFCareer.Skills.Mercantile))) << 8) / 200 + 128) >> 8; delta_personality = ((merchant_personality_level << 8) / 200 + 128) * (((100 - player.Stats.LivePersonality) << 8) / 200 + 128) >> 8 << 6; amount = ((((192 * delta_mercantile) >> 8) + (delta_personality >> 8)) * cost) >> 8; } return(amount); }
/// <summary> /// Removes items that have expired. Used for magically-created items. Only for the player. /// Note: Reverse-engineering suggests this was intended behavior in classic, but classic /// does not correctly set the item flags so magically-created items never disappear. /// </summary> public void RemoveExpiredItems() { uint gameMinutes = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime(); List <DaggerfallUnityItem> itemsToRemove = new List <DaggerfallUnityItem>(); foreach (DaggerfallUnityItem item in items.Values) { if (item.TimeForItemToDisappear != 0 && item.TimeForItemToDisappear < gameMinutes) { Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; foreach (EquipSlots slotToCheck in Enum.GetValues(typeof(EquipSlots))) { if (player.ItemEquipTable.GetItem(slotToCheck) == item) { player.ItemEquipTable.UnequipItem(slotToCheck); } } itemsToRemove.Add(item); } } foreach (DaggerfallUnityItem item in itemsToRemove) { RemoveItem(item); } }
// Create by item class and subclass DaggerfallUnityItem CreateItem(int itemClass, int itemSubClass) { // Validate if (itemClass == -1) { throw new Exception(string.Format("Tried to create Item with class {0}", itemClass)); } DaggerfallUnityItem result; // Handle random magic items if (itemClass == (int)ItemGroups.MagicItems && itemSubClass == -1) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; result = ItemBuilder.CreateRandomMagicItem(playerEntity.Level, playerEntity.Gender, playerEntity.Race); } else { // Handle random subclass if (itemSubClass == -1) { Array enumArray = DaggerfallUnity.Instance.ItemHelper.GetEnumArray((ItemGroups)itemClass); itemSubClass = UnityEngine.Random.Range(0, enumArray.Length); } // Create item result = new DaggerfallUnityItem((ItemGroups)itemClass, itemSubClass); } // Link item to quest result.LinkQuestItem(ParentQuest.UID, Symbol.Clone()); return(result); }
// Create stack of gold pieces DaggerfallUnityItem CreateGold(int rangeLow, int rangeHigh) { // Get amount int amount = 0; if (rangeLow == -1 || rangeHigh == -1) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; int playerMod = (playerEntity.Level / 2) + 1; int factionMod = 50; IGuild guild = null; if (ParentQuest.FactionId != 0) { guild = GameManager.Instance.GuildManager.GetGuild(ParentQuest.FactionId); if (guild != null && !(guild is NonMemberGuild)) { // If this is a faction quest, playerMod is (player factionrank + 1) rather than level playerMod = guild.Rank + 1; // If this is a faction quest, factionMod = faction.power rather than 50 FactionFile.FactionData factionData; if (playerEntity.FactionData.GetFactionData(ParentQuest.FactionId, out factionData)) { factionMod = factionData.power; } } } if (playerMod > 10) { playerMod = 10; } PlayerGPS gps = GameManager.Instance.PlayerGPS; int regionPriceMod = playerEntity.RegionData[gps.CurrentRegionIndex].PriceAdjustment / 2; amount = UnityEngine.Random.Range(150 * playerMod, (200 * playerMod) + 1) * (regionPriceMod + 500) / 1000 * (factionMod + 50) / 100; if (guild != null) { amount = guild.AlterReward(amount); } } else { amount = UnityEngine.Random.Range(rangeLow, rangeHigh + 1); } if (amount < 1) { amount = 1; } // Create item DaggerfallUnityItem result = new DaggerfallUnityItem(ItemGroups.Currency, 0); result.stackCount = amount; result.LinkQuestItem(ParentQuest.UID, Symbol.Clone()); return(result); }
public PlayerControllerPresenter Init(Entity.PlayerEntity playerEntity) { _playerModel = new PlayerModel(playerEntity); _gunModel = new GunModel(playerEntity.BulletEntity); Bind(); DebugInit(); return(this); }
// Create by item class and subclass DaggerfallUnityItem CreateItem(int itemClass, int itemSubClass, int itemKey = -1) { // Validate if (itemClass == -1) { throw new Exception(string.Format("Tried to create Item with class {0}", itemClass)); } DaggerfallUnityItem result; // Handle random magic items if (itemClass == (int)ItemGroups.MagicItems) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; result = ItemBuilder.CreateRegularMagicItem(itemSubClass, playerEntity.Level, playerEntity.Gender, playerEntity.Race); } // Handle books else if (itemClass == (int)ItemGroups.Books) { result = (itemKey != -1) ? ItemBuilder.CreateBook(itemKey) : ItemBuilder.CreateRandomBook(); } // Handle potions else if (itemClass == (int)ItemGroups.UselessItems1 && itemSubClass == 1) { result = (itemKey != -1) ? ItemBuilder.CreatePotion(itemKey) : ItemBuilder.CreateRandomPotion(); } else { // Handle random subclass if (itemSubClass == -1) { Array enumArray = DaggerfallUnity.Instance.ItemHelper.GetEnumArray((ItemGroups)itemClass); itemSubClass = UnityEngine.Random.Range(0, enumArray.Length); } // Create item result = new DaggerfallUnityItem((ItemGroups)itemClass, itemSubClass); } // Link item to quest result.LinkQuestItem(ParentQuest.UID, Symbol.Clone()); string name = result.shortName.Replace("%it", result.ItemTemplate.name); QuestMachine.LogFormat( ParentQuest, "Generated \"{0}\" from Class {1} and Subclass {2} for item {3}", name, itemClass, itemSubClass, Symbol.Original ); return(result); }
// Calculate chance of successfully pickpocketing a target public static int CalculatePickpocketingChance(Entity.PlayerEntity player, Entity.EnemyEntity target) { int chance = player.Skills.Pickpocket; // If target is an enemy mobile, apply level modifier. if (target != null) { chance += 5 * ((player.Level) - (target.Level)); } return(Mathf.Clamp(chance, 5, 95)); }
public override void Dispose() { base.Dispose(); // Remove item if present in player item collections and still marked as a quest item if (item != null && item.IsQuestItem) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; playerEntity.Items.RemoveItem(item); } }
// Calculate chance of successfully pickpocketing a target public static int CalculatePickpocketingChance(Entity.PlayerEntity player, Entity.DaggerfallEntityBehaviour target) { int chance = player.Skills.Pickpocket; // If target is an enemy mobile, apply level modifier. if (target) { Entity.EnemyEntity enemyEntity = target.Entity as Entity.EnemyEntity; chance += 5 * ((player.Level) - (enemyEntity.Level)); } return(Mathf.Clamp(chance, 5, 95)); }
/// <summary> /// Reset all reputations and legal reputations back to 0 (and resets from FACTION.TXT). /// </summary> public void ZeroAllReputations() { // Reset faction reputations Reset(); // Reset legal reputations Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; for (int i = 0; i < player.RegionData.Length; i++) { player.RegionData[i].LegalRep = 0; } }
/// <summary> /// Looks for orphaned items (e.g. quest no longer active or invalid template) remaining in player item collections. /// </summary> void RemoveAllOrphanedItems() { int count = 0; Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; count += playerEntity.Items.RemoveOrphanedItems(); count += playerEntity.WagonItems.RemoveOrphanedItems(); count += playerEntity.OtherItems.RemoveOrphanedItems(); if (count > 0) { Debug.LogFormat("Removed {0} orphaned items.", count); } }
// Calculate hit points player gains per level. public static int CalculateHitPointsPerLevelUp(Entity.PlayerEntity player) { int minRoll = player.Career.HitPointsPerLevelOrMonsterLevel / 2; int maxRoll = player.Career.HitPointsPerLevelOrMonsterLevel + 1; // Adding +1 as Unity Random.Range(int,int) is exclusive of maximum value int addHitPoints = UnityEngine.Random.Range(minRoll, maxRoll); addHitPoints += HitPointsModifier(player.Stats.Endurance); if (addHitPoints < 1) { addHitPoints = 1; } return(addHitPoints); }
protected override void Setup() { // Load native texture nativeTexture = DaggerfallUI.GetTextureFromImg(nativeImgName); if (!nativeTexture) { throw new Exception("DaggerfallCourtWindow: Could not load native texture."); } // Native court panel courtPanel.HorizontalAlignment = HorizontalAlignment.Center; courtPanel.Size = TextureReplacement.GetSize(nativeTexture, nativeImgName); courtPanel.BackgroundTexture = nativeTexture; NativePanel.Components.Add(courtPanel); playerEntity = GameManager.Instance.PlayerEntity; state = 0; }
// Create stack of gold pieces DaggerfallUnityItem CreateGold(int rangeLow, int rangeHigh) { // Get amount int amount = 0; if (rangeLow == -1 || rangeHigh == -1) { Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; // TODO: If this is a faction quest, playerMod is (player factionrank + 1) rather than level int playerMod = (player.Level / 2) + 1; if (playerMod > 10) { playerMod = 10; } // TODO: If this is a faction quest, factionMod = faction.power rather than 50 int factionMod = 50; PlayerGPS gps = GameManager.Instance.PlayerGPS; int regionPriceMod = player.RegionData[gps.CurrentRegionIndex].PriceAdjustment / 2; amount = UnityEngine.Random.Range(150 * playerMod, (200 * playerMod) + 1) * (regionPriceMod + 500) / 1000 * (factionMod + 50) / 100; } else { amount = UnityEngine.Random.Range(rangeLow, rangeHigh + 1); } if (amount < 1) { amount = 1; } // Create item DaggerfallUnityItem result = new DaggerfallUnityItem(ItemGroups.Currency, 0); result.stackCount = amount; result.LinkQuestItem(ParentQuest.UID, Symbol.Clone()); return(result); }
// Calculate whether the player is successful at pacifying an enemy. public static bool CalculateEnemyPacification(Entity.PlayerEntity player, DFCareer.Skills languageSkill) { double chance = 0; if (languageSkill == DFCareer.Skills.Etiquette || languageSkill == DFCareer.Skills.Streetwise) { chance += player.Skills.GetLiveSkillValue(languageSkill) / 10; chance += player.Stats.LivePersonality / 5; } else { chance += player.Skills.GetLiveSkillValue(languageSkill); chance += player.Stats.LivePersonality / 10; } chance += GameManager.Instance.WeaponManager.Sheathed ? 10 : -25; chance += player.Stats.LiveLuck / 5; // BCHG: luck is not part of formula on uesp, not checked in classic code int roll = UnityEngine.Random.Range(0, 145); // Max ~96.5% chance for 100% skill + per + luck and sheathed weapon. Debug.LogFormat("Pacification {3} using {0} skill: chance= {1} roll= {2}", languageSkill, chance, roll, (roll < chance) ? "success" : "failure"); return(roll < chance); }
protected void ConfirmGettingScammed_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton) { int playerIntell = player.Stats.LiveIntelligence; if (LimitedGoldShops.LimitedGoldShops.ShopBuildingData.TryGetValue(currentBuildingID, out sd)) { investedFlag = sd.InvestedIn; shopAttitude = sd.ShopAttitude; } CloseWindow(); if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Yes) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; if (playerEntity.GetGoldAmount() >= investOffer) { playerEntity.DeductGoldAmount(investOffer); DaggerfallUI.Instance.PlayOneShot(SoundClips.GoldPieces); tokens = LGSTextTokenHolder.ShopTextTokensNeutral(3); if (investedFlag) { tokens = LGSTextTokenHolder.ShopTextTokensNeutral(4); } DaggerfallUI.MessageBox(tokens); investOffer = 0; LimitedGoldShops.LimitedGoldShops.UpdateInvestAmount(investOffer); } else { DaggerfallUI.MessageBox("Good joke there, you really got me there, ya jerk..."); } } else if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.No) { DaggerfallUI.MessageBox("Yeah, I was just joking as well, haha..."); } }
public static int ApplyRegionalPriceAdjustment(int cost) { int adjustedCost; int currentRegionIndex; Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; PlayerGPS gps = GameManager.Instance.PlayerGPS; if (gps.HasCurrentLocation) { currentRegionIndex = gps.CurrentRegionIndex; } else { return(cost); } adjustedCost = cost * player.RegionData[currentRegionIndex].PriceAdjustment / 1000; if (adjustedCost < 1) { adjustedCost = 1; } return(adjustedCost); }
public static int CalculateWeaponDamage(Entity.DaggerfallEntity attacker, Entity.DaggerfallEntity target, FPSWeapon onscreenWeapon) { if (attacker == null || target == null) { return(0); } int damageLow = 0; int damageHigh = 0; int damageModifiers = 0; int baseDamage = 0; int damageResult = 0; int chanceToHitMod = 0; Items.DaggerfallUnityItem weapon = null; Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; Entity.EnemyEntity AIAttacker = null; Entity.EnemyEntity AITarget = null; if (attacker != player) { AIAttacker = attacker as Entity.EnemyEntity; } if (target != player) { AITarget = target as Entity.EnemyEntity; } // TODO: Get weapons of enemy classes and monsters. if (attacker == player) { if (GameManager.Instance.WeaponManager.UsingRightHand) { weapon = attacker.ItemEquipTable.GetItem(Items.EquipSlots.RightHand); } else { weapon = attacker.ItemEquipTable.GetItem(Items.EquipSlots.LeftHand); } } // If the player is attacking with no weapon equipped, use hand-to-hand skill for damage if (weapon == null && attacker == player) { damageLow = CalculateHandToHandMinDamage(attacker.Skills.HandToHand); damageHigh = CalculateHandToHandMaxDamage(attacker.Skills.HandToHand); chanceToHitMod = attacker.Skills.HandToHand; } // If a monster is attacking, use damage values from enemy definitions else if (weapon == null && AIAttacker != null) { damageLow = AIAttacker.MobileEnemy.MinDamage; damageHigh = AIAttacker.MobileEnemy.MaxDamage; chanceToHitMod = attacker.Skills.HandToHand; } // If the player is attacking with a weapon equipped, use the weapon's damage else if (attacker == player) { damageLow = weapon.GetBaseDamageMin(); damageHigh = weapon.GetBaseDamageMax(); short skillID = weapon.GetWeaponSkillID(); chanceToHitMod = attacker.Skills.GetSkillValue(skillID); } baseDamage = UnityEngine.Random.Range(damageLow, damageHigh + 1); if (onscreenWeapon != null && (attacker == player)) { // Apply swing modifiers for player. // The Daggerfall manual groups diagonal slashes to the left and right as if they are the same, but they are different. // Classic does not apply swing modifiers to hand-to-hand. if (onscreenWeapon.WeaponState == WeaponStates.StrikeUp) { damageModifiers += -4; chanceToHitMod += 10; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownRight) { damageModifiers += -2; chanceToHitMod += 5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownLeft) { damageModifiers += 2; chanceToHitMod += -5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDown) { damageModifiers += 4; chanceToHitMod += -10; } } // Apply weapon proficiency modifiers for player. if ((attacker == player) && weapon != null && ((int)attacker.Career.ExpertProficiencies & weapon.GetWeaponSkillUsed()) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } // Apply hand-to-hand proficiency modifiers for player. Hand-to-hand proficiencty is not applied in classic. else if ((attacker == player) && weapon == null && ((int)attacker.Career.ExpertProficiencies & (int)(DaggerfallConnect.DFCareer.ProficiencyFlags.HandToHand)) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } // Apply modifiers for Skeletal Warrior. // In classic these appear to be applied after the swing and weapon proficiency modifiers but before all other // damage modifiers. Doing the same here. // DF Chronicles just says "Edged weapons inflict 1/2 damage" if (weapon != null && (target != player) && AITarget.CareerIndex == (int)Entity.MonsterCareers.SkeletalWarrior) { if (weapon.NativeMaterialValue == (int)Items.WeaponMaterialTypes.Silver) { baseDamage *= 2; damageModifiers *= 2; } if (weapon.GetWeaponSkillUsed() != (int)DaggerfallConnect.DFCareer.ProficiencyFlags.BluntWeapons) { baseDamage /= 2; damageModifiers /= 2; } } // Apply bonus or penalty by opponent type. // In classic this is broken and only works if the attack is done with a weapon that has the maximum number of enchantments. if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Undead)) { if (((int)attacker.Career.UndeadAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.UndeadAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Daedra)) { if (((int)attacker.Career.DaedraAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.DaedraAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Humanoid)) { if (((int)attacker.Career.HumanoidAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.HumanoidAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Animals)) { if (((int)attacker.Career.AnimalsAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.AnimalsAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } // Apply racial modifiers for player. if ((attacker == player) && weapon != null) { if (player.RaceTemplate.ID == (int)Entity.Races.DarkElf) { damageModifiers += (attacker.Level / 4); chanceToHitMod += (attacker.Level / 4); } else if (weapon.GetWeaponSkillUsed() == (int)DaggerfallConnect.DFCareer.ProficiencyFlags.MissileWeapons) { if (player.RaceTemplate.ID == (int)Entity.Races.WoodElf) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } else if (player.RaceTemplate.ID == (int)Entity.Races.Redguard) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } // Apply strength modifier for player or for AI characters using weapons. // The in-game display of the strength modifier in Daggerfall is incorrect. It is actually ((STR - 50) / 5). if ((attacker == player) || (weapon != null)) { damageModifiers += DamageModifier(attacker.Stats.Strength); } // Apply material modifier. // The in-game display in Daggerfall of weapon damages with material modifiers is incorrect. The material modifier is half of what the display suggests. if (weapon != null) { damageModifiers += weapon.GetWeaponMaterialModifier(); } // Check for a successful hit. if (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon) == true) { // 0 damage is possible. Creates no blood splash. damageResult = Mathf.Max(0, (baseDamage + damageModifiers)); } // If attack was by player or weapon-based, end here if ((attacker == player) || (weapon != null)) { return(damageResult); } // Handle multiple attacks by AI characters. else { if (AIAttacker.MobileEnemy.MaxDamage2 != 0 && (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon) == true)) { baseDamage = UnityEngine.Random.Range(AIAttacker.MobileEnemy.MinDamage2, AIAttacker.MobileEnemy.MaxDamage2 + 1); damageResult += Mathf.Max(0, (baseDamage + damageModifiers)); } if (AIAttacker.MobileEnemy.MaxDamage3 != 0 && (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon) == true)) { baseDamage = UnityEngine.Random.Range(AIAttacker.MobileEnemy.MinDamage3, AIAttacker.MobileEnemy.MaxDamage3 + 1); damageResult += Mathf.Max(0, (baseDamage + damageModifiers)); } return(damageResult); } }
protected void ConfirmInvestment_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton) { int playerIntell = player.Stats.LiveIntelligence; if (LimitedGoldShops.LimitedGoldShops.ShopBuildingData.TryGetValue(currentBuildingID, out sd)) { investedFlag = sd.InvestedIn; shopAttitude = sd.ShopAttitude; } CloseWindow(); if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Yes) { Entity.PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; if (playerEntity.GetGoldAmount() >= investOffer) { playerEntity.DeductGoldAmount(investOffer); DaggerfallUI.Instance.PlayOneShot(SoundClips.GoldPieces); if (buildQual <= 3) // 01 - 03 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("I'll do my best, partner."); } else { DaggerfallUI.MessageBox("Thanks for the gold, ya nutter."); } } else if (buildQual <= 7) // 04 - 07 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("Ya won't be disappointed, boss."); } else { DaggerfallUI.MessageBox("Really care for those fish, huh?"); } } else if (buildQual <= 17) // 08 - 17 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("Not a bad signature, do you practice?"); } else { DaggerfallUI.MessageBox("Your signature is atrocious, by the way."); } } else if (buildQual >= 18) // 18 - 20 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("I never disappoint when it comes to turning a profit."); } else { DaggerfallUI.MessageBox("Wipe your feet next time, you're tracking sludge in, lamprey."); } } LimitedGoldShops.LimitedGoldShops.UpdateInvestAmount(investOffer); } else { if (buildQual <= 3) // 01 - 03 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("I think you counted wrong, you don't have that much."); } else { DaggerfallUI.MessageBox("I know you don't have that much, stop lyin' ya idiot!"); } } else if (buildQual <= 7) // 04 - 07 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("Might want to recount, boss, cause I don't see that amount."); } else { DaggerfallUI.MessageBox("Who ya tryna impress, huh? I know you don't have that much."); } } else if (buildQual <= 17) // 08 - 17 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("Sorry, but it appears your funds are less than you suggest."); } else { DaggerfallUI.MessageBox("Quit wasting my damn time, you dolt, you don't have that much!"); } } else if (buildQual >= 18) // 18 - 20 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("I think you need to hire a new accountant, because you don't have that."); } else { DaggerfallUI.MessageBox("I need to charge more for my time, so leeches like you won't waste it so often!"); } } } } else if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.No) { if (buildQual <= 3) // 01 - 03 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("I understand your reluctance, just look around, haha!"); } else { DaggerfallUI.MessageBox("Why you gettin' my hopes up, just to dash them down?"); } } else if (buildQual <= 7) // 04 - 07 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("That's fine, I would not take such a gamble myself either."); } else { DaggerfallUI.MessageBox("Why you tryna bait me in just to pull away the line?"); } } else if (buildQual <= 17) // 08 - 17 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("Very well, thankfully parchment is cheap around here."); } else { DaggerfallUI.MessageBox("What's with the indecisive always wasting my time in this town?"); } } else if (buildQual >= 18) // 18 - 20 { if (shopAttitude == 0) { DaggerfallUI.MessageBox("So be it, ask again when you are ready to commit."); } else { DaggerfallUI.MessageBox("The parasite sucks my precious time away once again, a pity."); } } } }
public static bool CalculateSuccessfulHit(Entity.DaggerfallEntity attacker, Entity.DaggerfallEntity target, int chanceToHitMod, Items.DaggerfallUnityItem weapon, int struckBodyPart) { if (attacker == null || target == null) { return(false); } int chanceToHit = chanceToHitMod; Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; Entity.EnemyEntity AITarget = target as Entity.EnemyEntity; int armorValue = 0; // Apply hit mod from character biography if (target == player) { chanceToHit -= player.BiographyAvoidHitMod; } // Get armor value for struck body part if (struckBodyPart <= target.ArmorValues.Length) { armorValue = target.ArmorValues[struckBodyPart]; } chanceToHit += armorValue; // Apply adrenaline rush modifiers. if (attacker.Career.AdrenalineRush && attacker.CurrentHealth < (attacker.MaxHealth / 8)) { chanceToHit += 5; } if (target.Career.AdrenalineRush && target.CurrentHealth < (target.MaxHealth / 8)) { chanceToHit -= 5; } // Apply luck modifier. chanceToHit += ((attacker.Stats.Luck - target.Stats.Luck) / 10); // Apply agility modifier. chanceToHit += ((attacker.Stats.Agility - target.Stats.Agility) / 10); // Apply weapon material modifier. if (weapon != null) { chanceToHit += (weapon.GetWeaponMaterialModifier() * 10); } // Apply dodging modifier. // This modifier is bugged in classic and the attacker's dodging skill is used rather than the target's. // DF Chronicles says the dodging calculation is (dodging / 10), but it actually seems to be (dodging / 4). chanceToHit -= (target.Skills.Dodging / 4); // Apply critical strike modifier. if (UnityEngine.Random.Range(0, 100 + 1) < attacker.Skills.CriticalStrike) { chanceToHit += (attacker.Skills.CriticalStrike / 10); } // Apply monster modifier. if ((target != player) && (AITarget.EntityType == EntityTypes.EnemyMonster)) { chanceToHit += 40; } // DF Chronicles says -60 is applied at the end, but it actually seems to be -50. chanceToHit -= 50; Mathf.Clamp(chanceToHit, 3, 97); int roll = UnityEngine.Random.Range(0, 100 + 1); if (roll <= chanceToHit) { return(true); } else { return(false); } }
public static int CalculateWeaponDamage(Entity.DaggerfallEntity attacker, Entity.DaggerfallEntity target, FPSWeapon onscreenWeapon) { if (attacker == null || target == null) { return(0); } int damageLow = 0; int damageHigh = 0; int damageModifiers = 0; int baseDamage = 0; int damageResult = 0; int chanceToHitMod = 0; Items.DaggerfallUnityItem weapon = null; Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; Entity.EnemyEntity AIAttacker = null; Entity.EnemyEntity AITarget = null; if (attacker != player) { AIAttacker = attacker as Entity.EnemyEntity; weapon = attacker.ItemEquipTable.GetItem(Items.EquipSlots.RightHand); if (weapon == null) { weapon = attacker.ItemEquipTable.GetItem(Items.EquipSlots.LeftHand); } } else { if (GameManager.Instance.WeaponManager.UsingRightHand) { weapon = attacker.ItemEquipTable.GetItem(Items.EquipSlots.RightHand); } } if (target != player) { AITarget = target as Entity.EnemyEntity; } if (weapon != null) { // If the attacker has a weapon equipped, check if the material is high enough to damage the target if (target.MinMetalToHit > (Items.WeaponMaterialTypes)weapon.NativeMaterialValue) { if (attacker == player) { DaggerfallUI.Instance.PopupMessage(UserInterfaceWindows.HardStrings.materialIneffective); } return(0); } // If the attacker has a weapon equipped, get the weapon's damage damageLow = weapon.GetBaseDamageMin(); damageHigh = weapon.GetBaseDamageMax(); short skillID = weapon.GetWeaponSkillIDAsShort(); chanceToHitMod = attacker.Skills.GetSkillValue(skillID); } else if (attacker == player) { // If the player is attacking with no weapon equipped, use hand-to-hand skill for damage damageLow = CalculateHandToHandMinDamage(attacker.Skills.HandToHand); damageHigh = CalculateHandToHandMaxDamage(attacker.Skills.HandToHand); chanceToHitMod = attacker.Skills.HandToHand; } if (AIAttacker != null) { // Note: In classic, for enemies that have weapons, the damage values in the enemy // definitions are overridden by the weapon stats. This is fine for enemy classes, // who have non-weapon damage values of 0, but for the monsters that use weapons, // they may have a better attack if they don't use a weapon. // In DF Unity, enemies are using whichever is more damaging, the weapon or non-weapon attack. int weaponAverage = ((damageLow + damageHigh) / 2); int noWeaponAverage = ((AIAttacker.MobileEnemy.MinDamage + AIAttacker.MobileEnemy.MaxDamage) / 2); if (noWeaponAverage > weaponAverage) { damageLow = AIAttacker.MobileEnemy.MinDamage; damageHigh = AIAttacker.MobileEnemy.MaxDamage; chanceToHitMod = attacker.Skills.HandToHand; } } baseDamage = UnityEngine.Random.Range(damageLow, damageHigh + 1); if (onscreenWeapon != null && (attacker == player)) { // Apply swing modifiers for player. // The Daggerfall manual groups diagonal slashes to the left and right as if they are the same, but they are different. // Classic does not apply swing modifiers to hand-to-hand. if (onscreenWeapon.WeaponState == WeaponStates.StrikeUp) { damageModifiers += -4; chanceToHitMod += 10; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownRight) { damageModifiers += -2; chanceToHitMod += 5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownLeft) { damageModifiers += 2; chanceToHitMod += -5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDown) { damageModifiers += 4; chanceToHitMod += -10; } } // Apply weapon proficiency modifiers for player. if ((attacker == player) && weapon != null && ((int)attacker.Career.ExpertProficiencies & weapon.GetWeaponSkillUsed()) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } // Apply hand-to-hand proficiency modifiers for player. Hand-to-hand proficiencty is not applied in classic. else if ((attacker == player) && weapon == null && ((int)attacker.Career.ExpertProficiencies & (int)(DaggerfallConnect.DFCareer.ProficiencyFlags.HandToHand)) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } // Apply modifiers for Skeletal Warrior. // In classic these appear to be applied after the swing and weapon proficiency modifiers but before all other // damage modifiers. Doing the same here. // DF Chronicles just says "Edged weapons inflict 1/2 damage" if (weapon != null && (target != player) && AITarget.CareerIndex == (int)Entity.MonsterCareers.SkeletalWarrior) { if (weapon.NativeMaterialValue == (int)Items.WeaponMaterialTypes.Silver) { baseDamage *= 2; damageModifiers *= 2; } if (weapon.GetWeaponSkillUsed() != (int)DaggerfallConnect.DFCareer.ProficiencyFlags.BluntWeapons) { baseDamage /= 2; damageModifiers /= 2; } } // Apply bonus or penalty by opponent type. // In classic this is broken and only works if the attack is done with a weapon that has the maximum number of enchantments. if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Undead)) { if (((int)attacker.Career.UndeadAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.UndeadAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Daedra)) { if (((int)attacker.Career.DaedraAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.DaedraAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Humanoid)) { if (((int)attacker.Career.HumanoidAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.HumanoidAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } else if ((target != player) && (AITarget.GetEnemyGroup() == DaggerfallConnect.DFCareer.EnemyGroups.Animals)) { if (((int)attacker.Career.AnimalsAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Bonus) != 0) { damageModifiers += attacker.Level; } if (((int)attacker.Career.AnimalsAttackModifier & (int)DaggerfallConnect.DFCareer.AttackModifier.Phobia) != 0) { damageModifiers -= attacker.Level; } } // Apply racial modifiers for player. if ((attacker == player) && weapon != null) { if (player.RaceTemplate.ID == (int)Entity.Races.DarkElf) { damageModifiers += (attacker.Level / 4); chanceToHitMod += (attacker.Level / 4); } else if (weapon.GetWeaponSkillUsed() == (int)DaggerfallConnect.DFCareer.ProficiencyFlags.MissileWeapons) { if (player.RaceTemplate.ID == (int)Entity.Races.WoodElf) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } else if (player.RaceTemplate.ID == (int)Entity.Races.Redguard) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } // Apply strength modifier for player or for AI characters using weapons. // The in-game display of the strength modifier in Daggerfall is incorrect. It is actually ((STR - 50) / 5). if ((attacker == player) || (weapon != null)) { damageModifiers += DamageModifier(attacker.Stats.Strength); } // Apply material modifier. // The in-game display in Daggerfall of weapon damages with material modifiers is incorrect. The material modifier is half of what the display suggests. if (weapon != null) { damageModifiers += weapon.GetWeaponMaterialModifier(); } // Choose struck body part int[] bodyParts = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6 }; int struckBodyPart = bodyParts[UnityEngine.Random.Range(0, bodyParts.Length)]; // Check for a successful hit. if (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon, struckBodyPart) == true) { // 0 damage is possible. Creates no blood splash. damageResult = Mathf.Max(0, (baseDamage + damageModifiers)); } // If damage was done by a weapon, damage condition of weapon and armor of hit body part // In classic, shields are never damaged because the item in the equip slot of the hit // body part is all that is handled. // Here, if an equipped shield covered the hit body part, it takes damage instead. if (weapon != null && damageResult > 0) { weapon.DamageThroughPhysicalHit(damageResult, attacker); Items.DaggerfallUnityItem shield = target.ItemEquipTable.GetItem(Items.EquipSlots.LeftHand); bool shieldTakesDamage = false; if (shield != null) { Items.BodyParts[] protectedBodyParts = shield.GetShieldProtectedBodyParts(); for (int i = 0; (i < protectedBodyParts.Length) && !shieldTakesDamage; i++) { if (protectedBodyParts[i] == (Items.BodyParts)struckBodyPart) { shieldTakesDamage = true; } } } if (shieldTakesDamage) { shield.DamageThroughPhysicalHit(damageResult, target); } else { Items.EquipSlots hitSlot = Items.DaggerfallUnityItem.GetEquipSlotForBodyPart((Items.BodyParts)struckBodyPart); Items.DaggerfallUnityItem armor = target.ItemEquipTable.GetItem(hitSlot); if (armor != null) { armor.DamageThroughPhysicalHit(damageResult, target); } } } // If attack was by player or weapon-based, end here if ((attacker == player) || (weapon != null)) { return(damageResult); } // Handle multiple attacks by AI characters. else { if (AIAttacker.MobileEnemy.MaxDamage2 != 0 && (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon, struckBodyPart) == true)) { baseDamage = UnityEngine.Random.Range(AIAttacker.MobileEnemy.MinDamage2, AIAttacker.MobileEnemy.MaxDamage2 + 1); damageResult += Mathf.Max(0, (baseDamage + damageModifiers)); } if (AIAttacker.MobileEnemy.MaxDamage3 != 0 && (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon, struckBodyPart) == true)) { baseDamage = UnityEngine.Random.Range(AIAttacker.MobileEnemy.MinDamage3, AIAttacker.MobileEnemy.MaxDamage3 + 1); damageResult += Mathf.Max(0, (baseDamage + damageModifiers)); } return(damageResult); } }
public static int CalculateAttackDamage(Entity.DaggerfallEntity attacker, Entity.DaggerfallEntity target, int weaponEquipSlot, int enemyAnimStateRecord) { if (attacker == null || target == null) { return(0); } int minBaseDamage = 0; int maxBaseDamage = 0; int damageModifiers = 0; int damage = 0; int chanceToHitMod = 0; int backstabbingLevel = 0; Entity.PlayerEntity player = GameManager.Instance.PlayerEntity; Items.DaggerfallUnityItem weapon = attacker.ItemEquipTable.GetItem((Items.EquipSlots)weaponEquipSlot); short skillID = 0; // Choose whether weapon-wielding enemies use their weapons or weaponless attacks. // In classic, weapon-wielding enemies use the damage values of their weapons // instead of their weaponless values. // For some enemies this gives lower damage than similar-tier monsters // and the weaponless values seems more appropriate, so here // enemies will choose to use their weaponless attack if it is more damaging. Entity.EnemyEntity AIAttacker = attacker as Entity.EnemyEntity; if (AIAttacker != null && weapon != null) { int weaponAverage = ((minBaseDamage + maxBaseDamage) / 2); int noWeaponAverage = ((AIAttacker.MobileEnemy.MinDamage + AIAttacker.MobileEnemy.MaxDamage) / 2); if (noWeaponAverage > weaponAverage) { // Use hand-to-hand weapon = null; } } if (weapon != null) { // If the attacker is using a weapon, check if the material is high enough to damage the target if (target.MinMetalToHit > (Items.WeaponMaterialTypes)weapon.NativeMaterialValue) { if (attacker == player) { DaggerfallUI.Instance.PopupMessage(UserInterfaceWindows.HardStrings.materialIneffective); } return(0); } // Get weapon skill used skillID = weapon.GetWeaponSkillIDAsShort(); } else { skillID = (short)DFCareer.Skills.HandToHand; } chanceToHitMod = attacker.Skills.GetLiveSkillValue(skillID); Entity.EnemyEntity AITarget = null; if (target != player) { AITarget = target as Entity.EnemyEntity; } if (attacker == player) { // Apply swing modifiers. Not applied to hand-to-hand in classic. FPSWeapon onscreenWeapon = GameManager.Instance.WeaponManager.ScreenWeapon; if (onscreenWeapon != null) { // The Daggerfall manual groups diagonal slashes to the left and right as if they are the same, but they are different. // Classic does not apply swing modifiers to hand-to-hand. if (onscreenWeapon.WeaponState == WeaponStates.StrikeUp) { damageModifiers += -4; chanceToHitMod += 10; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownRight) { damageModifiers += -2; chanceToHitMod += 5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDownLeft) { damageModifiers += 2; chanceToHitMod += -5; } if (onscreenWeapon.WeaponState == WeaponStates.StrikeDown) { damageModifiers += 4; chanceToHitMod += -10; } } if (weapon != null) { // Apply weapon proficiency if (((int)attacker.Career.ExpertProficiencies & weapon.GetWeaponSkillUsed()) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } } // Apply hand-to-hand proficiency. Hand-to-hand proficiency is not applied in classic. else if (((int)attacker.Career.ExpertProficiencies & (int)(DFCareer.ProficiencyFlags.HandToHand)) != 0) { damageModifiers += ((attacker.Level / 3) + 1); chanceToHitMod += attacker.Level; } // Apply racial bonuses if (weapon != null) { if (player.RaceTemplate.ID == (int)Entity.Races.DarkElf) { damageModifiers += (attacker.Level / 4); chanceToHitMod += (attacker.Level / 4); } else if (skillID == (short)DFCareer.Skills.Archery) { if (player.RaceTemplate.ID == (int)Entity.Races.WoodElf) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } else if (player.RaceTemplate.ID == (int)Entity.Races.Redguard) { damageModifiers += (attacker.Level / 3); chanceToHitMod += (attacker.Level / 3); } } // Apply backstabbing if (enemyAnimStateRecord % 5 > 2) // Facing away from player { chanceToHitMod += attacker.Skills.GetLiveSkillValue(DFCareer.Skills.Backstabbing); attacker.TallySkill(DFCareer.Skills.Backstabbing, 1); // backstabbing backstabbingLevel = attacker.Skills.GetLiveSkillValue(DFCareer.Skills.Backstabbing); } } // Choose struck body part int[] bodyParts = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6 }; int struckBodyPart = bodyParts[UnityEngine.Random.Range(0, bodyParts.Length)]; // Get damage for weaponless attacks if (skillID == (short)DFCareer.Skills.HandToHand) { if (attacker == player) { if (CalculateSuccessfulHit(attacker, target, chanceToHitMod, null, struckBodyPart)) { minBaseDamage = CalculateHandToHandMinDamage(attacker.Skills.GetLiveSkillValue(DFCareer.Skills.HandToHand)); maxBaseDamage = CalculateHandToHandMaxDamage(attacker.Skills.GetLiveSkillValue(DFCareer.Skills.HandToHand)); damage = UnityEngine.Random.Range(minBaseDamage, maxBaseDamage + 1); // Apply damage modifiers. damage += damageModifiers; // Apply strength modifier. It is not applied in classic despite what the in-game description for the Strength attribute says. damage += DamageModifier(attacker.Stats.LiveStrength); // Handle backstabbing if (backstabbingLevel > 0 && UnityEngine.Random.Range(1, 101) <= backstabbingLevel) { damage *= 3; string backstabMessage = UserInterfaceWindows.HardStrings.successfulBackstab; DaggerfallUI.Instance.PopupMessage(backstabMessage); } } } else // attacker is monster { // Handle multiple attacks by AI int attackNumber = 0; while (attackNumber < 3) // Classic supports up to 5 attacks but no monster has more than 3 { if (attackNumber == 0) { minBaseDamage = AIAttacker.MobileEnemy.MinDamage; maxBaseDamage = AIAttacker.MobileEnemy.MaxDamage; } else if (attackNumber == 1) { minBaseDamage = AIAttacker.MobileEnemy.MinDamage2; maxBaseDamage = AIAttacker.MobileEnemy.MaxDamage2; } else if (attackNumber == 2) { minBaseDamage = AIAttacker.MobileEnemy.MinDamage3; maxBaseDamage = AIAttacker.MobileEnemy.MaxDamage3; } if (DFRandom.rand() % 100 < 50 && minBaseDamage > 0 && CalculateSuccessfulHit(attacker, target, chanceToHitMod, null, struckBodyPart)) { damage += UnityEngine.Random.Range(minBaseDamage, maxBaseDamage + 1); } ++attackNumber; } } } // Handle weapon attacks else { if (CalculateSuccessfulHit(attacker, target, chanceToHitMod, weapon, struckBodyPart)) { damage = UnityEngine.Random.Range(weapon.GetBaseDamageMin(), weapon.GetBaseDamageMax() + 1); damage += damageModifiers; // Apply modifiers for Skeletal Warrior. if (AITarget != null && AITarget.CareerIndex == (int)Entity.MonsterCareers.SkeletalWarrior) { if (weapon.NativeMaterialValue == (int)Items.WeaponMaterialTypes.Silver) { damage *= 2; } if ((weapon.flags & 0x10) == 0) // not a blunt weapon { damage /= 2; } } // Apply strength modifier damage += DamageModifier(attacker.Stats.LiveStrength); // Apply material modifier. // The in-game display in Daggerfall of weapon damages with material modifiers is incorrect. The material modifier is half of what the display suggests. damage += weapon.GetWeaponMaterialModifier(); if (damage < 1) { damage = 0; } damage += GetBonusOrPenaltyByEnemyType(attacker, AITarget); if (backstabbingLevel > 1 && UnityEngine.Random.Range(1, 100 + 1) <= backstabbingLevel) { damage *= 3; string backstabMessage = UserInterfaceWindows.HardStrings.successfulBackstab; DaggerfallUI.Instance.PopupMessage(backstabMessage); } } } damage = Mathf.Max(0, damage); // If damage was done by a weapon, damage the weapon and armor of the hit body part. // In classic, shields are never damaged, only armor specific to the hitbody part is. // Here, if an equipped shield covers the hit body part, it takes damage instead. if (weapon != null && damage > 0) { weapon.DamageThroughPhysicalHit(damage, attacker); Items.DaggerfallUnityItem shield = target.ItemEquipTable.GetItem(Items.EquipSlots.LeftHand); bool shieldTakesDamage = false; if (shield != null) { Items.BodyParts[] protectedBodyParts = shield.GetShieldProtectedBodyParts(); for (int i = 0; (i < protectedBodyParts.Length) && !shieldTakesDamage; i++) { if (protectedBodyParts[i] == (Items.BodyParts)struckBodyPart) { shieldTakesDamage = true; } } } if (shieldTakesDamage) { shield.DamageThroughPhysicalHit(damage, target); } else { Items.EquipSlots hitSlot = Items.DaggerfallUnityItem.GetEquipSlotForBodyPart((Items.BodyParts)struckBodyPart); Items.DaggerfallUnityItem armor = target.ItemEquipTable.GetItem(hitSlot); if (armor != null) { armor.DamageThroughPhysicalHit(damage, target); } } } return(damage); }
public PlayerModel(Entity.PlayerEntity playerDefaultEntity) { _hp.Value = playerDefaultEntity.DefaultHP; }