예제 #1
0
        private void BowDamage()
        {
            if (entityBehaviour)
            {
                // Can we see target? Then apply damage.
                if (senses.TargetInSight)
                {
                    EnemyEntity entity = entityBehaviour.Entity as EnemyEntity;
                    if (entityBehaviour.Target == GameManager.Instance.PlayerEntityBehaviour)
                    {
                        damage = ApplyDamageToPlayer(entity.ItemEquipTable.GetItem(Items.EquipSlots.RightHand));
                    }
                    else
                    {
                        damage = ApplyDamageToNonPlayer(entity.ItemEquipTable.GetItem(Items.EquipSlots.RightHand), true);
                    }

                    // Play arrow sound and add arrow to target inventory
                    if (entityBehaviour.Target == GameManager.Instance.PlayerEntityBehaviour)
                    {
                        GameManager.Instance.PlayerObject.SendMessage("PlayArrowSound");
                    }
                    else
                    {
                        EnemySounds targetSounds = entityBehaviour.Target.GetComponent <EnemySounds>();
                        targetSounds.PlayArrowSound();
                    }
                    Items.DaggerfallUnityItem arrow = Items.ItemBuilder.CreateItem(Items.ItemGroups.Weapons, (int)Items.Weapons.Arrow);
                    entityBehaviour.Target.Entity.Items.AddItem(arrow);
                }
            }
        }
예제 #2
0
        private void WeaponDamage(FPSWeapon weapon, out bool hitEnemy)
        {
            hitEnemy = false;
            DaggerfallUnityItem strikingWeapon = null;

            if (!mainCamera || !weapon)
            {
                return;
            }

            // Fire ray along player facing using weapon range
            // Origin point of ray is set back slightly to fix issue where strikes against enemy capsules touching player capsule do not connect
            RaycastHit hit;
            Ray        ray = new Ray(mainCamera.transform.position + -mainCamera.transform.forward * 0.1f, mainCamera.transform.forward);

            if (Physics.SphereCast(ray, SphereCastRadius, out hit, weapon.Reach - SphereCastRadius))
            {
                // Check if hit has an DaggerfallAction component
                DaggerfallAction action = hit.transform.gameObject.GetComponent <DaggerfallAction>();
                if (action)
                {
                    action.Receive(player, DaggerfallAction.TriggerTypes.Attack);
                }

                // Check if hit has an DaggerfallActionDoor component
                DaggerfallActionDoor actionDoor = hit.transform.gameObject.GetComponent <DaggerfallActionDoor>();
                if (actionDoor)
                {
                    actionDoor.AttemptBash();
                    return;
                }

                // Check if hit an entity and remove health
                DaggerfallEntityBehaviour entityBehaviour  = hit.transform.GetComponent <DaggerfallEntityBehaviour>();
                DaggerfallMobileUnit      entityMobileUnit = hit.transform.GetComponentInChildren <DaggerfallMobileUnit>();
                if (entityBehaviour)
                {
                    if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                    {
                        EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                        // Calculate damage
                        int damage;
                        if (usingRightHand)
                        {
                            strikingWeapon = currentRightHandWeapon;
                            damage         = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, strikingWeapon, entityMobileUnit.Summary.AnimStateRecord);
                        }
                        else
                        {
                            strikingWeapon = currentLeftHandWeapon;
                            damage         = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, strikingWeapon, entityMobileUnit.Summary.AnimStateRecord);
                        }

                        // Break any "normal power" concealment effects on player
                        if (playerEntity.IsMagicallyConcealedNormalPower && damage > 0)
                        {
                            EntityEffectManager.BreakNormalPowerConcealmentEffects(GameManager.Instance.PlayerEntityBehaviour);
                        }

                        EnemyMotor  enemyMotor  = hit.transform.GetComponent <EnemyMotor>();
                        EnemySounds enemySounds = hit.transform.GetComponent <EnemySounds>();

                        // Play arrow sound and add arrow to target's inventory
                        if (weapon.WeaponType == WeaponTypes.Bow)
                        {
                            enemySounds.PlayArrowSound();
                            DaggerfallUnityItem arrow = ItemBuilder.CreateItem(ItemGroups.Weapons, (int)Weapons.Arrow);
                            enemyEntity.Items.AddItem(arrow);
                        }

                        // Play hit sound and trigger blood splash at hit point
                        if (damage > 0)
                        {
                            if (usingRightHand)
                            {
                                enemySounds.PlayHitSound(currentRightHandWeapon);
                            }
                            else
                            {
                                enemySounds.PlayHitSound(currentLeftHandWeapon);
                            }

                            EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                            if (blood)
                            {
                                blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point);
                            }

                            // Knock back enemy based on damage and enemy weight
                            if (enemyMotor)
                            {
                                if (enemyMotor.KnockBackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) &&
                                    entityBehaviour.EntityType == EntityTypes.EnemyClass ||
                                    enemyEntity.MobileEnemy.Weight > 0)
                                {
                                    float enemyWeight    = enemyEntity.GetWeightInClassicUnits();
                                    float tenTimesDamage = damage * 10;
                                    float twoTimesDamage = damage * 2;

                                    float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage;
                                    float knockBackSpeed  = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256));
                                    knockBackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10);

                                    if (knockBackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)))
                                    {
                                        knockBackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10));
                                    }
                                    enemyMotor.KnockBackSpeed     = knockBackSpeed;
                                    enemyMotor.KnockBackDirection = mainCamera.transform.forward;
                                }
                            }

                            if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.EntityType == EntityTypes.EnemyClass && UnityEngine.Random.Range(1, 101) <= 40)
                            {
                                Genders gender;
                                if (entityMobileUnit.Summary.Enemy.Gender == MobileGender.Male || enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch)
                                {
                                    gender = Genders.Male;
                                }
                                else
                                {
                                    gender = Genders.Female;
                                }

                                bool heavyDamage = damage >= enemyEntity.MaxHealth / 4;
                                enemySounds.PlayCombatVoice(gender, false, heavyDamage);
                            }
                        }
                        else
                        {
                            if ((weapon.WeaponType != WeaponTypes.Bow && !enemyEntity.MobileEnemy.ParrySounds) || weapon.WeaponType == WeaponTypes.Melee)
                            {
                                weapon.PlaySwingSound();
                            }
                            else if (enemyEntity.MobileEnemy.ParrySounds)
                            {
                                enemySounds.PlayParrySound();
                            }
                        }

                        // Remove health
                        enemyEntity.DecreaseHealth(damage);
                        hitEnemy = true;

                        // Assign "cast when strikes" to target entity
                        if (strikingWeapon != null && strikingWeapon.IsEnchanted)
                        {
                            EntityEffectManager enemyEffectManager = enemyEntity.EntityBehaviour.GetComponent <EntityEffectManager>();
                            if (enemyEffectManager)
                            {
                                enemyEffectManager.StrikeWithItem(strikingWeapon, GameManager.Instance.PlayerEntityBehaviour);
                            }
                        }

                        // Make foe attack their aggressor
                        // Currently this is just player, but should be expanded later
                        // for a wider variety of behaviours
                        if (enemyMotor)
                        {
                            // Make enemies in an area aggressive if player attacked a non-hostile one.
                            if (!enemyMotor.IsHostile)
                            {
                                GameManager.Instance.MakeEnemiesHostile();
                            }
                            enemyMotor.MakeEnemyHostileToAttacker(GameManager.Instance.PlayerEntityBehaviour);
                        }
                    }
                }

                // Check if hit a mobile NPC
                MobilePersonNPC mobileNpc = hit.transform.GetComponent <MobilePersonNPC>();
                if (mobileNpc)
                {
                    EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                    if (blood)
                    {
                        blood.ShowBloodSplash(0, hit.point);
                    }
                    mobileNpc.Motor.gameObject.SetActive(false);
                    playerEntity.TallyCrimeGuildRequirements(false, 5);
                    // TODO: LOS check from each townsperson. If seen, register crime and start spawning guards as below.
                    playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder;
                    playerEntity.SpawnCityGuards(true);
                }
            }
        }
예제 #3
0
        private void WeaponDamage(FPSWeapon weapon, out bool hitEnemy)
        {
            hitEnemy = false;

            if (!mainCamera || !weapon)
            {
                return;
            }

            // Fire ray along player facing using weapon range
            RaycastHit hit;
            Ray        ray = new Ray(mainCamera.transform.position, mainCamera.transform.forward);

            if (Physics.SphereCast(ray, SphereCastRadius, out hit, weapon.Reach - SphereCastRadius))
            {
                // Check if hit has an DaggerfallAction component
                DaggerfallAction action = hit.transform.gameObject.GetComponent <DaggerfallAction>();
                if (action)
                {
                    action.Receive(player, DaggerfallAction.TriggerTypes.Attack);
                }

                // Check if hit has an DaggerfallActionDoor component
                DaggerfallActionDoor actionDoor = hit.transform.gameObject.GetComponent <DaggerfallActionDoor>();
                if (actionDoor)
                {
                    actionDoor.AttemptBash();
                    return;
                }

                // Check if hit an entity and remove health
                DaggerfallEntityBehaviour entityBehaviour  = hit.transform.GetComponent <DaggerfallEntityBehaviour>();
                DaggerfallMobileUnit      entityMobileUnit = hit.transform.GetComponentInChildren <DaggerfallMobileUnit>();
                if (entityBehaviour)
                {
                    if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                    {
                        EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                        // Calculate damage
                        int damage;
                        if (usingRightHand)
                        {
                            damage = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, (int)(EquipSlots.RightHand), entityMobileUnit.Summary.AnimStateRecord);
                        }
                        else
                        {
                            damage = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, (int)(EquipSlots.LeftHand), entityMobileUnit.Summary.AnimStateRecord);
                        }

                        EnemyMotor  enemyMotor  = hit.transform.GetComponent <EnemyMotor>();
                        EnemySounds enemySounds = hit.transform.GetComponent <EnemySounds>();

                        // Play arrow sound and add arrow to target's inventory
                        if (weapon.WeaponType == WeaponTypes.Bow)
                        {
                            enemySounds.PlayArrowSound();
                            DaggerfallUnityItem arrow = ItemBuilder.CreateItem(ItemGroups.Weapons, (int)Weapons.Arrow);
                            enemyEntity.Items.AddItem(arrow);
                        }

                        // Play hit sound and trigger blood splash at hit point
                        if (damage > 0)
                        {
                            if (usingRightHand)
                            {
                                enemySounds.PlayHitSound(currentRightHandWeapon);
                            }
                            else
                            {
                                enemySounds.PlayHitSound(currentLeftHandWeapon);
                            }

                            EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                            if (blood)
                            {
                                blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point);
                            }

                            // Knock back enemy based on damage and enemy weight
                            if (enemyMotor)
                            {
                                if (enemyMotor.KnockBackSpeed <= (5 / (PlayerMotor.classicToUnitySpeedUnitRatio / 10)) &&
                                    entityBehaviour.EntityType == EntityTypes.EnemyClass ||
                                    enemyEntity.MobileEnemy.Weight > 0)
                                {
                                    float enemyWeight    = enemyEntity.GetWeightInClassicUnits();
                                    float tenTimesDamage = damage * 10;
                                    float twoTimesDamage = damage * 2;

                                    float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage;
                                    float knockBackSpeed  = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256));
                                    knockBackSpeed /= (PlayerMotor.classicToUnitySpeedUnitRatio / 10);

                                    if (knockBackSpeed < (15 / (PlayerMotor.classicToUnitySpeedUnitRatio / 10)))
                                    {
                                        knockBackSpeed = (15 / (PlayerMotor.classicToUnitySpeedUnitRatio / 10));
                                    }
                                    enemyMotor.KnockBackSpeed     = knockBackSpeed;
                                    enemyMotor.KnockBackDirection = mainCamera.transform.forward;
                                }
                            }
                        }
                        else
                        {
                            if ((weapon.WeaponType != WeaponTypes.Bow && !enemyEntity.MobileEnemy.ParrySounds) || weapon.WeaponType == WeaponTypes.Melee)
                            {
                                weapon.PlaySwingSound();
                            }
                            else if (enemyEntity.MobileEnemy.ParrySounds)
                            {
                                enemySounds.PlayParrySound();
                            }
                        }

                        // Remove health
                        enemyEntity.DecreaseHealth(damage);
                        hitEnemy = true;

                        // Make foe attack their aggressor
                        // Currently this is just player, but should be expanded later
                        // for a wider variety of behaviours
                        if (enemyMotor)
                        {
                            // Make enemies in an area aggressive if player attacked a non-hostile one.
                            if (!enemyMotor.IsHostile)
                            {
                                GameManager.Instance.MakeEnemiesHostile();
                            }
                            enemyMotor.MakeEnemyHostileToPlayer(gameObject);
                        }
                    }
                }

                // Check if hit a mobile NPC
                MobilePersonNPC mobileNpc = hit.transform.GetComponent <MobilePersonNPC>();
                if (mobileNpc)
                {
                    // TODO: Create blood splash.
                    mobileNpc.Motor.gameObject.SetActive(false);
                    //GameManager.Instance.PlayerEntity.TallyCrimeGuildRequirements(false, 5);
                }
            }
        }