/// <summary> /// Applies damage to itself /// </summary> /// <param name="damage">Damage.</param> protected virtual void SelfDamage(int damage) { if (_health != null) { _health.Damage(damage, gameObject, 0f, DamageTakenInvincibilityDuration); } // we apply knockback to ourself if (_coreController != null) { Vector2 totalVelocity = _colliderCoreController.Speed + _velocity; Vector2 knockbackForce = new Vector2( -1 * Mathf.Sign(totalVelocity.x) * DamageTakenKnockbackForce.x, -1 * Mathf.Sign(totalVelocity.y) * DamageTakenKnockbackForce.y); if (DamageTakenKnockbackType == KnockbackStyles.SetForce) { _coreController.SetForce(knockbackForce); } if (DamageTakenKnockbackType == KnockbackStyles.AddForce) { _coreController.AddForce(knockbackForce); } } }
/// <summary> /// Handles the character status. /// </summary> protected virtual void HandleCharacterStatus() { // if the character is dead, we prevent it from moving horizontally if (ConditionState.CurrentState == CharacterStates.CharacterConditions.Dead) { _controller.SetHorizontalForce(0); return; } // if the character is frozen, we prevent it from moving if (ConditionState.CurrentState == CharacterStates.CharacterConditions.Frozen) { _controller.GravityActive(false); _controller.SetForce(Vector2.zero); } }
/// <summary> /// Describes what happens when colliding with a damageable object /// </summary> /// <param name="health">Health.</param> protected virtual void OnCollideWithDamageable(Health health) { // if what we're colliding with is a CorgiController, we apply a knockback force _colliderCoreController = health.gameObject.GetComponentNoAlloc <CoreController>(); if ((_colliderCoreController != null) && (DamageCausedKnockbackForce != Vector2.zero) && (!_colliderHealth.Invulnerable) && (!_colliderHealth.ImmuneToKnockback)) { _knockbackForce.x = DamageCausedKnockbackForce.x; if (DamageCausedKnockbackDirection == KnockbackDirections.BasedOnSpeed) { Vector2 totalVelocity = _colliderCoreController.Speed + _velocity; _knockbackForce.x *= -1 * Mathf.Sign(totalVelocity.x); } if (DamagedTakenKnockbackDirection == KnockbackDirections.BasedOnOwnerPosition) { if (Owner == null) { Owner = this.gameObject; } Vector2 relativePosition = _colliderCoreController.transform.position - Owner.transform.position; _knockbackForce.x *= Mathf.Sign(relativePosition.x); } _knockbackForce.y = DamageCausedKnockbackForce.y; if (DamageCausedKnockbackType == KnockbackStyles.SetForce) { _colliderCoreController.SetForce(_knockbackForce); } if (DamageCausedKnockbackType == KnockbackStyles.AddForce) { _colliderCoreController.AddForce(_knockbackForce); } } /*if (FreezeFramesOnHitDuration > 0) * { * MMEventManager.TriggerEvent(new MMFreezeFrameEvent(FreezeFramesOnHitDuration)); * }*/ // we apply the damage to the thing we've collided with _colliderHealth.Damage(DamageCaused, gameObject, InvincibilityDuration, InvincibilityDuration); SelfDamage(DamageTakenEveryTime + DamageTakenDamageable); }
/// <summary> /// Describes what happens when the weapon starts /// </summary> protected virtual void TurnWeaponOn() { SfxPlayWeaponStartSound(); WeaponState.ChangeState(WeaponStates.WeaponStart); if ((_characterHorizontalMovement != null) && (ModifyMovementWhileAttacking)) { _movementMultiplierStorage = _characterHorizontalMovement.MovementSpeedMultiplier; _characterHorizontalMovement.MovementSpeedMultiplier = MovementMultiplier; } if (_comboWeapon != null) { _comboWeapon.WeaponStarted(this); } if (PreventAllMovementWhileInUse && (_characterHorizontalMovement != null) && (_controller != null)) { _controller.SetForce(Vector2.zero); _characterHorizontalMovement.SetHorizontalMove(0f); _characterHorizontalMovement.MovementForbidden = true; } }
/// <summary> /// Called when the object takes damage /// </summary> /// <param name="damage">The amount of health points that will get lost.</param> /// <param name="instigator">The object that caused the damage.</param> /// <param name="flickerDuration">The time (in seconds) the object should flicker after taking the damage.</param> /// <param name="invincibilityDuration">The duration of the short invincibility following the hit.</param> public virtual void Damage(int damage, GameObject instigator, float flickerDuration, float invincibilityDuration, bool ignoreArmor = false) { // if the object is invulnerable, we do nothing and exit if (Invulnerable) { return; } // if we're already below zero, we do nothing and exit if ((CurrentHealth <= 0) && (InitialHealth != 0)) { return; } if (isBlocking) { PlaySound(blockSound); DamageDisabled(); StartCoroutine(DamageEnabled(invincibilityDuration)); Vector2 knockbackForce = new Vector2(3.0f, 0.0f); if (_character.IsFacingRight) { knockbackForce.x *= -1; } _controller.SetForce(knockbackForce); _stamina.spendStamina(blockStaminaSpend); gotHitCooldown = 5.0f; return; } gotHitCooldown = 5.0f; // we decrease the character's health by the damage float previousHealth = CurrentHealth; float rng = Random.Range(0.0f, 1.0f); ignoreArmor = (rng > 0.75f) ? true : ignoreArmor; CurrentHealth -= (ignoreArmor) ? damage : (damage - Armor); PlaySound(damageSound); if (OnHit != null) { OnHit(); } if (CurrentHealth < 0) { CurrentHealth = 0; } // we prevent the character from colliding with Projectiles, Player and Enemies if (invincibilityDuration > 0) { DamageDisabled(); StartCoroutine(DamageEnabled(invincibilityDuration)); } // we trigger a damage taken event // TODO:: Event Manager will do something //MMEventManager.TriggerEvent(new MMDamageTakenEvent(_character, instigator, CurrentHealth, damage, previousHealth)); if (_animator != null) { _animator.SetTrigger("Damage"); } // we play the sound the player makes when it gets hit PlayHitSfx(); // When the character takes damage, we create an auto destroy hurt particle system if (DamageEffect != null) { Instantiate(DamageEffect, transform.position, transform.rotation); } if (FlickerSpriteOnHit && !isBlocking) { // We make the character's sprite flicker if (_renderer != null) { StartCoroutine(Blink(flickerDuration, 0.05f, 0.05f)); } } //CharacterStates.CharacterTypes.AI if (_character.CharacterType == CharacterStates.CharacterTypes.Player) { UpdateHealthBar(true); } // if health has reached zero if (CurrentHealth <= 0) { // we set its health to zero (useful for the healthbar) CurrentHealth = 0; if (_character != null) { //Debug.Log("Character's Health is " + CurrentHealth); //if (_character.CharacterType == Character.CharacterTypes.Player) //{ // LevelManager.Instance.KillPlayer(_character); // return; //} } Kill(); } }