// Returns true if the target is being attacked from the rear. // Doesn't include attacks from the left or right. private bool IsBackstab(ObjectMechanics target) { float rotation1 = target.transform.eulerAngles.y; float rotation2 = transform.eulerAngles.y; return(VeryApproximateMatch(Mathf.Abs(rotation1 - rotation2), 0.0f) || VeryApproximateMatch(Mathf.Abs(rotation1 - rotation2), 360.0f)); }
public void PerformAttackWithStatusEffect(ObjectMechanics target, StatusEffect.EffectType type, int duration, int powerLevel = -1, float damageMultiplier = 1.0f) { if (HitAndDamage(target, false, damageMultiplier)) { new StatusEffect(type, duration, target, powerLevel); } }
IEnumerator AttackAfterDelay(float time, ObjectMechanics targetMechanics) { yield return(new WaitForSeconds(time)); if (targetMechanics != null) // If the target wasn't destroyed by the first attack. { mechanics.PerformAttackWithStatusEffect(targetMechanics, StatusEffect.EffectType.SLOWED, 2, -1, 0.5f); } yield break; }
private bool IsCrit(ObjectMechanics target, bool isBackstab) { int chance = CritChance(); if (isBackstab) { chance *= 2; } return(PercentRoll(chance)); }
IEnumerator AttackAfterDelay(float time, ObjectMechanics targetMechanics) { yield return(new WaitForSeconds(time)); if (targetMechanics != null) // If the target wasn't destroyed by the first attack. { mechanics.PerformBasicAttack(targetMechanics, false); } yield break; }
void ResolveAttack(GameObject target) { spentActionPoints += MIN_AP_COST; ObjectMechanics targetMechanics = target.GetComponent <CreatureMechanics>(); if (targetMechanics == null) { targetMechanics = target.GetComponent <ObjectMechanics>(); } AttackEffects(targetMechanics); }
// Some status effects have varying power levels, others default to -1 public StatusEffect(EffectType effectType, int durationRounds, ObjectMechanics effectTarget, int effectPowerLevel = -1) { // Only CreatureMechanics can get status effects. if (effectTarget.GetType() == typeof(ObjectMechanics)) { return; } roundsRemaining = durationRounds; type = effectType; target = (CreatureMechanics)effectTarget; powerLevel = effectPowerLevel; target.RegisterStatusEffect(this); }
private float HeightAdvantageMultiplier(ObjectMechanics target) { float relativeHeight = transform.position.y - target.transform.position.y; if (relativeHeight > 0.25f) { return(1.2f); } if (relativeHeight > 0f) { return(1.1f); } return(1.0f); }
// Main attack function. Applies damage and returns true if there is a hit. // Returns false if there is a miss. private bool HitAndDamage(ObjectMechanics target, bool isConcentrationEligible, float damageMultiplier) { if (isConcentrationEligible) { BoostConcentration(); } Animate("IsAttacking"); if (!PercentRoll(HitChance())) { SoundManager.PlaySound(attackSound); target.Animate("IsDodging"); DisplayPopupAfterDelay(0.2f, "Miss"); return(false); } if (PercentRoll(target.DodgeChance())) { SoundManager.PlaySound(attackSound); target.Animate("IsDodging"); target.DisplayPopupAfterDelay(0.2f, "Dodge"); return(false); } int dam = DamageInflicted(); bool backstab = false; if (IsVulnerable(target)) { if (isConcentrationEligible) { BoostConcentration(); } backstab = true; dam += BonusRearDamage(); } // Critical hits apply a +100% multiplier, after all fixed modifiers are considered. if (IsCrit(target, backstab)) { dam += dam; DisplayPopupAfterDelay(0.2f, "Crit"); } else if (backstab) // Only display the backstab popup if it's not a crit. { DisplayPopupAfterDelay(0.2f, "Backstab"); } damageMultiplier *= HeightAdvantageMultiplier(target); dam = (int)((float)dam * damageMultiplier); target.ReceiveDamage(dam); return(true); }
private bool IsVulnerable(ObjectMechanics target) { if (StatusEffect.HasEffectType(ref target.statusEffects, StatusEffect.EffectType.PETRIFIED)) { return(false); } if (!target.canBeBackstabbed) { return(false); } if (IsBackstab(target)) { return(true); } if (StatusEffect.HasEffectType(ref target.statusEffects, StatusEffect.EffectType.KNOCKDOWN)) { return(true); } if (StatusEffect.HasEffectType(ref target.statusEffects, StatusEffect.EffectType.BLINDED)) { return(true); } return(false); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { new StatusEffect(StatusEffect.EffectType.FROZEN, 2, targetMechanics, -1); targetMechanics.DisplayPopup("Frozen"); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { new StatusEffect(StatusEffect.EffectType.PETRIFIED, 3, targetMechanics, -1); targetMechanics.DisplayPopup("Petrified"); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { mechanics.PerformAttackWithStatusEffect(targetMechanics, StatusEffect.EffectType.BURNING, 2); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { new StatusEffect(StatusEffect.EffectType.BLINDED, 2, targetMechanics, -1); targetMechanics.DisplayPopup("Blinded"); }
virtual protected void AttackEffects(ObjectMechanics targetStats) { mechanics.PerformBasicAttack(targetStats); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { new StatusEffect(StatusEffect.EffectType.EMPOWER, 2, targetMechanics, -1); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { mechanics.PerformBasicAttack(targetMechanics, false, 0.5f); }
// Public wrapper for HitAndDamage public void PerformBasicAttack(ObjectMechanics target, bool isConcentrationEligible = true, float damageMultiplier = 1.0f) { HitAndDamage(target, isConcentrationEligible, damageMultiplier); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { mechanics.PerformAttackWithStatusEffect(targetMechanics, StatusEffect.EffectType.KNOCKDOWN, 1, -1, 0.5f); StartCoroutine(AttackAfterDelay(1.0f, targetMechanics)); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { mechanics.PerformBasicAttack(targetMechanics, false); StartCoroutine(AttackAfterDelay(1.0f, targetMechanics)); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { mechanics.PerformAttackWithStatusEffect(targetMechanics, StatusEffect.EffectType.KNOCKDOWN, 1, -1, 0.5f); }
override protected void AttackEffects(ObjectMechanics targetMechanics) { new StatusEffect(StatusEffect.EffectType.BURNING, 5, targetMechanics, -1); targetMechanics.DisplayPopup("Ignited"); }