Exemplo n.º 1
0
 /// <summary>
 /// Ends the item use.
 /// </summary>
 private void EndUse()
 {
     if (!InUse())
     {
         return;
     }
     if (m_UseEvent != null)
     {
         Scheduler.Cancel(ref m_UseEvent);
     }
     if (m_CastParticles)
     {
         m_CastParticles.Stop();
     }
     if (m_CastSound != null && m_CastSound.Length > 0 && m_CastMode == CastMode.Continuous)
     {
         m_AudioSource.Stop();
     }
     if (m_RegenerateDelay != 0)
     {
         m_RegenerateEvent = Scheduler.Schedule(m_RegenerateDelay, RegenerateAmmo);
     }
     m_InUse             = false;
     m_Used              = false;
     m_StopContinuousUse = false;
     m_AimStates.NextState();
     m_UseStates.NextState();
     EventHandler.ExecuteEvent(m_Character, "OnItemStopUse");
 }
Exemplo n.º 2
0
 /// <summary>
 /// Cancels the spawn from occurring.
 /// </summary>
 public void CancelSpawn()
 {
     if (m_RespawnEvent != null)
     {
         Scheduler.Cancel(ref m_RespawnEvent);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Cancel the scheduled activation if the timer isn't what caused the projectile to deactivate, and disable the TrailRenderer.
        /// </summary>
        private void OnDisable()
        {
            Scheduler.Cancel(ref m_ScheduledActivation);
            m_Rigidbody.velocity        = Vector3.zero;
            m_Rigidbody.angularVelocity = Vector3.zero;

            // Set the TrailRenderer time to a negative value to prevent a trail from being added when the object pool changes the position of the projectile.
            if (m_TrailRenderer)
            {
                m_TrailRenderer.time = -m_TrailRenderer.time;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// The projectile has collided. Apply damage to the object hit and spawn various effects (explosion, decal, etc).
        /// </summary>
        /// <param name="originator">The originator of the projectile.</param>
        /// <param name="collisionTransform">The collision object that the destructable collided with. Can be null.</param>
        /// <param name="collisionPoint">The point of destruction.</param>
        /// <param name="collisionNormal">The normal at the destruction point.</param>
        /// <param name="destroy">Should the projectile be destroyed and placed back in the ObjectPool?</param>
        protected override void Collide(GameObject originator, Transform collisionTransform, Vector3 collisionPoint, Vector3 collisionNormal, bool destroy)
        {
            base.Collide(originator, collisionTransform, collisionPoint, collisionNormal, destroy);
            enabled = false;

            if (!destroy)
            {
                // If the projectile isn't being destroyed then set the parent, make it kinematic, and deactivate the collider to prevent it from interfering with other objects.
                m_Transform.parent      = collisionTransform;
                m_Rigidbody.isKinematic = true;
                m_Collider.enabled      = false;
                Scheduler.Cancel(ref m_ScheduledActivation);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Do the explosion.
        /// </summary>
        /// <param name="originator">The originator of the object.</param>
        public void Explode(GameObject originator)
        {
            // Cancel the explosion event if it exists.
            Scheduler.Cancel(ref m_ExplosionEvent);

            // Loop through all of the nearby colliders and apply an explosion force and damage.
            Rigidbody colliderRigidbody = null;
            Health    health            = null;
            var       hitCount          = Physics.OverlapSphereNonAlloc(m_Transform.position, m_Radius, m_HitColliders, -1, QueryTriggerInteraction.Ignore);

            for (int i = 0; i < hitCount; ++i)
            {
                // A GameObject can contain multiple colliders. Prevent the explosion from occurring on the same GameObject multiple times.
                if (m_GameObjectExplosions.Contains(m_HitColliders[i].gameObject))
                {
                    continue;
                }
                m_GameObjectExplosions.Add(m_HitColliders[i].gameObject);

                // If the Health component exists it will apply an explosive force to the rigidbody in addition to deducting the health. Otherwise just apply the force to the rigidbody.
                if ((health = m_HitColliders[i].transform.GetComponentInParent <Health>()) != null)
                {
                    // The further out the collider is, the less it is damaged.
                    var direction      = m_Transform.position - m_HitColliders[i].transform.position;
                    var damageModifier = Mathf.Max(1 - (direction.magnitude / m_Radius), 0.01f);
                    health.Damage(m_DamageAmount * damageModifier, m_Transform.position, direction.normalized * -m_ImpactForce * damageModifier, m_Radius, originator);
                }
                else if ((colliderRigidbody = Utility.GetComponentForType <Rigidbody>(m_HitColliders[i].gameObject)) != null)
                {
                    colliderRigidbody.AddExplosionForce(m_ImpactForce, m_Transform.position, m_Radius);
                }

                // Execute any custom events.
                if (!string.IsNullOrEmpty(m_DamageEvent))
                {
                    EventHandler.ExecuteEvent(m_HitColliders[i].gameObject, m_DamageEvent, m_DamageAmount, m_Transform.position, m_Transform.forward * -m_ImpactForce, originator);
                }
            }
            m_GameObjectExplosions.Clear();

            // Boom.
            if (m_Sound != null)
            {
                m_AudioSource.clip = m_Sound;
                m_AudioSource.Play();
            }

            Scheduler.Schedule(m_Lifespan, Destroy);
        }
Exemplo n.º 6
0
 /// <summary>
 /// The object has been enabled. Set IsDepleted to false and initialize the rigidbody.
 /// </summary>
 private void OnEnable()
 {
     m_IsDepleted       = false;
     m_Renderer.enabled = enabled;
     if (m_Rigidbody != null)
     {
         m_Rigidbody.isKinematic = false;
         m_Collider.enabled      = true;
         if (m_TriggerEnableEvent != null)
         {
             Scheduler.Cancel(ref m_TriggerEnableEvent);
         }
         m_Trigger.enabled = false;
     }
 }
Exemplo n.º 7
0
        /// <summary>
        /// The object is no longer alive. Kill it.
        /// </summary>
        /// <param name="position">The position of the damage.</param>
        /// <param name="force">The amount of force applied to the object while taking the damage.</param>
        /// <param name="attacker">The GameObject that killed the character.</param>
        private void DieLocal(Vector3 position, Vector3 force, GameObject attacker)
        {
            // Notify those interested.
            EventHandler.ExecuteEvent(m_GameObject, "OnDeath");
            EventHandler.ExecuteEvent <Vector3, Vector3, GameObject>(m_GameObject, "OnDeathDetails", force, position, attacker);

            // Spawn any objects on death, such as an explosion if the object is an explosive barrell.
            for (int i = 0; i < m_SpawnedObjectsOnDeath.Length; ++i)
            {
                var       spawnedObject = ObjectPool.Instantiate(m_SpawnedObjectsOnDeath[i], transform.position, transform.rotation);
                Explosion explosion;
                if ((explosion = Utility.GetComponentForType <Explosion>(spawnedObject)) != null)
                {
                    explosion.Originator = gameObject;
                }
            }

            // Destroy any objects on death. The objects will be placed back in the object pool if they were created within it otherwise the object will be destroyed.
            for (int i = 0; i < m_DestroyedObjectsOnDeath.Length; ++i)
            {
                if (ObjectPool.SpawnedWithPool(m_DestroyedObjectsOnDeath[i]))
                {
                    ObjectPool.Destroy(m_DestroyedObjectsOnDeath[i]);
                }
                else
                {
                    Object.Destroy(m_DestroyedObjectsOnDeath[i]);
                }
            }

            // Change the layer to a death layer.
            if (m_DeathLayer.value != 0)
            {
                m_AliveLayer       = m_GameObject.layer;
                m_GameObject.layer = m_DeathLayer;
            }

            // Stop any scheduled events.
            Scheduler.Cancel(ref m_ShieldRegenerativeEvent);

            // Deactivate the object if requested.
            if (m_DeactivateOnDeath)
            {
                Scheduler.Schedule(m_DeactivateOnDeathDelay, Deactivate);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Try to fire the weapon. The weapon may not be able to be fired for various reasons such as it already firing or it being out of ammo.
        /// </summary>
        public override bool TryUse()
        {
            if (!m_IsFiring && m_CanFire && m_LastShootTime + m_ShootDelay < Time.time)
            {
                if (m_Inventory.GetItemCount(m_ConsumableItemType) > 0)
                {
                    m_IsFiring = true;
                    // Prevent the weapon from continuously firing if it not a fully automatic. AI agents do not have to follow this because they don't manually stop firing.
                    m_CanFire = m_FireMode == FireMode.FullAuto || m_AIAgent.Invoke();

                    // Do not regenerate any more ammo after starting to fire.
                    if (m_RegenerateEvent != null)
                    {
                        Scheduler.Cancel(ref m_RegenerateEvent);
                    }

                    // Wait until the used event is called before firing.
                    if (!m_FireOnUsedEvent)
                    {
                        DoFire();
                    }
                    else
                    {
                        EventHandler.ExecuteEvent(m_Character, "OnUpdateAnimator");
                    }

                    return(true);
                }
                else
                {
#if ENABLE_MULTIPLAYER
                    m_NetworkMonitor.ExecuteItemEvent(m_ConsumableItemType.ID, "OnItemEmptyClip");
#else
                    EmptyClip();
#endif
                }
            }
            return(false);
        }
Exemplo n.º 9
0
 /// <summary>
 /// Try to cast the magic. The item may not be able be casted if the last cast time was too recent.
 /// <returns>True if the item was used.</returns>
 /// </summary>
 public bool TryUse()
 {
     if (!m_InUse && m_LastCastTime + m_UseDelay < Time.time)
     {
         if (m_Inventory.GetItemCount(m_ItemType) >= m_CastAmount)
         {
             m_LastCastTime = Time.time;
             m_InUse        = true;
             // Do not regenerate any more ammo after starting to use the item.
             if (m_RegenerateEvent != null)
             {
                 Scheduler.Cancel(ref m_RegenerateEvent);
             }
             EventHandler.ExecuteEvent(m_Character, "OnItemUse");
             return(true);
         }
         else
         {
             EventHandler.ExecuteEvent(m_Character, "OnItemStopUse");
         }
     }
     return(false);
 }
Exemplo n.º 10
0
        /// <summary>
        /// Stop firing the weapon. Cancel and reset the affected variables.
        /// </summary>
        /// <param name="success">Did the item successfully fire?</param>
        private void StopFiring(bool success)
        {
            // Can't stop firing if the weapon isn't firing to begin with.
            if (!m_IsFiring)
            {
                EventHandler.ExecuteEvent(m_Character, "OnItemStopUse");
                return;
            }

            m_IsFiring     = false;
            m_CurrentBurst = m_BurstRate;
            m_UseStates.NextState();

            if (m_FireEvent != null)
            {
                Scheduler.Cancel(ref m_FireEvent);
            }

            // Keep repeating the empty clip method until the stop used event is called.
            if (m_EmptyClipEvent == null && success &&
                ((m_FireMode != FireMode.SemiAuto && m_Inventory.GetItemCount(m_ConsumableItemType, true) == 0) || (m_FireMode == FireMode.Burst && m_CurrentBurst == 0)))
            {
                m_EmptyClipEvent = Scheduler.Schedule(m_ShootDelay, EmptyClip);
            }

            if (m_FireParticles)
            {
                m_FireParticles.Stop();
            }

            if (m_RegenerateDelay != 0)
            {
                m_RegenerateEvent = Scheduler.Schedule(m_RegenerateDelay, RegenerateAmmo);
            }

            EventHandler.ExecuteEvent(m_Character, "OnItemStopUse");
        }
Exemplo n.º 11
0
        /// <summary>
        /// The weapon no longer has any ammo. Play the empty clip audio.
        /// </summary>
        private void EmptyClip()
        {
            // Don't play another empty clip sound effect if it is already scheduled.
            if (m_EmptyClipEvent != null)
            {
                Scheduler.Cancel(ref m_EmptyClipEvent);
            }

            if (m_EmptyFireSound != null && m_EmptyFireSound.Length > 0 && !m_AudioSource.isPlaying)
            {
                m_AudioSource.clip = m_EmptyFireSound[Random.Range(0, m_EmptyFireSound.Length)];
                m_AudioSource.Play();
            }

            // Keep repeating until the stop used event is called.
            if ((m_FireMode != FireMode.SemiAuto && m_Inventory.GetItemCount(m_ConsumableItemType, true) == 0) || (m_FireMode == FireMode.Burst && m_CurrentBurst == 0))
            {
                m_EmptyClipEvent = Scheduler.Schedule(m_ShootDelay, EmptyClip);
            }
            else
            {
                EventHandler.ExecuteEvent(m_Character, "OnItemStopUse");
            }
        }
Exemplo n.º 12
0
 /// <summary>
 /// Stops the empty clip from playing.
 /// </summary>
 private void StopEmptyClip()
 {
     Scheduler.Cancel(ref m_EmptyClipEvent);
 }
Exemplo n.º 13
0
        /// <summary>
        /// The object has been damaged. Update the health and shield. Execute the OnDeath events if the health and shield is equal to zero.
        /// </summary>
        /// <param name="amount">The amount of damage taken.</param>
        /// <param name="position">The position of the damage.</param>
        /// <param name="force">The amount of force applied to the object while taking the damage.</param>
        /// <param name="radius">The radius of the explosive damage. If 0 then a non-exposive force will be used.</param>
        /// <param name="attacker">The GameObject that did the damage.</param>
        /// <param name="hitGameObject">The GameObject that was hit.</param>
        private void DamageLocal(float amount, Vector3 position, Vector3 force, float radius, GameObject attacker, GameObject hitGameObject)
        {
            // Add a multiplier if a particular GameObject was hit. Do not apply a multiplier if the damage is applied through a radius because multiple
            // GameObjects are hit.
            if (radius == 0 && hitGameObject != null)
            {
                DamageMultiplier damageMultiplier;
                if (m_DamageMultiplierMap != null && m_DamageMultiplierMap.TryGetValue(hitGameObject, out damageMultiplier))
                {
                    amount *= damageMultiplier.Multiplier;
                }
            }

            // Apply the damage to the shield first because the shield can regenrate.
            if (m_CurrentShield > 0)
            {
                var shieldAmount = Mathf.Min(amount, m_CurrentShield);
                amount -= shieldAmount;
                SetShieldAmount(m_CurrentShield - shieldAmount);
            }

            // Decrement the health by remaining amount after the shield has taken damage.
            if (m_CurrentHealth > 0)
            {
                SetHealthAmount(m_CurrentHealth - Mathf.Min(amount, m_CurrentHealth));
            }

            // Apply a force to the hit rigidbody if the force is greater than 0.
            if (m_Rigidbody != null && !m_Rigidbody.isKinematic && force.sqrMagnitude > 0)
            {
                if (radius == 0)
                {
                    m_Rigidbody.AddForceAtPosition(force, position);
                }
                else
                {
                    m_Rigidbody.AddExplosionForce(force.magnitude, position, radius);
                }
            }

            // Let other interested objects know that the object took damage.
            EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject>(m_GameObject, "OnHealthDamageDetails", amount, position, force, attacker);

            // The shield should stop regenerating when the object is taking damage.
            Scheduler.Cancel(ref m_ShieldRegenerativeEvent);

            // The object is dead when there is no more health or shield.
            if (!IsAlive())
            {
                Die(position, force, attacker);
                // Regenerate the shield if the unit is still alive after taking damage. The server should be the only object regenerating the shield if on the network.
#if ENABLE_MULTIPLAYER
            }
            else if (m_MaxShield > 0 && isServer)
            {
#else
            }
            else if (m_MaxShield > 0)
            {
#endif
                m_ShieldRegenerativeEvent = Scheduler.Schedule(m_ShieldRegenerativeInitialWait, RegenerateShield);
            }
        }