// Initialization + Setup #region public void SetupBaseProperties(AbilityDataSO abilityFromLibrary) { myAbilityData = abilityFromLibrary; // only for defenders. enemies don't have ability button gameobjects if (abilityImage) { abilityImage.sprite = abilityFromLibrary.sprite; } // Set base properties abilityName = abilityFromLibrary.abilityName; abilityDescription = abilityFromLibrary.description; abilityBaseCooldownTime = abilityFromLibrary.baseCooldownTime; abilityEnergyCost = abilityFromLibrary.energyCost; abilityRange = abilityFromLibrary.range; abilityPrimaryValue = abilityFromLibrary.primaryValue; abilitySecondaryValue = abilityFromLibrary.secondaryValue; abilityDamageType = abilityFromLibrary.damageType; abilityType = abilityFromLibrary.abilityType; weaponDamagePercentage = abilityFromLibrary.weaponDamagePercentage; requiresMeleeWeapon = abilityFromLibrary.requiresMeleeWeapon; requiresRangedWeapon = abilityFromLibrary.requiresRangedWeapon; requiresShield = abilityFromLibrary.requiresShield; // Set up info panel for defenders if (myLivingEntity != null && myLivingEntity.defender) { AbilityInfoSheetController.Instance.BuildSheetFromData(abilityInfoSheet, abilityFromLibrary, AbilityInfoSheet.PivotDirection.Upwards); } }
public float CalculateAndGetDamagePercentageModifier(LivingEntity attacker, LivingEntity victim, AbilityDataSO.DamageType damageType) { // Get damage type first AbilityDataSO.DamageType DamageType = damageType; // TO DO in future: this is where we modify the damage type based on character traits // (e.g. if a character has a buff that makes all it damage types magical float damageModifier = 1f; if (victim.isKnockedDown) { damageModifier += 0.5f; } if (victim.myPassiveManager.Exposed) { damageModifier += 0.5f; } if (attacker.myPassiveManager.Exhausted) { damageModifier -= 0.5f; } /* * if (PositionLogic.Instance.CanAttackerHitTargetsBackArc(attacker, victim)) * { * damageModifier += 1f; * } */ if (victim.myPassiveManager.Flanked) { damageModifier += 0.5f; } if (victim.myPassiveManager.MagicImmunity && DamageType == AbilityDataSO.DamageType.Magic) { damageModifier = 0; } if (victim.myPassiveManager.PhysicalImmunity && DamageType == AbilityDataSO.DamageType.Physical) { damageModifier = 0; } // prevent modifier from going negative if (damageModifier < 0) { damageModifier = 0; } return(damageModifier); }
public void SetupBaseProperties(AbilityDataSO abilityFromLibrary) { myAbilityData = abilityFromLibrary; abilityImage = abilityFromLibrary.abilityImage; Image image = GetComponent <Image>(); // only for defenders. enemies don't have ability button gameobjects, so GetComponent<Image> will cause a null ref on enemies. if (image) { GetComponent <Image>().sprite = abilityImage; } abilityName = abilityFromLibrary.abilityName; abilityDescription = abilityFromLibrary.abilityDescription; abilityBaseCooldownTime = abilityFromLibrary.abilityBaseCooldownTime; abilityAPCost = abilityFromLibrary.abilityAPCost; abilityRange = abilityFromLibrary.abilityRange; abilityPrimaryValue = abilityFromLibrary.abilityPrimaryValue; abilitySecondaryValue = abilityFromLibrary.abilitySecondaryValue; abilityAttackType = abilityFromLibrary.abilityAttackType; abilityDamageType = abilityFromLibrary.abilityDamageType; usesMeleeWeapon = abilityFromLibrary.usesMeleeWeapon; usesRangedWeapon = abilityFromLibrary.usesRangedWeapon; // Set up info panel for defenders if (myLivingEntity.GetComponent <Defender>()) { cdText.text = abilityFromLibrary.abilityBaseCooldownTime.ToString(); rangeText.text = abilityFromLibrary.abilityRange.ToString(); apCostText.text = abilityFromLibrary.abilityAPCost.ToString(); nameText.text = abilityFromLibrary.abilityName.ToString(); descriptionText.text = abilityFromLibrary.abilityDescription.ToString(); } }
// Overload method used for aoe damage events not caused by spells/abilities (e.g. volatile passive) public void CreateAoEAttackEvent(LivingEntity attacker, int damage, TileScript aoeCentrePoint, int aoeSize, bool excludeCentreTile, bool friendlyFire, AbilityDataSO.DamageType damageType) { Debug.Log("Starting new AoE damage event..."); Defender defender = attacker.GetComponent <Defender>(); Enemy enemy = attacker.GetComponent <Enemy>(); List <TileScript> tilesInAoERadius = LevelManager.Instance.GetTilesWithinRange(aoeSize, aoeCentrePoint, excludeCentreTile); List <LivingEntity> livingEntitiesWithinAoeRadius = new List <LivingEntity>(); List <LivingEntity> finalList = new List <LivingEntity>(); // Get all living entities within the blast radius foreach (LivingEntity livingEntity in LivingEntityManager.Instance.allLivingEntities) { if (tilesInAoERadius.Contains(livingEntity.TileCurrentlyOn)) { livingEntitiesWithinAoeRadius.Add(livingEntity); } } // if this ability doesn't not damage friendly targets, filter out friendly targets from the list if (friendlyFire == false) { foreach (LivingEntity livingEntity in livingEntitiesWithinAoeRadius) { if (defender && livingEntity.GetComponent <Enemy>()) { finalList.Add(livingEntity); } else if (enemy && livingEntity.GetComponent <Defender>()) { finalList.Add(livingEntity); } } } // Else if this ability can damage everything, add all living entities within the blast radius to the final list else if (friendlyFire == true) { finalList.AddRange(livingEntitiesWithinAoeRadius); } // Deal damage to all characters in the final list foreach (LivingEntity livingEntity in finalList) { //livingEntity.HandleDamage(livingEntity.CalculateDamage(damage, livingEntity, attacker), attacker, true); HandleDamage(CalculateDamage(damage, livingEntity, attacker, damageType), attacker, livingEntity, true); } }
public int CalculateDamage(int abilityBaseDamage, LivingEntity victim, LivingEntity attacker, AbilityDataSO.DamageType damageType) { int newDamageValue = 0; // Establish base ability damage value newDamageValue += abilityBaseDamage; Debug.Log("Base damage value: " + newDamageValue); // add bonus strength newDamageValue += attacker.currentStrength; Debug.Log("Damage value after strength added: " + newDamageValue); // multiply/divide the damage value based on factors like vulnerable, knock down, magic vulnerability, etc newDamageValue = (int)(newDamageValue * CalculateAndGetDamagePercentageModifier(attacker, victim, damageType)); Debug.Log("Damage value after percentage modifers like knockdown added: " + newDamageValue); return(newDamageValue); }
public void HandleDamage(int damageAmount, LivingEntity attacker, LivingEntity victim, bool playVFXInstantly = false, AbilityDataSO.AttackType attackType = AbilityDataSO.AttackType.None, AbilityDataSO.DamageType damageType = AbilityDataSO.DamageType.None) { int blockAfter = victim.currentBlock; int healthAfter = victim.currentHealth; if (victim.currentBlock == 0) { healthAfter = victim.currentHealth - damageAmount; blockAfter = 0; } else if (victim.currentBlock > 0) { blockAfter = victim.currentBlock; Debug.Log("block after = " + blockAfter); blockAfter = blockAfter - damageAmount; Debug.Log("block after = " + blockAfter); if (blockAfter < 0) { healthAfter = victim.currentHealth; healthAfter += blockAfter; blockAfter = 0; Debug.Log("block after = " + blockAfter); } } if (victim.hasBarrier && healthAfter < victim.currentHealth) { damageAmount = 0; healthAfter = victim.currentHealth; victim.ModifyCurrentBarrierStacks(-1); } // Poisonous trait if (attacker.myPassiveManager.Poisonous && healthAfter < victim.currentHealth) { victim.ModifyPoison(attacker.myPassiveManager.poisonousStacks); } // Remove sleeping if (victim.isSleeping && damageAmount > 0) { Debug.Log("Damage taken, removing sleep"); victim.ModifySleeping(-victim.currentSleepingStacks); } // Enrage if (victim.myPassiveManager.Enrage && healthAfter < victim.currentHealth) { Debug.Log("Enrage triggered, gaining strength"); victim.ModifyCurrentStrength(victim.myPassiveManager.enrageStacks); } if (victim.myPassiveManager.Adaptive && healthAfter < victim.currentHealth) { Debug.Log("Adaptive triggered, gaining block"); victim.ModifyCurrentBlock(victim.myPassiveManager.adaptiveStacks); } // remove camoflage if damaged if (victim.isCamoflaged && healthAfter < victim.currentHealth) { victim.RemoveCamoflage(); } victim.currentHealth = healthAfter; victim.currentBlock = blockAfter; victim.myHealthBar.value = victim.CalculateHealthBarPosition(); victim.UpdateCurrentHealthText(); victim.SetCurrentBlock(victim.currentBlock); if (damageAmount > 0) { StartCoroutine(VisualEffectManager.Instance.CreateDamageEffect(victim.transform.position, damageAmount, playVFXInstantly)); } if (victim.myPassiveManager.Thorns) { // TO DO: this needs be updated when we implement damage and attack types // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies // thorns damage can only be triggered by a melee attack if (attackType == AbilityDataSO.AttackType.Melee) { HandleDamage(CalculateDamage(victim.myPassiveManager.thornsStacks, victim, attacker, AbilityDataSO.DamageType.None), attacker, victim); } } if (victim.myPassiveManager.LightningShield) { // TO DO: this needs be updated when we implement damage and attack types // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies // thorns damage can only be triggered by a melee attack HandleDamage(CalculateDamage(victim.myPassiveManager.lightningShieldStacks, victim, attacker, AbilityDataSO.DamageType.Magic), attacker, victim); } if (victim.timesAttackedThisTurn == 0 && victim.myPassiveManager.QuickReflexes && victim.IsAbleToMove()) { StartCoroutine(VisualEffectManager.Instance.CreateStatusEffect(victim.transform.position, "Quick Reflexes", true)); StartCoroutine(victim.StartQuickReflexesMove()); } victim.timesAttackedThisTurn++; if (victim.currentHealth <= 0) { StartCoroutine(victim.HandleDeath()); } }