Esempio n. 1
0
        /// <summary>
        /// Tells the actor when to block
        /// </summary>
        public void DetermineBlock()
        {
            if (_Target == null)
            {
                return;
            }

#if USE_SWORD_SHIELD_MP || OOTII_SSMP
            Vector3 lToTarget         = _Target.transform.position - transform.position;
            float   lToTargetDistance = lToTarget.magnitude;

            BasicMeleeBlock lMeleeBlock = mMotionController.GetMotion <BasicMeleeBlock>();
            if (lMeleeBlock != null)
            {
                if (lMeleeBlock.IsActive)
                {
                    if (lMeleeBlock.Age > 1f)
                    {
                        CombatMessage lMessage = CombatMessage.Allocate();
                        lMessage.ID       = CombatMessage.MSG_COMBATANT_CANCEL;
                        lMessage.Defender = gameObject;
                        lMeleeBlock.OnMessageReceived(lMessage);

                        CombatMessage.Release(lMessage);

                        mActorCore.SetStateValue("State", IDLE);
                    }
                }
                else
                {
                    BasicMeleeAttack lMeleeAttack = mTargetMotionController.GetMotion <BasicMeleeAttack>();
                    if (lMeleeAttack != null && lMeleeAttack.IsActive)
                    {
                        if (lMeleeAttack.Age < 0.1f && !lMeleeBlock.IsActive)
                        {
                            if (mActorCore.GetStateValue("Stance") == EnumControllerStance.COMBAT_MELEE)
                            {
                                mMotionController.ActivateMotion(lMeleeBlock);
                                mActorCore.SetStateValue("State", BLOCKING);
                            }
                        }
                    }

#if USE_ARCHERY_MP || OOTII_AYMP
                    BasicRangedAttack lRangedAttack = mTargetMotionController.GetMotion <BasicRangedAttack>();
                    if (lRangedAttack != null && lRangedAttack.IsActive)
                    {
                    }
#endif
                }
            }
#endif
        }
Esempio n. 2
0
        /// <summary>
        /// Clears a slot by the storing the current item. We'll use the
        /// store motion if it exists
        /// </summary>
        /// <param name="rSlotID">Slot that is being cleared</param>
        /// <returns></returns>
        protected virtual IEnumerator Internal_StoreItem(string rSlotID)
        {
            BasicInventorySlot lSlot = GetInventorySlot(rSlotID);

            if (lSlot != null)
            {
                BasicInventoryItem lItem = GetInventoryItem(lSlot.ItemID);
                if (lItem != null)
                {
                    // Run the unequip motion
                    if (lItem.StoreMotion.Length > 0)
                    {
                        // If we have a motion to unequip, activate it
                        MotionControllerMotion lMotion = mMotionController.GetMotion(lItem.StoreMotion);
                        if (lMotion != null)
                        {
                            // This is an extra test so we don't try to sheathe a weapons we just
                            // unsheathed... until we're totally done with the transitions
                            while (lMotion.MotionLayer._AnimatorTransitionID != 0)
                            {
                                yield return(null);
                            }

                            IEquipStoreMotion lEquipStoreMotion = lMotion as IEquipStoreMotion;
                            if (lEquipStoreMotion != null)
                            {
                                lEquipStoreMotion.OverrideItemID = lItem.ID;
                                lEquipStoreMotion.OverrideSlotID = lSlot.ID;
                            }

                            // Now sheathe
                            mMotionController.ActivateMotion(lMotion);
                            while (lMotion.IsActive || lMotion.QueueActivation)
                            {
                                yield return(null);
                            }
                        }
                    }
                    // Otherwise, simply unequip
                    else
                    {
                        StoreItem(lSlot.ID);
                    }
                }

                // Clear the slot
                lSlot.ItemID = "";
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Coroutine to play the death animation and disable the actor after a couple of seconds
        /// </summary>
        /// <param name="rDamageValue">Amount of damage to take</param>
        /// <param name="rDamageType">Damage type taken</param>
        /// <param name="rAttackAngle">Angle that the damage came from releative to the actor's forward</param>
        /// <param name="rBone">Transform that the damage it... if known</param>
        /// <returns></returns>
        protected virtual IEnumerator InternalDeath(float rDamageValue = 0, int rDamageType = 0, float rAttackAngle = 0f, Transform rBone = null)
        {
            MotionController lMC = gameObject.GetComponent <MotionController>();

            if (lMC != null)
            {
                // Wait for any transition to finish
                while (lMC.ActiveMotion != null && lMC.ActiveMotion.MotionLayer.AnimatorTransitionID != 0)
                {
                    yield return(null);
                }

                // Trigger the death animation
                lMC.ActivateMotion(DeathMotion, (int)rAttackAngle);
                yield return(new WaitForSeconds(3.5f));

                // Shut down the MC
                lMC.enabled = false;
                lMC.ActorController.enabled = false;

                Collider[] lColliders = gameObject.GetComponents <Collider>();
                for (int i = 0; i < lColliders.Length; i++)
                {
                    lColliders[i].enabled = false;
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Called when the actor takes damage. This allows the actor to respond.
        /// Damage Type 0 = Physical melee
        /// Damage Type 1 = Physical ranged
        /// </summary>
        /// <param name="rDamageValue">Amount of damage to take</param>
        /// <param name="rDamageType">Damage type taken</param>
        /// <param name="rAttackAngle">Angle that the damage came from releative to the actor's forward</param>
        /// <returns>Determines if the damage was applied</returns>
        public virtual bool OnDamaged(float rDamageValue, int rDamageType = 0, float rAttackAngle = 0f, Transform rBone = null)
        {
            if (!IsAlive)
            {
                return(true);
            }

            float lRemainingHealth = 0f;

            if (AttributeSource != null)
            {
                lRemainingHealth = AttributeSource.GetAttributeValue(HealthID) - rDamageValue;
                AttributeSource.SetAttributeValue(HealthID, lRemainingHealth);
            }

            if (lRemainingHealth <= 0f)
            {
                OnDeath(rDamageValue, rDamageType, rAttackAngle, rBone);
            }
            else
            {
                MotionController lMC = gameObject.GetComponent <MotionController>();
                if (lMC != null)
                {
                    lMC.ActivateMotion(DamagedMotion, (int)rAttackAngle);
                }
            }

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Activates the motion on the specified target
        /// </summary>
        /// <param name="rTarget">GameObject to activate the motion on</param>
        /// <returns>Bool that determines if the motion was activated</returns>
        public bool ActivateInstance(GameObject rTarget)
        {
            bool lIsActivated = false;

            // Check if we have a motion controller and activate the motion
            MotionController lMotionController = rTarget.GetComponent <MotionController>();

            if (lMotionController != null)
            {
                mMotion = lMotionController.ActivateMotion(MotionName);
                if (mMotion != null)
                {
                    lIsActivated = true;

                    // Clear out any event first, then add our event
                    if (TargetTypeIndex == 0 || TargetTypeIndex == 1)
                    {
                        mMotion.OnDeactivatedEvent -= OnMotionDeactivated;
                        mMotion.OnDeactivatedEvent += OnMotionDeactivated;
                    }
                }
                // Grab the state as needed
                if (ExitState.Length > 0)
                {
                    mExitStateID = lMotionController.AddAnimatorName(ExitState);
                }
            }

            return(lIsActivated);
        }
Esempio n. 6
0
        /// <summary>
        /// Coroutine to play the death animation and disable the actor after a couple of seconds
        /// </summary>
        /// <param name="rDamageValue">Amount of damage to take</param>
        /// <param name="rDamageType">Damage type taken</param>
        /// <param name="rAttackAngle">Angle that the damage came from releative to the actor's forward</param>
        /// <param name="rBone">Transform that the damage it... if known</param>
        /// <returns></returns>
        protected virtual IEnumerator InternalDeath(IMessage rMessage)
        {
            ActorController  lActorController  = gameObject.GetComponent <ActorController>();
            MotionController lMotionController = gameObject.GetComponent <MotionController>();

            // Run the death animation if we can
            if (rMessage != null && lMotionController != null)
            {
                // Send the message to the MC to let it activate
                rMessage.ID = CombatMessage.MSG_DEFENDER_KILLED;
                lMotionController.SendMessage(rMessage);

                if (!rMessage.IsHandled && DeathMotion.Length > 0)
                {
                    MotionControllerMotion lMotion = lMotionController.GetMotion(DeathMotion);
                    if (lMotion != null)
                    {
                        lMotionController.ActivateMotion(lMotion);
                    }
                    else
                    {
                        int lID = Animator.StringToHash(DeathMotion);
                        if (lID != 0)
                        {
                            Animator lAnimator = gameObject.GetComponent <Animator>();
                            if (lAnimator != null)
                            {
                                try
                                {
                                    lAnimator.CrossFade(DeathMotion, 0.25f, 0);
                                }
                                catch { }
                            }
                        }
                    }
                }

                // Trigger the death animation
                yield return(new WaitForSeconds(3.0f));

                // Shut down the MC
                lMotionController.enabled = false;
                lMotionController.ActorController.enabled = false;
            }

            // Disable all colliders
            Collider[] lColliders = gameObject.GetComponents <Collider>();
            for (int i = 0; i < lColliders.Length; i++)
            {
                lColliders[i].enabled = false;
            }

            if (lActorController != null)
            {
                lActorController.RemoveBodyShapes();
            }
        }
        /// <summary>
        /// Activate the hand pose motion
        /// </summary>
        /// <param name="rHandPose"></param>
        protected void SetHandPose(BasicHandPose rHandPose)
        {
            if (rHandPose == null)
            {
                return;
            }

            //Debug.Log("[BasicHandPoseReactor] Setting " + rHandPose.Name);
            mMotionController.ActivateMotion(rHandPose);
        }
Esempio n. 8
0
        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        protected virtual void Update()
        {
            // Check if we should cast a spell
            if (_ActionAlias.Length > 0 && _InputSource != null && _DefaultSpellIndex > 0 && _DefaultSpellIndex < _Spells.Count)
            {
                if (_InputSource.IsJustPressed(_ActionAlias))
                {
                    bool lCast = false;

                    // Activate the spell through the motion
                    MotionController lMotionController = gameObject.GetComponent <MotionController>();
                    if (lMotionController != null)
                    {
                        PMP_BasicSpellCastings lCastMotion = lMotionController.GetMotion <PMP_BasicSpellCastings>();
                        if (lCastMotion != null)
                        {
                            lCast = true;
                            lMotionController.ActivateMotion(lCastMotion, _DefaultSpellIndex);
                        }
                    }

                    // If we couldn't activate the motion, activate the spell directly
                    if (!lCast)
                    {
                        InstantiateSpell(_DefaultSpellIndex);
                    }
                }
            }

            // Update each active spell
            for (int i = 0; i < _ActiveSpells.Count; i++)
            {
                _ActiveSpells[i].Update();
            }

            // Release the completed spells
            for (int i = _ActiveSpells.Count - 1; i >= 0; i--)
            {
                Spell lSpell = _ActiveSpells[i];
                if (lSpell.State == EnumSpellState.COMPLETED)
                {
                    lSpell.Release();
                    _ActiveSpells.RemoveAt(i);
                }
            }
        }
        void MotionPlay()
        {
            GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);

            if (go == null)
            {
                return;
            }

            mMotionController = go.GetComponent <MotionController>();

            if (mMotionController != null)
            {
                MotionControllerMotion lMotion = mMotionController.GetMotion(mLayer.Value, motionName.Value);
                mMotionController.ActivateMotion(lMotion);
            }
        }
Esempio n. 10
0
        private void OnGUI()
        {
            if (MotionController == null || SpellInventory == null)
            {
                GUI.Label(new Rect(10, 10, 300, 20), "No Motion Controller or Spell Inventory Set!");
                return;
            }

            float lWidth  = 60f;
            float lHeight = 45f;
            float lSpacer = 10f;

            int lSpellCount = Mathf.Min(SpellInventory._Spells.Count, SpellIndexes.Count);

            float lBarWidth = (lSpellCount * lWidth) + ((lSpellCount - 1) * lSpacer);
            float lBarX     = (Screen.width - lBarWidth) * 0.5f;
            float lBarY     = (Screen.height - lHeight - lSpacer);

            for (int i = 0; i < lSpellCount; i++)
            {
                int lIndex = SpellIndexes[i];

                string lName = SpellInventory._Spells[lIndex].Name.Replace(" ", "\n");

                if (GUI.Button(new Rect(lBarX + ((lWidth + lSpacer) * i), lBarY, lWidth, lHeight), lName))
                {
                    BasicSpellCasting lCastMotion = MotionController.GetMotion <BasicSpellCasting>();
                    if (!lCastMotion.IsActive && (!lCastMotion.RequiresStance || MotionController.ActorController.State.Stance == EnumControllerStance.SPELL_CASTING))
                    {
                        MotionController.ActivateMotion(lCastMotion, lIndex);
                    }
                }
            }

            //if (GUI.Button(new Rect(10f, lHeight + lSpacer, lWidth, lHeight), "Interrupt"))
            //{
            //    MotionControllerMotion lMotion = MotionController.GetActiveMotion(0);
            //    lMotion.Interrupt(null);
            //}
        }
Esempio n. 11
0
        void SpellCast()
        {
            GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);

            if (go == null)
            {
                return;
            }

            mMotionController = go.GetComponent <MotionController>();
            mSpellInventory   = go.GetComponent <SpellInventory>();

            if (mMotionController != null && mSpellInventory != null)
            {
                PMP_BasicSpellCastings lCastMotion = mMotionController.GetMotion <PMP_BasicSpellCastings>();
                if (!lCastMotion.IsActive && (!lCastMotion.RequiresStance || mMotionController.ActorController.State.Stance == EnumControllerStance.SPELL_CASTING))
                {
                    mMotionController.ActivateMotion(lCastMotion, spellIndex.Value);
                }
                Debug.Log("Cast Spell " + GetSpellName());
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Coroutine for moving the actor to the right position
        /// </summary>
        /// <param name="rMotion"></param>
        /// <returns></returns>
        public virtual IEnumerator MoveToTargetInternal(IInteractableCore rInteractableCore)
        {
            bool lStoredWalkRunMotionEnabled = false;
            bool lStoredUseTransformPosition = false;
            bool lStoredUseTransformRotation = false;

            MotionController lMotionController = mMotionController;
            ActorController  lActorController  = lMotionController._ActorController;

            // Enable AC positioning
            lStoredUseTransformPosition           = lActorController.UseTransformPosition;
            lActorController.UseTransformPosition = true;

            lStoredUseTransformRotation           = lActorController.UseTransformRotation;
            lActorController.UseTransformRotation = true;

            // Enable our strafing motion
            MotionControllerMotion lWalkRunMotion = lMotionController.GetMotion(_WalkRunMotion, true);

            if (lWalkRunMotion != null)
            {
                lStoredWalkRunMotionEnabled = lWalkRunMotion.IsEnabled;
                lWalkRunMotion.IsEnabled    = true;
            }

            Vector3 lTargetPosition = lActorController._Transform.position;

            if (rInteractableCore.ForcePosition)
            {
                if (rInteractableCore.TargetLocation != null)
                {
                    lTargetPosition = rInteractableCore.TargetLocation.position;
                }
                else if (rInteractableCore.TargetDistance > 0f)
                {
                    Vector3 lInteractablePosition = rInteractableCore.gameObject.transform.position;
                    lInteractablePosition.y = lActorController._Transform.position.y;

                    lTargetPosition = lInteractablePosition + ((lActorController._Transform.position - lInteractablePosition).normalized * rInteractableCore.TargetDistance);
                }
            }

            Vector3 lTargetForward = lActorController._Transform.forward;

            if (rInteractableCore.ForceRotation)
            {
                if (rInteractableCore.TargetLocation != null)
                {
                    lTargetForward = rInteractableCore.TargetLocation.forward;
                }
                else
                {
                    Vector3 lInteractablePosition = rInteractableCore.gameObject.transform.position;
                    lInteractablePosition.y = lActorController._Transform.position.y;

                    lTargetForward = (lInteractablePosition - lActorController._Transform.position).normalized;
                }
            }

            // Move to the target position and rotation
            Vector3 lDirection = lTargetPosition - lActorController._Transform.position;
            float   lAngle     = Vector3Ext.HorizontalAngleTo(lActorController._Transform.forward, lTargetForward);

            while (HorizontalDistance(lActorController._Transform.position, lTargetPosition) > 0.01f || Mathf.Abs(lAngle) > 0.1f)
            {
                float lDistance = Mathf.Min(lDirection.magnitude, _WalkSpeed * Time.deltaTime);
                lActorController._Transform.position = lActorController._Transform.position + (lDirection.normalized * lDistance);

                float lYaw = Mathf.Sign(lAngle) * Mathf.Min(Mathf.Abs(lAngle), _RotationSpeed * Time.deltaTime);
                lActorController._Transform.rotation = (lActorController._Transform.rotation * Quaternion.Euler(0f, lYaw, 0f));

                yield return(new WaitForEndOfFrame());

                lDirection = lTargetPosition - lActorController._Transform.position;
                lAngle     = Vector3Ext.HorizontalAngleTo(lActorController._Transform.forward, lTargetForward);
            }

            // Activate BasicInteraction
            mActiveForm      = rInteractableCore.Form;
            InteractableCore = rInteractableCore;
            lMotionController.ActivateMotion(this);

            // Give some final frames to get to the exact position
            yield return(new WaitForSeconds(0.2f));

            // Reset the motion and movement options
            if (lWalkRunMotion != null)
            {
                lWalkRunMotion.IsEnabled = lStoredWalkRunMotionEnabled;
            }
            lActorController.UseTransformPosition = lStoredUseTransformPosition;
            lActorController.UseTransformRotation = lStoredUseTransformRotation;

            lMotionController.TargetNormalizedSpeed = 1f;
        }
Esempio n. 13
0
        /// <summary>
        /// Called each frame
        /// </summary>
        private void Update()
        {
            if (!IsActive)
            {
                return;
            }
            if (mCombatant == null)
            {
                return;
            }
            if (Target == null)
            {
                return;
            }

            MotionControllerMotion lMotion = mMotionController.ActiveMotion;

            if (lMotion == null)
            {
                return;
            }

            MotionControllerMotion lTargetMotion = mTargetMotionController.ActiveMotion;

            // Determine if we rotate to the target
            bool lRotate = true;

            // Ensure our weapon is equipped
            //if (!mBasicInventory.IsWeaponSetEquipped(2))
            //{
            //    if (mLastEquipTime + AttackDelay < Time.time)
            //    {
            //        mBasicInventory.EquipWeaponSet(2);
            //        mLastEquipTime = Time.time;
            //    }
            //}
            //// The main AI loop
            //else
            //{
            Vector3 lToTarget = Target._Transform.position - transform.position;

            lToTarget.y = 0f;

            Vector3 lToTargetDirection = lToTarget.normalized;
            float   lToTargetDistance  = lToTarget.magnitude;

            bool lIsTargetAimingAtMe = false;

#if USE_ARCHERY_MP || OOTII_AYMP
            //float lTargetToMeHorizontalAngle = NumberHelper.GetHorizontalAngle(Target._Transform.forward, -lToTargetDirection, Target._Transform.up);
            //lIsTargetAimingAtMe = ((lTargetMotion is Bow_WalkRunTarget || lTargetMotion is Bow_BasicAttacks) && Mathf.Abs(lTargetToMeHorizontalAngle) < 10f);
#endif

            // Determine if we should move to the target
            float lRange = Range;

            if (!mFollow && lToTargetDistance > lRange + 1f)
            {
                mFollow = true;
            }
            if (mFollow && lToTargetDistance <= lRange)
            {
                mFollow = false;
            }
            if (mFollow && (lMotion.Category != EnumMotionCategories.IDLE && lMotion.Category != EnumMotionCategories.WALK))
            {
                mFollow = false;
            }
            if (mFollow && lIsTargetAimingAtMe)
            {
                mFollow = false;
            }
            if (!Move)
            {
                mFollow = false;
            }

            // Ensure we're not casting
            if (mMotionController.ActiveMotion is BasicSpellCasting)
            {
            }
            // Cast a healing spell
            else if (Cast &&
                     mLastCastTime + CastDelay < Time.time &&
                     mBasicAttributes != null && mBasicAttributes.GetAttributeValue <float>("Health", 100f) < 40f &&
                     mSpellInventory != null && mSpellInventory.GetSpellIndex("Heal Self") >= 0)
            {
                int lSpellIndex = mSpellInventory.GetSpellIndex("Heal Self");
                if (lSpellIndex >= 0)
                {
                    BasicSpellCasting lCastMotion = mMotionController.GetMotion <BasicSpellCasting>();
                    mMotionController.ActivateMotion(lCastMotion, lSpellIndex);

                    mLastCastTime = Time.time;
                }
            }
            // Move to the target
            else if (mFollow)
            {
                float lSpeed = Mathf.Min(MovementSpeed * Time.deltaTime, lToTargetDistance);
                transform.position = transform.position + (lToTargetDirection * lSpeed);
            }
            // If we're being shot at, block
            else if (Block && lIsTargetAimingAtMe)
            {
                mFollow = false;

                CombatMessage lMessage = CombatMessage.Allocate();
                lMessage.ID       = CombatMessage.MSG_COMBATANT_BLOCK;
                lMessage.Attacker = null;
                lMessage.Defender = gameObject;

                mMotionController.SendMessage(lMessage);
                CombatMessage.Release(lMessage);
            }
            // Let the movement finish up
            else if (lMotion.Category == EnumMotionCategories.WALK)
            {
            }
            // Attack with the sword
            else if (Attack && lMotion.Category == EnumMotionCategories.IDLE && (mLastAttackTime + AttackDelay < Time.time))
            {
                CombatMessage lMessage = CombatMessage.Allocate();
                lMessage.ID       = CombatMessage.MSG_COMBATANT_ATTACK;
                lMessage.Attacker = gameObject;
                lMessage.Defender = Target.gameObject;

                mMotionController.SendMessage(lMessage);
                CombatMessage.Release(lMessage);

                mLastAttackTime = Time.time;
            }
            // Block with the shield
            else if (Block && lMotion.Category == EnumMotionCategories.IDLE && lMotion.Age > 0.5f)
            {
                CombatMessage lMessage = CombatMessage.Allocate();
                lMessage.ID       = CombatMessage.MSG_COMBATANT_BLOCK;
                lMessage.Attacker = null;
                lMessage.Defender = gameObject;

                mMotionController.SendMessage(lMessage);
                CombatMessage.Release(lMessage);
            }
            // Free the block
            else if (lMotion.Category == EnumMotionCategories.COMBAT_MELEE_BLOCK && (lToTargetDistance > lRange + 1f || lMotion.Age > BlockHold))
            {
                CombatMessage lMessage = CombatMessage.Allocate();
                lMessage.ID       = CombatMessage.MSG_COMBATANT_CANCEL;
                lMessage.Attacker = null;
                lMessage.Defender = gameObject;

                mMotionController.SendMessage(lMessage);
                CombatMessage.Release(lMessage);
            }

            // Allow rotation only
            if (mMotionController.enabled && lRotate)
            {
                float lAngle = NumberHelper.GetHorizontalAngle(transform.forward, lToTargetDirection, transform.up);
                if (lAngle != 0f)
                {
                    float lRotationSpeed = Mathf.Sign(lAngle) * Mathf.Min(RotationSpeed * Time.deltaTime, Mathf.Abs(lAngle));
                    transform.rotation = transform.rotation * Quaternion.AngleAxis(lRotationSpeed, transform.up);
                }
            }
            //}

            // If we're dead, we can just stop
            if (lMotion.Category == EnumMotionCategories.DEATH)
            {
                IsActive = false;
            }
            // Clear the target if they are dead
            else if (Target != null && !Target.enabled)
            {
                Target = null;
                //StartCoroutine(WaitAndStoreEquipment(2f));
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Called when the actor takes damage. This allows the actor to respond.
        /// Damage Type 0 = Physical melee
        /// Damage Type 1 = Physical ranged
        /// </summary>
        /// <param name="rDamageValue">Amount of damage to take</param>
        /// <param name="rDamageType">Damage type taken</param>
        /// <param name="rAttackAngle">Angle that the damage came from releative to the actor's forward</param>
        /// <param name="rDamagedMotion">Motion to activate due to damage</param>
        /// <param name="rDeathMotion">Motion to activate due to death</param>
        /// <returns>Determines if the damage was applied</returns>
        public virtual bool OnDamaged(IMessage rMessage)
        {
            if (!IsAlive)
            {
                return(true);
            }

            float lRemainingHealth = 0f;

            if (AttributeSource != null)
            {
                if (rMessage is DamageMessage)
                {
                    lRemainingHealth = AttributeSource.GetAttributeValue(HealthID) - ((DamageMessage)rMessage).Damage;
                    AttributeSource.SetAttributeValue(HealthID, lRemainingHealth);
                }
            }

            if (lRemainingHealth <= 0f)
            {
                OnKilled(rMessage);
            }
            else if (rMessage != null)
            {
                bool lPlayAnimation = true;
                if (rMessage is DamageMessage)
                {
                    lPlayAnimation = ((DamageMessage)rMessage).AnimationEnabled;
                }

                if (lPlayAnimation)
                {
                    MotionController lMotionController = gameObject.GetComponent <MotionController>();
                    if (lMotionController != null)
                    {
                        // Send the message to the MC to let it activate
                        rMessage.ID = CombatMessage.MSG_DEFENDER_DAMAGED;
                        lMotionController.SendMessage(rMessage);
                    }

                    if (!rMessage.IsHandled && DamagedMotion.Length > 0)
                    {
                        MotionControllerMotion lMotion = lMotionController.GetMotion(DamagedMotion);
                        if (lMotion != null)
                        {
                            lMotionController.ActivateMotion(lMotion);
                        }
                        else
                        {
                            Animator lAnimator = gameObject.GetComponent <Animator>();
                            if (lAnimator != null)
                            {
                                lAnimator.CrossFade(DamagedMotion, 0.25f);
                            }
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Called when the reactor is first activated
        /// </summary>
        /// <returns>Determines if other reactors should process.</returns>
        public override bool Activate()
        {
            base.Activate();

            float lRemainingHealth = 0f;

            if (mActorCore.AttributeSource != null)
            {
                lRemainingHealth = mActorCore.AttributeSource.GetAttributeValue <float>(HealthID) - ((DamageMessage)mMessage).Damage;
                mActorCore.AttributeSource.SetAttributeValue(HealthID, lRemainingHealth);
            }

            // Forward to a death reactor
            if (lRemainingHealth <= 0f)
            {
                mMessage.ID = CombatMessage.MSG_DEFENDER_KILLED;
                mActorCore.SendMessage(mMessage);
            }
            // Process the damage
            else if (mMessage != null)
            {
                bool lPlayAnimation = ((DamageMessage)mMessage).AnimationEnabled;

                if (lPlayAnimation)
                {
                    MotionController lMotionController = mActorCore.gameObject.GetComponent <MotionController>();
                    if (lMotionController != null)
                    {
                        // Send the message to the MC to let it activate
                        mMessage.ID = CombatMessage.MSG_DEFENDER_DAMAGED;
                        lMotionController.SendMessage(mMessage);
                    }

                    if (!mMessage.IsHandled && DamagedMotion.Length > 0)
                    {
                        MotionControllerMotion lMotion = null;
                        if (lMotionController != null)
                        {
                            lMotion = lMotionController.GetMotion(DamagedMotion);
                        }

                        if (lMotion != null)
                        {
                            lMotionController.ActivateMotion(lMotion);
                        }
                        else
                        {
                            int lID = Animator.StringToHash(DamagedMotion);
                            if (lID != 0)
                            {
                                Animator lAnimator = mActorCore.gameObject.GetComponent <Animator>();
                                if (lAnimator != null)
                                {
                                    lAnimator.CrossFade(DamagedMotion, 0.25f, 0);
                                }
                            }
                        }
                    }
                }
            }

            // Disable the reactor
            Deactivate();

            // Allow other reactors to continue
            return(true);
        }