Exemplo n.º 1
0
        // 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));
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        /// <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);
            }
        }
Exemplo n.º 5
0
        // 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);
        }
Exemplo n.º 7
0
        public PlayerControllerPresenter Init(Entity.PlayerEntity playerEntity)
        {
            _playerModel = new PlayerModel(playerEntity);
            _gunModel    = new GunModel(playerEntity.BulletEntity);

            Bind();
            DebugInit();

            return(this);
        }
Exemplo n.º 8
0
        // 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);
        }
Exemplo n.º 9
0
        // 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));
        }
Exemplo n.º 10
0
        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);
            }
        }
Exemplo n.º 11
0
        // 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));
        }
Exemplo n.º 12
0
        /// <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);
            }
        }
Exemplo n.º 14
0
        // 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);
        }
Exemplo n.º 15
0
        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;
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
0
        // 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);
        }
Exemplo n.º 18
0
        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...");
            }
        }
Exemplo n.º 19
0
        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);
        }
Exemplo n.º 20
0
        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);
            }
        }
Exemplo n.º 21
0
        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.");
                    }
                }
            }
        }
Exemplo n.º 22
0
        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);
            }
        }
Exemplo n.º 23
0
        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);
            }
        }
Exemplo n.º 24
0
        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);
        }
Exemplo n.º 25
0
 public PlayerModel(Entity.PlayerEntity playerDefaultEntity)
 {
     _hp.Value = playerDefaultEntity.DefaultHP;
 }