예제 #1
0
        /// <summary>
        /// Notifies the defender that they are attacked.
        /// </summary>
        /// <param name="rRound"></param>
        public virtual void OnAttacked(CombatMessage rMessage)
        {
            //com.ootii.Utilities.Debug.Log.FileWrite(_Transform.name + ".OnAttacked()");

            if (Attacked != null)
            {
                Attacked(this, rMessage);
            }

            if (rMessage.ID != CombatMessage.MSG_DEFENDER_ATTACKED)
            {
                return;
            }

            ActorCore lDefenderCore = gameObject.GetComponent <ActorCore>();

            if (lDefenderCore != null)
            {
                lDefenderCore.SendMessage(rMessage);
            }
            else
            {
                // Check if this defender is blocking, parrying, etc
                if (mMotionController != null)
                {
                    mMotionController.SendMessage(rMessage);
                }

                // Determine if we're continuing with the attack and apply damage
                if (rMessage.ID == CombatMessage.MSG_DEFENDER_ATTACKED)
                {
                    IDamageable lDamageable = gameObject.GetComponent <IDamageable>();
                    if (lDamageable != null)
                    {
                        lDamageable.OnDamaged(rMessage);
                    }
                    else
                    {
                        rMessage.ID = CombatMessage.MSG_DEFENDER_DAMAGED;
                        if (mMotionController != null)
                        {
                            mMotionController.SendMessage(rMessage);
                        }
                    }
                }

                // Disable this combatant
                if (rMessage.ID == CombatMessage.MSG_DEFENDER_KILLED)
                {
                    this.enabled = false;
                }
            }
        }
        /// <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);
        }
        /// <summary>
        /// Raised when the impact occurs
        /// </summary>
        /// <param name="rHitInfo">CombatHit structure detailing the hit information.</param>
        /// <param name="rAttackStyle">ICombatStyle that details the combat style being used.</param>
        protected override void OnImpact(CombatHit rHitInfo, ICombatStyle rAttackStyle = null)
        {
            // Test impact is now rolling up to the parent object but this means we are trying to apply the damage to the actorcore rather than the collider actually hit
            // see Test impact below
            IHealthManager lHealthManager = rHitInfo.Collider.gameObject.GetComponentInParent <IHealthManager>();
            GameObject     defender       = ((MonoBehaviour)lHealthManager).gameObject;

            mDefenders.Add(defender);

            mImpactCount++;

            Transform lHitTransform = GetClosestTransform(rHitInfo.Point, rHitInfo.Collider.transform);
            Vector3   lHitDirection = Quaternion.Inverse(lHitTransform.rotation) * (rHitInfo.Point - lHitTransform.position).normalized;

            CombatMessage lMessage = CombatMessage.Allocate();

            lMessage.Attacker     = mOwner;
            lMessage.Defender     = rHitInfo.Collider.gameObject;
            lMessage.Weapon       = this;
            lMessage.Damage       = GetAttackDamage(Random.value, (rAttackStyle != null ? rAttackStyle.DamageModifier : 1f));
            lMessage.ImpactPower  = GetAttackImpactPower();
            lMessage.HitPoint     = rHitInfo.Point;
            lMessage.HitDirection = lHitDirection;
            lMessage.HitVector    = rHitInfo.Vector;
            lMessage.HitTransform = lHitTransform;
            lMessage.AttackIndex  = mAttackStyleIndex;
            lMessage.CombatStyle  = rAttackStyle;

            ActorCore lAttackerCore = (mOwner != null ? mOwner.GetComponentInParent <ActorCore>() : null);
            ActorCore lDefenderCore = defender.gameObject.GetComponentInParent <ActorCore>();

            lMessage.ID = CombatMessage.MSG_ATTACKER_ATTACKED;

            if (lAttackerCore != null)
            {
                lAttackerCore.SendMessage(lMessage);
            }

#if USE_MESSAGE_DISPATCHER || OOTII_MD
            MessageDispatcher.SendMessage(lMessage);
#endif

            lMessage.ID = CombatMessage.MSG_DEFENDER_ATTACKED;

            if (lDefenderCore != null)
            {
                lDefenderCore.SendMessage(lMessage);

#if USE_MESSAGE_DISPATCHER || OOTII_MD
                MessageDispatcher.SendMessage(lMessage);
#endif
            }

            if (lAttackerCore != null)
            {
                lAttackerCore.SendMessage(lMessage);

#if USE_MESSAGE_DISPATCHER || OOTII_MD
                MessageDispatcher.SendMessage(lMessage);
#endif
            }

            OnImpactComplete(lMessage);

            CombatMessage.Release(lMessage);
        }