// Check if raycast hit a generic action component
 private bool ActionCheck(RaycastHit hitInfo, out DaggerfallAction action)
 {
     // Look for action
     action = hitInfo.transform.GetComponent<DaggerfallAction>();
     if (action == null)
         return false;
     else
         return true;
 }
 // Check if raycast hit a generic action component
 private bool ActionCheck(RaycastHit hitInfo, out DaggerfallAction action)
 {
     // Look for action
     action = hitInfo.transform.GetComponent <DaggerfallAction>();
     if (action == null)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
        // Check if raycast hit a generic action component
        private bool ActionCheck(RaycastHit hitInfo, out DaggerfallAction action)
        {
            // Look for action
            action = hitInfo.transform.GetComponent<DaggerfallAction>();
            if (action == null)
                return false;

            // Must be root action of chain (no parent)
            if (action.PreviousObject != null)
            {
                action = null;
                return false;
            }

            return true;
        }
Exemple #4
0
        // Check if raycast hit a generic action component
        private bool ActionCheck(RaycastHit hitInfo, out DaggerfallAction action)
        {
            // Look for action
            action = hitInfo.transform.GetComponent <DaggerfallAction>();
            if (action == null)
            {
                return(false);
            }

            // Must be root action of chain (no parent)
            if (action.PreviousObject != null)
            {
                action = null;
                return(false);
            }

            return(true);
        }
    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();
        DrawDefaultInspector();
        DaggerfallAction thisAction = (DaggerfallAction)target;

        if (GUILayout.Button("Activate") && EditorApplication.isPlaying)
        {
            if (thisAction.PreviousObject == null)
            {
                thisAction.Play(GameObject.FindGameObjectWithTag("Player"));
            }
            else
            {
                thisAction.Play(thisAction.PreviousObject);
            }
        }
    }
        /// <summary>
        /// Links action chains together.
        /// </summary>
        public static void LinkActionNodes(Dictionary <int, ActionLink> actionLinkDict)
        {
            // Exit if no actions
            if (actionLinkDict.Count == 0)
            {
                return;
            }

            // Iterate through actions
            foreach (var item in actionLinkDict)
            {
                ActionLink       link     = item.Value;
                DaggerfallAction dfAction = link.gameObject.GetComponent <DaggerfallAction>();

                if (dfAction == null)
                {
                    continue;
                }

                try
                {
                    // Link to next node
                    if (actionLinkDict.ContainsKey(link.nextKey))
                    {
                        dfAction.NextObject = actionLinkDict[link.nextKey].gameObject;
                    }

                    // Link to previous node
                    if (actionLinkDict.ContainsKey(link.prevKey))
                    {
                        dfAction.PreviousObject = actionLinkDict[link.prevKey].gameObject;
                    }
                }
                catch (Exception ex)
                {
                    DaggerfallUnity.LogMessage(ex.Message, true);
                    DaggerfallUnity.LogMessage(string.Format("Error in LinkActionNodes; {0} : {1} : {2} : {3}", link.gameObject.name, link.nextKey, link.prevKey, dfAction), true);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Constructs a Vector3 from magnitude and direction in RDB action resource.
        /// </summary>
        private static void GetRotationActionVector(ref DaggerfallAction action, DFBlock.RdbActionAxes axis)
        {
            Vector3 vector    = Vector3.zero;
            float   magnitude = action.Magnitude;

            switch (axis)
            {
            case DFBlock.RdbActionAxes.NegativeX:
                vector.x = -magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeY:
                vector.y = -magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeZ:
                vector.z = -magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveX:
                vector.x = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveY:
                vector.y = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveZ:
                vector.z = magnitude;
                break;

            default:
                magnitude = 0f;
                break;
            }

            action.ActionRotation = vector / BlocksFile.RotationDivisor;
        }
Exemple #8
0
        /// <summary>
        /// Constructs a Vector3 from magnitude and direction in RDB action resource.
        /// </summary>
        private static void GetTranslationActionVector(ref DaggerfallAction action, DFBlock.RdbActionAxes axis)
        {
            Vector3 vector    = Vector3.zero;
            float   magnitude = action.Magnitude;

            switch (axis)
            {
            case DFBlock.RdbActionAxes.NegativeX:
                vector.x = magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeY:
                vector.y = -magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeZ:
                vector.z = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveX:
                vector.x = -magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveY:
                vector.y = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveZ:
                vector.z = -magnitude;
                break;

            default:
                magnitude = 0f;
                break;
            }
            action.ActionTranslation = vector * MeshReader.GlobalScale;
        }
        /// <summary>
        /// Add action to model.
        /// </summary>
        private static void AddAction(
            GameObject go,
            DFBlock blockData,
            DFBlock.RdbObject obj,
            int modelReference,
            int groupIndex,
            Dictionary <int, ActionLink> actionLinkDict)
        {
            // Get model action record and description
            DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource;
            string description = blockData.RdbBlock.ModelReferenceList[modelReference].Description;

            // Check for known action types
            Vector3 actionRotation    = Vector3.zero;
            Vector3 actionTranslation = Vector3.zero;

            if ((action.Flags & (int)DFBlock.RdbActionFlags.Rotation) == (int)DFBlock.RdbActionFlags.Rotation)
            {
                actionRotation = (GetActionVector(ref action) / BlocksFile.RotationDivisor);
            }
            if ((action.Flags & (int)DFBlock.RdbActionFlags.Translation) == (int)DFBlock.RdbActionFlags.Translation)
            {
                actionTranslation = GetActionVector(ref action) * MeshReader.GlobalScale;
            }

            // A quick hack to fix special-case rotation issues.
            // Currently unknown if there is data indicating different rotation behaviour or if something else is happening.
            switch (description)
            {
            case "LID":
                actionRotation = new Vector3(0, 0, -90f);           // Coffin lids (e.g. Scourg barrow)
                break;

            case "WHE":
                actionRotation = new Vector3(0, -360f, 0);          // Wheels (e.g. Direnni Tower)
                break;
            }

            // Create action component
            DaggerfallAction c = go.AddComponent <DaggerfallAction>();

            c.ActionEnabled     = true;
            c.ModelDescription  = description;
            c.ActionRotation    = actionRotation;
            c.ActionTranslation = actionTranslation;
            c.ActionSoundID     = obj.Resources.ModelResource.SoundId;

            // Using 1/20 of native value in seconds
            // This seems to match game very closely
            c.ActionDuration = (float)action.Duration / 20f;
            c.ActionFlags    = action.Flags;

            // Create action links
            ActionLink link;

            link.gameObject = go;
            link.nextKey    = GetActionKey(groupIndex, action.NextObjectIndex);
            link.prevKey    = GetActionKey(groupIndex, action.PreviousObjectIndex);
            actionLinkDict.Add(GetActionKey(groupIndex, obj.Index), link);

            // Add sound
            AddActionAudioSource(go, (uint)c.ActionSoundID);

            return;
        }
Exemple #10
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>();
                if (entityBehaviour)
                {
                    if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                    {
                        EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                        // Calculate damage
                        int damage = FormulaHelper.CalculateWeaponDamage(playerEntity, enemyEntity, weapon);

                        // Play hit sound and trigger blood splash at hit point
                        if (damage > 0)
                        {
                            weapon.PlayHitSound();
                            EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                            if (blood)
                            {
                                blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point);
                            }
                        }
                        else
                        {
                            if (!enemyEntity.MobileEnemy.ParrySounds || weapon.WeaponType == WeaponTypes.Melee)
                            {
                                weapon.PlaySwingSound();
                            }
                            else
                            {
                                weapon.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
                        EnemyMotor enemyMotor = hit.transform.GetComponent <EnemyMotor>();
                        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.
                    weapon.PlayHitSound();
                    mobileNpc.Motor.gameObject.SetActive(false);
                    //GameManager.Instance.PlayerEntity.TallyCrimeGuildRequirements(false, 5);
                }
            }
        }
        // Returns true if hit an enemy entity
        public bool WeaponDamage(RaycastHit hit, Vector3 direction, Collider arrowHitCollider = null, bool arrowHit = false)
        {
            DaggerfallUnityItem strikingWeapon = null;

            if (!arrowHit)
            {
                // 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(true);
                    return(false);
                }

                // Check if player hit a static exterior door
                if (GameManager.Instance.PlayerActivate.AttemptExteriorDoorBash(hit))
                {
                    return(false);
                }
            }

            // Set up for use below
            DaggerfallEntityBehaviour entityBehaviour  = null;
            DaggerfallMobileUnit      entityMobileUnit = null;
            EnemyMotor  enemyMotor  = null;
            EnemySounds enemySounds = null;

            if (!arrowHit)
            {
                entityBehaviour  = hit.transform.GetComponent <DaggerfallEntityBehaviour>();
                entityMobileUnit = hit.transform.GetComponentInChildren <DaggerfallMobileUnit>();
                enemyMotor       = hit.transform.GetComponent <EnemyMotor>();
                enemySounds      = hit.transform.GetComponent <EnemySounds>();
            }
            else if (arrowHitCollider != null)
            {
                entityBehaviour  = arrowHitCollider.gameObject.transform.GetComponent <DaggerfallEntityBehaviour>();
                entityMobileUnit = arrowHitCollider.gameObject.transform.GetComponentInChildren <DaggerfallMobileUnit>();
                enemyMotor       = arrowHitCollider.gameObject.transform.GetComponent <EnemyMotor>();
                enemySounds      = arrowHitCollider.gameObject.transform.GetComponent <EnemySounds>();
            }

            // Check if hit a mobile NPC
            MobilePersonNPC mobileNpc = null;

            if (!arrowHit)
            {
                mobileNpc = hit.transform.GetComponent <MobilePersonNPC>();
            }
            else if (arrowHitCollider != null)
            {
                mobileNpc = arrowHitCollider.gameObject.transform.GetComponent <MobilePersonNPC>();
            }

            if (mobileNpc)
            {
                if (!mobileNpc.Billboard.IsUsingGuardTexture)
                {
                    EnemyBlood blood = null;
                    if (!arrowHit)
                    {
                        blood = hit.transform.GetComponent <EnemyBlood>();
                    }
                    else if (arrowHitCollider != null)
                    {
                        blood = arrowHitCollider.gameObject.transform.GetComponent <EnemyBlood>();
                    }

                    if (blood)
                    {
                        if (!arrowHit)
                        {
                            blood.ShowBloodSplash(0, hit.point);
                        }
                        else
                        {
                            blood.ShowBloodSplash(0, arrowHitCollider.gameObject.transform.position);
                        }
                    }
                    mobileNpc.Motor.gameObject.SetActive(false);
                    playerEntity.TallyCrimeGuildRequirements(false, 5);
                    playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder;
                    playerEntity.SpawnCityGuards(true);

                    // Allow custom race handling of weapon hit against mobile NPCs, e.g. vampire feeding or lycanthrope killing
                    if (entityBehaviour)
                    {
                        entityBehaviour.Entity.SetHealth(0);
                        RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect();
                        if (racialOverride != null)
                        {
                            racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity);
                        }
                    }
                }
                else
                {
                    playerEntity.CrimeCommitted = PlayerEntity.Crimes.Assault;
                    GameObject guard = playerEntity.SpawnCityGuard(mobileNpc.transform.position, mobileNpc.transform.forward);
                    entityBehaviour  = guard.GetComponent <DaggerfallEntityBehaviour>();
                    entityMobileUnit = guard.GetComponentInChildren <DaggerfallMobileUnit>();
                    enemyMotor       = guard.GetComponent <EnemyMotor>();
                    enemySounds      = guard.GetComponent <EnemySounds>();
                }
                mobileNpc.Motor.gameObject.SetActive(false);
            }

            // Check if hit an entity and remove health
            if (entityBehaviour)
            {
                if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                {
                    EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                    // Calculate damage
                    int damage;
                    if (!arrowHit)
                    {
                        if (usingRightHand)
                        {
                            strikingWeapon = currentRightHandWeapon;
                        }
                        else
                        {
                            strikingWeapon = currentLeftHandWeapon;
                        }
                    }
                    else
                    {
                        strikingWeapon = lastBowUsed;
                    }

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

                    // Play arrow sound and add arrow to target's inventory
                    if (arrowHit)
                    {
                        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 = null;
                        if (!arrowHit)
                        {
                            blood = hit.transform.GetComponent <EnemyBlood>();
                        }
                        else if (arrowHitCollider != null)
                        {
                            blood = arrowHitCollider.gameObject.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 = direction;
                            }
                        }

                        if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.EntityType == EntityTypes.EnemyClass && Dice100.SuccessRoll(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 ((!arrowHit && !enemyEntity.MobileEnemy.ParrySounds) || strikingWeapon == null)
                        {
                            ScreenWeapon.PlaySwingSound();
                        }
                        else if (enemyEntity.MobileEnemy.ParrySounds)
                        {
                            enemySounds.PlayParrySound();
                        }
                    }

                    // Handle weapon striking enchantments - this could change damage amount
                    if (strikingWeapon != null && strikingWeapon.IsEnchanted)
                    {
                        EntityEffectManager effectManager = GetComponent <EntityEffectManager>();
                        if (effectManager)
                        {
                            damage = effectManager.DoItemEnchantmentPayloads(EnchantmentPayloadFlags.Strikes, strikingWeapon, GameManager.Instance.PlayerEntity.Items, enemyEntity.EntityBehaviour, damage);
                        }
                        strikingWeapon.RaiseOnWeaponStrikeEvent(entityBehaviour, damage);
                    }

                    // Remove health
                    enemyEntity.DecreaseHealth(damage);

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

                    if (enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch && enemyEntity.CurrentHealth <= 0)
                    {
                        playerEntity.TallyCrimeGuildRequirements(false, 1);
                        playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder;
                    }

                    // Allow custom race handling of weapon hit against enemies, e.g. vampire feeding or lycanthrope killing
                    RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect();
                    if (racialOverride != null)
                    {
                        racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity);
                    }

                    return(true);
                }
            }

            return(false);
        }
Exemple #12
0
        private static void AddAction(
            GameObject go,
            string description,
            int soundID_and_index,
            float duration,
            float magnitude,
            int axis_raw,
            DFBlock.RdbTriggerFlags triggerFlag,
            DFBlock.RdbActionFlags actionFlag,
            long loadID = 0
            )
        {
            DaggerfallAction action = go.AddComponent <DaggerfallAction>();

            action.ModelDescription = description;
            action.ActionDuration   = duration;
            action.Magnitude        = magnitude;
            action.Index            = soundID_and_index;
            action.TriggerFlag      = triggerFlag;
            action.ActionFlag       = actionFlag;
            action.LoadID           = loadID;

            // If SaveLoadManager present in game then attach SerializableActionObject
            if (SaveLoadManager.Instance != null)
            {
                go.AddComponent <SerializableActionObject>();
            }

            //if a collision type action or action flat, add DaggerFallActionCollision component
            if (action.TriggerFlag == DFBlock.RdbTriggerFlags.Collision01 || action.TriggerFlag == DFBlock.RdbTriggerFlags.Collision03 ||
                action.TriggerFlag == DFBlock.RdbTriggerFlags.DualTrigger || action.TriggerFlag == DFBlock.RdbTriggerFlags.Collision09)
            {
                DaggerfallActionCollision collision = go.AddComponent <DaggerfallActionCollision>();
                collision.isFlat = false;
            }
            else if (description == "FLT")
            {
                DaggerfallActionCollision collision = go.AddComponent <DaggerfallActionCollision>();
                collision.isFlat = true;
            }


            switch (action.ActionFlag)
            {
            case DFBlock.RdbActionFlags.Translation:
            {
                action.Magnitude = magnitude;
                GetTranslationActionVector(ref action, (DFBlock.RdbActionAxes)axis_raw);
            }
            break;

            case DFBlock.RdbActionFlags.Rotation:
            {
                action.Magnitude = magnitude;
                GetRotationActionVector(ref action, (DFBlock.RdbActionAxes)axis_raw);
            }
            break;

            case DFBlock.RdbActionFlags.PositiveX:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.PositiveX);
            }
            break;

            case DFBlock.RdbActionFlags.NegativeX:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.NegativeX);
            }
            break;

            case DFBlock.RdbActionFlags.PositiveY:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.PositiveY);
            }
            break;

            case DFBlock.RdbActionFlags.NegativeY:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.NegativeY);
            }
            break;

            case DFBlock.RdbActionFlags.PositiveZ:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.PositiveZ);
            }
            break;

            case DFBlock.RdbActionFlags.NegativeZ:
            {
                action.ActionDuration = 50;
                action.Magnitude      = axis_raw * 8;
                GetTranslationActionVector(ref action, DFBlock.RdbActionAxes.NegativeZ);
            }
            break;

            default:
            {
                //Dmg actions use axis value to modifiy tot. dmg.
                action.Magnitude = axis_raw;
            }
            break;
            }

            // A quick hack to fix special-case rotation issues.
            // Currently unknown if there is data indicating different rotation behaviour or if something else is happening.
            switch (description)
            {
            case "LID":
                action.ActionRotation = new Vector3(0, 0, -90f);           // Coffin lids (e.g. Scourg barrow)
                break;

            case "WHE":
                action.ActionRotation = new Vector3(0, -360f, 0);          // Wheels (e.g. Direnni Tower)
                break;
            }

            //Add audio
            AddActionAudioSource(go, (uint)action.Index);
        }
        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>();
                if (entityBehaviour)
                {
                    if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)
                    {
                        EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity;

                        // Calculate damage
                        int damage = FormulaHelper.CalculateWeaponDamage(playerEntity, enemyEntity, weapon);

                        // Play hit sound and trigger blood splash at hit point
                        if (damage > 0)
                        {
                            weapon.PlayHitSound();
                            EnemyBlood blood = hit.transform.GetComponent <EnemyBlood>();
                            if (blood)
                            {
                                blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point);
                            }
                        }
                        else
                        {
                            if (!enemyEntity.MobileEnemy.ParrySounds || weapon.WeaponType == WeaponTypes.Melee)
                            {
                                weapon.PlaySwingSound();
                            }
                            else
                            {
                                weapon.PlayParrySound();
                            }
                        }

                        // Remove health
                        enemyEntity.DecreaseHealth(damage);
                        hitEnemy = true;
                    }
                }
            }
        }
        private void MeleeDamage(FPSWeapon weapon)
        {
            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;
                }

                // TODO: Use correct damage based on weapon and swing type
                // Just using fudge values during development
                int damage = Random.Range(1, 25);

                // Check if hit has an EnemyHealth
                // This is part of the old Demo code and will eventually be removed
                // For now enemies should either use EnemyHealth (deprecated) or EnemyEntity (current) to track enemy health
                // Never use both components on same enemy
                EnemyHealth enemyHealth = hit.transform.gameObject.GetComponent<EnemyHealth>();
                if (enemyHealth)
                {
                    // Example: Play sound based on fake parry mechanics
                    if (Random.value < ChanceToBeParried)
                    {
                        // Parried
                        weapon.PlayParrySound();
                        return;
                    }
                    else
                    {
                        // Connected
                        weapon.PlayHitSound();
                        enemyHealth.RemoveHealth(player, damage, hit.point);
                    }
                }

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

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

                        // Remove health and handle death
                        enemyEntity.DecreaseHealth(damage);
                        if (enemyEntity.CurrentHealth <= 0)
                        {
                            // Using SendMessage for now, will replace later
                            hit.transform.SendMessage("Die");
                        }
                    }
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Constructs a Vector3 from magnitude and direction in RDB action resource.
        /// </summary>
        private static void GetRotationActionVector(ref DaggerfallAction action, DFBlock.RdbActionAxes axis)
        {
            Vector3 vector = Vector3.zero;
            float magnitude = action.Magnitude;
            switch (axis)
            {
                case DFBlock.RdbActionAxes.NegativeX:
                    vector.x = -magnitude;
                    break;
                case DFBlock.RdbActionAxes.NegativeY:
                    vector.y = -magnitude;
                    break;
                case DFBlock.RdbActionAxes.NegativeZ:
                    vector.z = -magnitude;
                    break;

                case DFBlock.RdbActionAxes.PositiveX:
                    vector.x = magnitude;
                    break;
                case DFBlock.RdbActionAxes.PositiveY:
                    vector.y = magnitude;
                    break;
                case DFBlock.RdbActionAxes.PositiveZ:
                    vector.z = magnitude;
                    break;
                default:
                    magnitude = 0f;
                    break;
            }

            action.ActionRotation = vector / BlocksFile.RotationDivisor;
        }
        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)
                        {
                            damage         = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, (int)(EquipSlots.RightHand), entityMobileUnit.Summary.AnimStateRecord);
                            strikingWeapon = currentRightHandWeapon;
                        }
                        else
                        {
                            damage         = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, (int)(EquipSlots.LeftHand), entityMobileUnit.Summary.AnimStateRecord);
                            strikingWeapon = currentLeftHandWeapon;
                        }

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

                // 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);
                }
            }
        }
Exemple #17
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);
                }
            }
        }
Exemple #18
0
        /// <summary>
        /// Constructs a Vector3 from magnitude and direction in RDB action resource.
        /// </summary>
        private static void GetTranslationActionVector(ref DaggerfallAction action, DFBlock.RdbActionAxes axis)
        {
            Vector3 vector = Vector3.zero;
            float magnitude = action.Magnitude;
            switch (axis)
            {
                case DFBlock.RdbActionAxes.NegativeX:
                    vector.x = magnitude;
                    break;
                case DFBlock.RdbActionAxes.NegativeY:
                    vector.y = -magnitude;
                    break;
                case DFBlock.RdbActionAxes.NegativeZ:
                    vector.z = magnitude;
                    break;

                case DFBlock.RdbActionAxes.PositiveX:
                    vector.x = -magnitude;
                    break;
                case DFBlock.RdbActionAxes.PositiveY:
                    vector.y = magnitude;
                    break;
                case DFBlock.RdbActionAxes.PositiveZ:
                    vector.z = -magnitude;
                    break;
                default:
                    magnitude = 0f;
                    break;
            }
            action.ActionTranslation = vector * MeshReader.GlobalScale;
        }
Exemple #19
0
        void Update()
        {
            if (GameManager.Instance.PlayerEntity.CurrentHealth < 1 ||
                GameManager.IsGamePaused ||
                GameManager.Instance.PlayerMotor.IsSwimming ||
                GameManager.Instance.PlayerMotor.IsLevitating ||
                GameManager.Instance.PlayerMotor.OnExteriorWater == PlayerMotor.OnExteriorWaterMethod.Swimming)
            {
                return;
            }

            float distance;

            if (!playerMotor.IsCrouching)
            {
                distance = (controller.height / 2f) - (controller.height * 0.1f);
            }
            else
            {
                distance = (controller.height / 2f);
            }

            if (moveScanner.HeadHitDistance < distance && moveScanner.HeadHitDistance > 0)
            {
                // Tests to prevent player being crushed by static geometry, non-action colliders, or currently stationary action objects
                // Only perform these tests if move scanner head raycast has found a valid transform
                if (moveScanner.HeadRaycastHit.transform)
                {
                    // Do nothing if move scanner has detected a static gameobject
                    // This prevents player from being crushed under sloping non-moving geometry found on boat and inside buildings
                    // Also stops player being forced into a crouch from just brushing up against sloping geometry
                    if (GameObjectHelper.IsStaticGeometry(moveScanner.HeadRaycastHit.transform.gameObject))
                    {
                        return;
                    }

                    // We found a non-static object, but it really an action object (e.g. moving platform)?
                    DaggerfallAction action = moveScanner.HeadRaycastHit.transform.gameObject.GetComponent <DaggerfallAction>();
                    if (!action)
                    {
                        return;
                    }

                    // Confirm dynamic object actually in motion, not just a stationary action object player happened to bump their head into
                    if (!action.IsMoving)
                    {
                        return;
                    }

                    // Exclude "BOX" to prevent unintended crushing hazard in Mantellan Crux - player instead pushed back by physics
                    if (action.ModelDescription == "BOX")
                    {
                        return;
                    }

                    // This object fits criteria for a crushing object
                    // Player will first be forced into a crouch then killed if they remain under crushing object past threshold height
                    if (!playerMotor.IsCrouching && heightChanger.HeightAction != HeightChangeAction.DoCrouching)
                    {
                        // If player is standing then crushing object forces them into a crouch
                        heightChanger.HeightAction = HeightChangeAction.DoCrouching;
                    }
                    else if (playerMotor.IsCrouching && playerMotor.IsGrounded)
                    {
                        // If player already crouching and on the ground, then kill
                        if (previousHeightHit > 0 && previousHeightHit > moveScanner.HeadHitDistance)
                        {
                            GameManager.Instance.PlayerEntity.SetHealth(0);
                        }
                    }
                }

                previousHeightHit = moveScanner.HeadHitDistance;
            }
            else
            {
                previousHeightHit = 0f;
            }
        }
Exemple #20
0
        // Returns true if hit an enemy entity
        public bool WeaponDamage(RaycastHit hit, Vector3 direction, bool arrowHit = false)
        {
            DaggerfallUnityItem strikingWeapon = null;

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

            // 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 (!arrowHit)
                    {
                        if (usingRightHand)
                        {
                            strikingWeapon = currentRightHandWeapon;
                        }
                        else
                        {
                            strikingWeapon = currentLeftHandWeapon;
                        }
                    }
                    else
                    {
                        strikingWeapon = lastBowUsed;
                    }

                    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 (arrowHit)
                    {
                        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 = direction;
                            }
                        }

                        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 ((!arrowHit && !enemyEntity.MobileEnemy.ParrySounds) || strikingWeapon == null)
                        {
                            ScreenWeapon.PlaySwingSound();
                        }
                        else if (enemyEntity.MobileEnemy.ParrySounds)
                        {
                            enemySounds.PlayParrySound();
                        }
                    }

                    // Remove health
                    enemyEntity.DecreaseHealth(damage);

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

                    return(true);
                }
            }

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

            return(false);
        }
 void Awake()
 {
     action = GetComponent<DaggerfallAction>();
     if (!action)
         throw new Exception("DaggerfallAction not found.");
 }