Пример #1
0
 /// <summary>
 /// This method gets called when the death timer starts.
 /// </summary>
 public virtual void WaitingToDestroyKillable(Killable deadKillable)
 {
     // your code here;
 }
Пример #2
0
 /// <summary>
 /// This method gets called when the Killable is prevented taking damage by invicibility.
 /// </summary>
 public virtual void DamagePrevented(int pointsDamage, Killable enemyHitBy)
 {
     // your code here.
 }
Пример #3
0
 /// <summary>
 /// This method gets called when the Killable is spawned.
 /// </summary>
 public virtual void Spawned(Killable newKillable)
 {
     // your code here
 }
Пример #4
0
 /// <summary>
 /// This method gets called when the Killable is taking damage.
 /// </summary>
 public virtual void TakingDamage(int pointsDamage, Killable enemyHitBy)
 {
     // your code here.
 }
Пример #5
0
        /// <summary>
        /// Call this method to inflict X points of damage to a Killable. 
        /// </summary>
        /// <param name="damagePoints">The number of points of damage to inflict.</param>
        /// <param name="enemy">The other Killable that collided with this one.</param>
        public virtual void TakeDamage(int damagePoints, Killable enemy)
        {
            var dmgPrefabsSpawned = false;
            var varsModded = false;
            var eventsFired = false;

            var knockBackSent = false;

            if (IsInvincible()) {
                if (damagePoints >= 0) {
                    LogIfEnabled("Taking no damage because Invincible is checked!");
                }

                if (listener != null) {
                    listener.DamagePrevented(damagePoints, enemy);
                }

                if (despawnMode == DespawnMode.CollisionOrTrigger) {
                    DestroyKillable();
                }

                // mod variables and spawn dmg prefabs
                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (!varsModded) {
                    ModifyWorldVariables(playerStatDamageModifiers, true);
                    varsModded = true;
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (!eventsFired && damageFireEvents) {
                    // ReSharper disable once ForCanBeConvertedToForeach
                    for (var i = 0; i < damageCustomEvents.Count; i++) {
                        var anEvent = damageCustomEvents[i].CustomEventName;

                        LevelSettings.FireCustomEventIfValid(anEvent, Trans.position);
                    }
                    eventsFired = true;
                }

                dmgPrefabsSpawned = SpawnDamagePrefabsIfPerHit(damagePoints);
                // end mod variables and spawn dmg prefabs

                if (sendDamageKnockback) {
                    knockBackSent = true;
                    Knockback(enemy);
                }

                if (damagePoints >= 0) {
                    // allow negative damage to continue
                    return;
                }
            }

            if (listener != null) {
                listener.TakingDamage(damagePoints, enemy);
            }

            if (sendDamageKnockback && !knockBackSent) {
                Knockback(enemy);
            }

            // mod variables and spawn dmg prefabs
            if (!varsModded) {
                ModifyWorldVariables(playerStatDamageModifiers, true);
                varsModded = true;
            }

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if (!eventsFired && damageFireEvents) {
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < damageCustomEvents.Count; i++) {
                    var anEvent = damageCustomEvents[i].CustomEventName;

                    LevelSettings.FireCustomEventIfValid(anEvent, Trans.position);
                }
                // ReSharper disable once RedundantAssignment
                eventsFired = true;
            }

            if (!dmgPrefabsSpawned) {
                dmgPrefabsSpawned = SpawnDamagePrefabsIfPerHit(damagePoints);
            }
            // end mod variables and spawn dmg prefabs

            if (damagePoints == 0) {
                return;
            }

            if (enableLogging) {
                LogIfEnabled("Taking " + damagePoints + " points damage!");
            }

            currentHitPoints -= damagePoints;

            if (currentHitPoints < 0) {
                currentHitPoints = 0;
            } else if (currentHitPoints > maxHitPoints.Value) {
                currentHitPoints = maxHitPoints.Value;
            }

            if (hitPoints.variableSource == LevelSettings.VariableSource.Variable && syncHitPointWorldVariable) {
                var aVar = WorldVariableTracker.GetWorldVariable(hitPoints.worldVariableName);
                if (aVar != null) {
                    aVar.CurrentIntValue = currentHitPoints;
                }
            }

            switch (retriggerLimitMode) {
                case TriggeredSpawner.RetriggerLimitMode.FrameBased:
                    _triggeredLastFrame = Time.frameCount;
                    break;
                case TriggeredSpawner.RetriggerLimitMode.TimeBased:
                    _triggeredLastTime = Time.time;
                    break;
            }

            // mod variables and spawn dmg prefabs
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            // ReSharper disable HeuristicUnreachableCode
            if (!varsModded) {
                ModifyWorldVariables(playerStatDamageModifiers, true);
                // ReSharper disable once RedundantAssignment
                varsModded = true;
            }
            // ReSharper restore HeuristicUnreachableCode

            if (!dmgPrefabsSpawned) {
                SpawnDamagePrefabs(damagePoints);
            }
            // end mod variables and spawn dmg prefabs

            switch (despawnMode) {
                case DespawnMode.ZeroHitPoints:
                    if (currentHitPoints > 0) {
                        return;
                    }
                    break;
                case DespawnMode.None:
                    return;
            }

            KilledBy = enemy;
            DestroyKillable();
        }
Пример #6
0
        public void UnregisterChildKillable(Killable kill)
        {
            _childKillables.Remove(kill);

            deathDespawnBehavior = DeathDespawnBehavior.Disable;

            if (_childKillables.Count == 0 && invincibleWhileChildrenKillablesExist &&
                disableCollidersWhileChildrenKillablesExist) {
                EnableColliders();
            }

            // Diagnostic code to uncomment if things are going wrong.
            //Debug.Log("REMOVE - children of '" + name + "': " + childKillables.Count);
        }
Пример #7
0
        public void RecordChildToDie(Killable kilChild)
        {
            if (_childrenToDestroy.Contains(kilChild)) {
                return;
            }

            _childrenToDestroy.Add(kilChild);
        }
Пример #8
0
 /// <summary>
 /// This method when damage is valid and is about to be inflicted (no invincibility).
 /// </summary>
 /// <param name="damagePoints">Number of damage points to take.</param>
 /// <param name="enemy">The enemy that dealt the damage.</param>
 protected virtual void TakingDamage(int damagePoints, Killable enemy)
 {
     if (listener != null) {
         listener.TakingDamage(damagePoints, enemy);
     }
 }
Пример #9
0
        private void CheckForAttackPoints(Killable enemy, GameObject goHit)
        {
            if (enemy == null) {
                LogIfEnabled("Not taking any damage because you've collided with non-Killable object '" + goHit.name +
                             "'.");
                return;
            }

            if (ignoreKillablesSpawnedByMe) {
                if (enemy.SpawnedFromObjectId == KillableId) {
                    LogIfEnabled("Not taking any damage because you've collided with a Killable named '" + goHit.name +
                                 "' spawned by this Killable.");
                    return;
                }
            }

            TakeDamage(enemy.atckPoints.Value, enemy);
        }
Пример #10
0
        /// <summary>
        /// This will knock back (and up) any combatents fighting with this Killable.
        /// </summary>
        /// <param name="enemy">The enemy knocking this Killable back.</param>
        public virtual void Knockback(Killable enemy)
        {
            if (atckPoints.Value <= 0 || !sendDamageKnockback || enemy == null) {
                return;
            }

            if (enemy.IsInvincible()) {
                if (!enemy.ReceiveKnockbackWhenInvince) {
                    return;
                }
            } else {
                if (!enemy.ReceiveKnockbackWhenDamaged) {
                    return;
                }
            }

            if (!IsGravBody) {
                return;
            }

            var pushHeight = damageKnockUpMeters.Value;
            var pushForce = damageKnockBackFactor.Value;

            var pushDir = (enemy.transform.position - transform.position);
            pushDir.y = 0f;

            if (Body != null) {
                var enemyBody = enemy.GetComponent<Rigidbody>();

                enemyBody.velocity = new Vector3(0, 0, 0);
                enemyBody.AddForce(pushDir.normalized * pushForce, ForceMode.VelocityChange);
                enemyBody.AddForce(Vector3.up * pushHeight, ForceMode.VelocityChange);
            } else {
                // Rigidbody 2D
                var enemyBody2D = enemy.GetComponent<Rigidbody2D>();

                enemyBody2D.velocity = new Vector2(0, 0);
                var knockback = Vector2.right * pushForce; // knock right

                if (enemy.transform.position.x < Trans.position.x) {
                    knockback *= -1; // knock left
                }

                enemyBody2D.AddForce(knockback, ForceMode2D.Impulse);
                enemyBody2D.AddForce(Vector3.up * pushHeight, ForceMode2D.Impulse);
            }
        }
Пример #11
0
        /// <summary>
        /// This method gets called whenever the object is spawned or starts in a Scene (from Awake event)
        /// </summary>
        /// <param name="spawned">True if spawned, false if in the Scene at beginning.</param>
        protected virtual void SpawnedOrAwake(bool spawned = true)
        {
            if (listener != null) {
                listener.Spawned(this);
            }

            KilledBy = null;
            _waitingToDestroy = false;

            _childrenToDestroy.Clear();

            if (parentDestroyedAction != SpawnerDestroyedBehavior.DoNothing && parentKillableForParentDestroyed != null) {
                parentKillableForParentDestroyed.RecordChildToDie(this);
            }

            // anything you want to do each time this is spawned.
            if (_timesRespawned == 0) {
                isVisible = false;
                _becameVisible = false;
            }

            _isDespawning = false;
            _spawnTime = Time.time;
            _isTemporarilyInvincible = false;

            if (respawnType != RespawnType.None && !_spawnLocationSet) {
                _respawnLocation = Trans.position;
                _spawnLocationSet = true;
            }

            // respawning from "respawn" setting.
            if (_timesRespawned > 0) {
                Trans.position = _respawnLocation;
            } else {
                // register child Killables with parent, if any
                var aParent = Trans.parent;
                while (aParent != null) {
                    _parentKillable = aParent.GetComponent<Killable>();
                    if (_parentKillable == null) {
                        aParent = aParent.parent;
                        continue;
                    }

                    _parentKillable.RegisterChildKillable(this);
                    break;
                }
            }

            currentHitPoints = hitPoints.Value;

            _damageTaken = 0;
            _damagePrefabsSpawned = 0;

            if (deathPrefabPoolName != null && deathPrefabSource == WaveSpecifics.SpawnOrigin.PrefabPool) {
                _deathPrefabWavePool = LevelSettings.GetFirstMatchingPrefabPool(deathPrefabPoolName);
                if (_deathPrefabWavePool == null) {
                    LevelSettings.LogIfNew("Death Prefab Pool '" + deathPrefabPoolName + "' not found for Killable '" +
                                           name + "'.");
                }
            }
            if (damagePrefabSpawnMode != DamagePrefabSpawnMode.None && damagePrefabPoolName != null &&
                damagePrefabSource == SpawnSource.PrefabPool) {
                _damagePrefabWavePool = LevelSettings.GetFirstMatchingPrefabPool(damagePrefabPoolName);
                if (_damagePrefabWavePool == null) {
                    LevelSettings.LogIfNew("Damage Prefab Pool '" + _damagePrefabWavePool + "' not found for Killable '" +
                                           name + "'.");
                }
            }

            if (damagePrefabSpawnMode != DamagePrefabSpawnMode.None && damagePrefabSource == SpawnSource.Specific &&
                damagePrefabSpecific == null) {
                LevelSettings.LogIfNew(string.Format("Damage Prefab for '{0}' is not assigned.", Trans.name));
            }

            CheckForValidVariables();

            StopAllCoroutines(); // for respawn purposes.
            StartCoroutine(CoUpdate());

            deathDespawnBehavior = DeathDespawnBehavior.ReturnToPool;

            if (invincibleOnSpawn) {
                TemporaryInvincibility(invincibleTimeSpawn.Value);
            }
        }
Пример #12
0
        /// <summary>
        /// Call this method to inflict X points of damage to a Killable. 
        /// </summary>
        /// <param name="damagePoints">The number of points of damage to inflict.</param>
        /// <param name="enemy">The other Killable that collided with this one.</param>
        public virtual void TakeDamage(int damagePoints, Killable enemy)
        {
            var dmgPrefabsSpawned = false;
            var dealDmgPrefabSpawned = false;
            var varsModded = false;
            var eventsFired = false;

            var knockBackSent = false;

            if (IsInvincible()) {
                SpawnInvinceHitPrefab();

                if (damagePoints >= 0) {
                    LogIfEnabled("Taking no damage because it's currently invincible!");
                }

                if (listener != null) {
                    DamagePrevented(damagePoints, enemy);
                }

                if (despawnMode == DespawnMode.CollisionOrTrigger) {
                    DestroyKillable();
                }

                // mod variables and spawn dmg prefabs
                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (!varsModded) {
                    ModifyWorldVariables(playerStatDamageModifiers, true);
                    varsModded = true;
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if (!eventsFired && damageFireEvents) {
                    // ReSharper disable once ForCanBeConvertedToForeach
                    for (var i = 0; i < damageCustomEvents.Count; i++) {
                        var anEvent = damageCustomEvents[i].CustomEventName;

                        LevelSettings.FireCustomEventIfValid(anEvent, Trans.position);
                    }
                    eventsFired = true;
                }

                dmgPrefabsSpawned = SpawnDamagePrefabsIfPerHit(damagePoints);
                // end mod variables and spawn dmg prefabs

                if (sendDamageKnockback) {
                    knockBackSent = true;
                    Knockback(enemy);
                }

                if (damagePoints >= 0) {
                    // allow negative damage to continue
                    return;
                }
            }

            TakingDamage(damagePoints, enemy);

            if (sendDamageKnockback && !knockBackSent) {
                Knockback(enemy);
            }

            var newHP = currentHitPoints - damagePoints;
            var isDeathHit = newHP <= 0 || (despawnMode == DespawnMode.LostAnyHitPoints && damagePoints > 0) || (despawnMode == DespawnMode.CollisionOrTrigger);

            // mod variables and spawn dmg prefabs
            if (!varsModded) {
                ModifyWorldVariables(playerStatDamageModifiers, true);
                varsModded = true;
            }

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if (!eventsFired && damageFireEvents) {
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < damageCustomEvents.Count; i++) {
                    var anEvent = damageCustomEvents[i].CustomEventName;

                    LevelSettings.FireCustomEventIfValid(anEvent, Trans.position);
                }
                // ReSharper disable once RedundantAssignment
                eventsFired = true;
            }

            var shouldSpawnDmgPrefab = !isDeathHit || damagePrefabOnDeathHit;
            var shouldSpawnDealDmgPrefab = !isDeathHit || (enemy != null && enemy.dealDamagePrefabOnDeathHit);

            if (!dmgPrefabsSpawned && shouldSpawnDmgPrefab) {
                dmgPrefabsSpawned = SpawnDamagePrefabsIfPerHit(damagePoints);
            }

            if (shouldSpawnDealDmgPrefab) {
                dealDmgPrefabSpawned = SpawnDealDamagePrefabsIfTakingDamage(damagePoints, enemy);
            }

            // end mod variables and spawn dmg prefabs

            if (damagePoints == 0 && !isDeathHit) {
                return;
            }

            if (enableLogging) {
                LogIfEnabled("Taking " + damagePoints + " points damage!");
            }

            currentHitPoints = newHP;

            if (currentHitPoints < 0) {
                currentHitPoints = 0;
            } else if (currentHitPoints > maxHitPoints.Value) {
                currentHitPoints = maxHitPoints.Value;
            }

            // must do this first so you don't turn invincible by the next lines!
            if (!dealDmgPrefabSpawned && isDeathHit && (enemy != null && enemy.dealDamagePrefabOnDeathHit)) {
                SpawnDealDamagePrefabsIfTakingDamage(damagePoints, enemy);
            }

            if (invincibleWhenDamaged && currentHitPoints > 0) {
                TemporaryInvincibility(invincibleDamageTime.Value);
            }

            if (hitPoints.variableSource == LevelSettings.VariableSource.Variable && syncHitPointWorldVariable) {
                var aVar = WorldVariableTracker.GetWorldVariable(hitPoints.worldVariableName);
                if (aVar != null) {
                    aVar.CurrentIntValue = currentHitPoints;
                }
            }

            // mod variables and spawn dmg prefabs
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            // ReSharper disable HeuristicUnreachableCode
            if (!varsModded) {
                ModifyWorldVariables(playerStatDamageModifiers, true);
                // ReSharper disable once RedundantAssignment
                varsModded = true;
            }
            // ReSharper restore HeuristicUnreachableCode

            if (!dmgPrefabsSpawned && shouldSpawnDmgPrefab) {
                SpawnDamagePrefabs(damagePoints);
            }

            // end mod variables and spawn dmg prefabs

            switch (despawnMode) {
                case DespawnMode.ZeroHitPoints:
                    if (currentHitPoints > 0) {
                        return;
                    }
                    break;
                case DespawnMode.None:
                    return;
            }

            KilledBy = enemy;
            DestroyKillable();
        }
Пример #13
0
        private bool SpawnDealDamagePrefabsIfTakingDamage(int damagePoints, Killable enemy)
        {
            if (IsInvincible() || damagePoints <= 0) { // do not spawn deal damage prefabs when invincible or no damage
                return false;
            }

            if (enemy == null) {
                return false;
            }

            var prefabToSpawn = enemy.CurrentDealDamagePrefab;
            if (prefabToSpawn == null) {
                // empty element, spawn nothing
                return false;
            }

            var spawnedDealDamagePrefab = SpawnPrefab(prefabToSpawn, Trans.position);
            // ReSharper disable once InvertIf
            if (spawnedDealDamagePrefab != null) {
                SpawnUtility.RecordSpawnerObjectIfKillable(spawnedDealDamagePrefab, GameObj);

                // affect the spawned object.
                var euler = prefabToSpawn.rotation.eulerAngles;

                if (enemy.dealDamagePrefabRandomizeXRotation) {
                    euler.x = UnityEngine.Random.Range(0f, 360f);
                }
                if (enemy.dealDamagePrefabRandomizeYRotation) {
                    euler.y = UnityEngine.Random.Range(0f, 360f);
                }
                if (enemy.dealDamagePrefabRandomizeZRotation) {
                    euler.z = UnityEngine.Random.Range(0f, 360f);
                }

                spawnedDealDamagePrefab.rotation = Quaternion.Euler(euler);
            }

            return true;
        }
Пример #14
0
 /// <summary>
 /// This method gets called when the Killable is destroyed.
 /// </summary>
 public virtual void DestroyingKillable(Killable deadKillable)
 {
     // your code here.
 }
Пример #15
0
        public void RegisterChildKillable(Killable kill)
        {
            if (_childKillables.Contains(kill)) {
                return;
            }

            _childKillables.Add(kill);

            if (invincibleWhileChildrenKillablesExist && disableCollidersWhileChildrenKillablesExist) {
                DisableColliders();
            }

            // Diagnostic code to uncomment if things are going wrong.
            //Debug.Log("ADD - children of '" + name + "': " + childKillables.Count);
        }
Пример #16
0
        /// <summary>
        /// This method gets called when the Scenario is about to be decided. You can add logic to decide the Scenario here.
        /// </summary>
        public virtual string DeterminingScenario(Killable deadKillable, string scenario)
        {
            // if you wish to use logic to change the Scenario, do it here. Example below.

            // if (yourLogicHere == true) {
            //   scenario = "ReachedTower";
            // }

            return scenario;
        }
Пример #17
0
 /// <summary>
 /// This method is called when damage is prevents by Invincibility
 /// </summary>
 /// <param name="pointsDamage">The number of points prevented.</param>
 /// <param name="enemyHitBy">The enemy that tried to inflict damage.</param>
 protected virtual void DamagePrevented(int pointsDamage, Killable enemyHitBy)
 {
     listener.DamagePrevented(pointsDamage, enemyHitBy);
 }