Example #1
0
        /// <summary>
        /// Sends the projectile flying
        /// </summary>
        public virtual void Launch(float rHAngle = 0f, float rVAngle = 0f, float rForce = 0f)
        {
            mAge            = 0f;
            mIsActive       = true;
            mHasExpired     = false;
            mIsShuttingDown = false;

            mImpactCount = 0;
            mLastImpact  = CombatHit.EMPTY;

            // Apply any rotation adjustment
            Quaternion lRotation = Quaternion.AngleAxis(rHAngle, _Transform.up) * Quaternion.AngleAxis(rVAngle, _Transform.right);

            _Transform.rotation = lRotation * _Transform.rotation;

            // Set the launch particles
            mLaunchPosition = _Transform.position;

            if (_LaunchRoot != null)
            {
                mLaunchInstance = GameObject.Instantiate(_LaunchRoot);
                mLaunchInstance.transform.position = _Transform.position;
                mLaunchInstance.transform.rotation = _Transform.rotation;

                StartEffects(mLaunchInstance);
            }

            if (_FlyRoot != null)
            {
                mFlyInstance = GameObject.Instantiate(_FlyRoot);
                mFlyInstance.transform.parent        = _Transform;
                mFlyInstance.transform.localRotation = Quaternion.identity;
                mFlyInstance.transform.localPosition = Vector3.zero;

                StartEffects(mFlyInstance);
            }

            // Add twice so we can create a trajectory from the start
            mLastPosition = _Transform.position;

            // If we're dealing with a rigidbody, add the force
            if (mRigidbody != null)
            {
                mRigidbody.useGravity  = true;
                mRigidbody.isKinematic = false;

                if (rForce == 0f)
                {
                    rForce = _Speed;
                }

                Vector3 lForce = _Transform.forward * rForce;
                mRigidbody.AddForce(lForce);
            }
        }
        /// <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);
        }
Example #3
0
        /// <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 virtual void OnImpact(CombatHit rHitInfo, ICombatStyle rAttackStyle = null)
        {
            // If we get here, there's an impact
            mImpactCount++;

            // Extract out information about the hit
            Transform lHitTransform = GetClosestTransform(rHitInfo.Point, rHitInfo.Collider.transform);
            Vector3   lHitDirection = Quaternion.Inverse(lHitTransform.rotation) * (rHitInfo.Point - lHitTransform.position).normalized;

            // Put together the combat info. This will will be modified over time
            CombatMessage lMessage = CombatMessage.Allocate();

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

            // Grab cores for processing
            ActorCore lAttackerCore = (mOwner != null ? mOwner.GetComponent <ActorCore>() : null);
            ActorCore lDefenderCore = rHitInfo.Collider.gameObject.GetComponent <ActorCore>();

            // Pre-Attack
            lMessage.ID = CombatMessage.MSG_ATTACKER_ATTACKED;

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

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

            // Attack Defender
            lMessage.ID = CombatMessage.MSG_DEFENDER_ATTACKED;

            if (lDefenderCore != null)
            {
                ICombatant lDefenderCombatant = rHitInfo.Collider.gameObject.GetComponent <ICombatant>();
                if (lDefenderCombatant != null)
                {
                    lMessage.HitDirection = Quaternion.Inverse(lDefenderCore.Transform.rotation) * (rHitInfo.Point - lDefenderCombatant.CombatOrigin).normalized;
                }

                lDefenderCore.SendMessage(lMessage);

#if USE_MESSAGE_DISPATCHER || OOTII_MD
                MessageDispatcher.SendMessage(lMessage);
#endif
            }
            else
            {
                lMessage.HitDirection = Quaternion.Inverse(lHitTransform.rotation) * (rHitInfo.Point - lHitTransform.position).normalized;

                IDamageable lDefenderDamageable = rHitInfo.Collider.gameObject.GetComponent <IDamageable>();
                if (lDefenderDamageable != null)
                {
                    lDefenderDamageable.OnDamaged(lMessage);
                }

                Rigidbody lRigidBody = rHitInfo.Collider.gameObject.GetComponent <Rigidbody>();
                if (lRigidBody != null)
                {
                    lRigidBody.AddForceAtPosition(rHitInfo.Vector * lMessage.ImpactPower, rHitInfo.Point, ForceMode.Impulse);
                }
            }

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

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

            // Finish up any impact processing (like sound)
            OnImpactComplete(lMessage);

            // Release the combatant to the pool
            CombatMessage.Release(lMessage);
        }
Example #4
0
        /// <summary>
        /// Raised when the impact occurs
        /// </summary>
        /// <param name="rHitInfo">RaycastHit data about the hit itself</param>
        /// <param name="rClosestTransform">Closets transform to the hit position</param>
        /// <param name="rLocalPosition">Position of the hit relative to the closest transform</param>
        /// <param name="rLocalForward">Direction the hit came from relative to the closest transform</param>
        protected virtual void OnImpact(CombatHit rHitInfo)
        {
            mAge      = 0f;
            mIsActive = false;

            mImpactCount++;

            ClearPhysics();

            // Stop the flight particles
            StopEffects(mLaunchInstance);
            StopEffects(mFlyInstance);

            // Play the particles
            if (_ImpactRoot != null)
            {
                mImpactInstance = GameObject.Instantiate(_ImpactRoot);
                mImpactInstance.transform.position = rHitInfo.Point;
                mImpactInstance.transform.rotation = Quaternion.LookRotation(rHitInfo.Normal, Vector3.up);

                StartEffects(mImpactInstance);
            }

            //// Combatant that is attacking
            //ICombatant lDefender = null;

            //// Determine who we're colliding with
            //lDefender = rHitInfo.Collider.gameObject.GetComponent<ICombatant>();
            //IDamageable lHitActorCore = rHitInfo.Collider.gameObject.GetComponent<IDamageable>();

            //if (lDefender == null)
            //{
            //    IWeaponCore lWeaponCore = rHitInfo.Collider.gameObject.GetComponent<IWeaponCore>();
            //    if (lWeaponCore != null)
            //    {
            //        lDefender = lWeaponCore.Owner.GetComponent<ICombatant>();
            //        if (lHitActorCore == null) { lHitActorCore = lWeaponCore.Owner.GetComponent<IDamageable>(); }
            //    }
            //}

            // Save the hit information
            Transform lHitTransform = GetClosestTransform(rHitInfo.Point, rHitInfo.Collider.transform);

            //Vector3 lCombatCenter = lHitTransform.position;
            //Vector3 lHitDirection = Vector3.zero;

            //if (lDefender != null)
            //{
            //    //lHitDirection = Quaternion.Inverse(lDefender.Transform.rotation) * (rHitInfo.Point - lDefender.CombatOrigin).normalized;

            //}
            //else
            //{
            //    //lHitDirection = Quaternion.Inverse(lHitTransform.rotation) * (rHitInfo.Point - lCombatCenter).normalized;
            //}

            // Determine if the projectile sticks around after impact
            if (_EmbedOnImpact)
            {
                // To compensate for scaling, we use a "connector". This way,
                // the projectile doesn't scale even if the target does
                Vector3 lLocalScale = lHitTransform.lossyScale;
                lLocalScale.x = 1f / Mathf.Max(Mathf.Abs(lLocalScale.x), 0.0001f);
                lLocalScale.y = 1f / Mathf.Max(Mathf.Abs(lLocalScale.y), 0.0001f);
                lLocalScale.z = 1f / Mathf.Max(Mathf.Abs(lLocalScale.z), 0.0001f);

                GameObject lConnector = new GameObject();
                lConnector.name                    = name + " connector";
                lConnector.transform.parent        = lHitTransform;
                lConnector.transform.localScale    = lLocalScale;
                lConnector.transform.localPosition = lHitTransform.InverseTransformPoint(rHitInfo.Point);
                lConnector.transform.localRotation = Quaternion.identity;

                _Transform.parent        = lConnector.transform;
                _Transform.localScale    = Vector3.one;
                _Transform.localPosition = Vector3.zero;
                _Transform.forward       = rHitInfo.Vector;
            }

            // Raise the impact event
            //mSpellAction.OnSuccess();
            if (OnImpactEvent != null)
            {
                OnImpactEvent(this, rHitInfo);
            }
        }