void OnEntityDeath(HealthEntityCombatObject entity) { if (entity is PlayerCombatObject) { bool allPlayersDead = true; foreach (var player in players) { if (!player.IsDead) { allPlayersDead = false; break; } } if (allPlayersDead) { FindObjectOfType <AudioManager>().PlayClip(DefeatSound); StopCoroutine(EnemyTurnCoroutine); combatOver = true; StartCoroutine(EndBattleCoroutine(true)); } } else if (entity is EnemyCombatObject) { OnEnemyDeath(entity); } }
/// <summary> /// Get all entities in combat with the relationship as alignment to the reference entity. /// </summary> /// <param name="entity">The reference entity</param> /// <param name="alignment">Relationship with the required entity</param> /// <param name="targetSelf">Can target itself?</param> /// <param name="canTargetUntargetable">Can target untargetable targets?</param> /// <returns></returns> List <HealthEntityCombatObject> GetEntitiesWithRelationTo(HealthEntityCombatObject entity, TargetingData_Base.TargetAlignment alignment, bool targetSelf = false, bool canTargetUntargetable = false, bool canTargetDead = false) { List <HealthEntityCombatObject> entities = new List <HealthEntityCombatObject>(); foreach (var e in AllEntities) { switch (alignment) { case TargetingData_Base.TargetAlignment.Both: if (ValidTarget(entity, canTargetUntargetable, canTargetDead)) { entities.Add(e); } break; default: if (e.GetFaction(alignment) == entity.alignment && (targetSelf && e == entity || e != entity) && ValidTarget(entity, canTargetUntargetable, canTargetDead)) { entities.Add(e); } break; } } return(entities); }
/// <summary> /// Takes 2 parameters: List<HealthEntityCombatObject> targets, HealthEntityCombatObject attacker. /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override OnPlayResult OnPlay(params object[] parameters) { List <HealthEntityCombatObject> targets = parameters[0] as List <HealthEntityCombatObject>; HealthEntityCombatObject attacker = parameters[1] as HealthEntityCombatObject; OnPlayResult onPlayResult = new OnPlayResult(); foreach (var t in targets) { HealthEntityCombatObject.DamageInfo damageInfo = t.TakeDamage(Instantiate <AbilityStep_Damage>(this), attacker); onPlayResult.unshieldedDamage = damageInfo.damageDealt; } foreach (var t in targets) { GameObject particlePrefab = particleEffectPrefab; if (particleEffectPrefab == null) { particlePrefab = FindObjectOfType <CombatManager>().particlePrefab; } GameObject go = Instantiate(particlePrefab, t.transform); go.GetComponent <ParticlesEffect>().Init(0); } return(onPlayResult); }
public override void OnAttacked(params object[] parameters) { HealthEntityCombatObject attacker = parameters[0] as HealthEntityCombatObject; AbilityStep_Damage dam = new AbilityStep_Damage(); dam.amount = amount; dam.damageType = AbilityStep_Damage.DamageType.True; dam.damageTypePerc = AbilityStep_Damage.DamageTypePerc.Flat; attacker.TakeDamage(dam, null); }
public override void TickPerTurn(params object[] parameters) { HealthEntityCombatObject target = parameters[0] as HealthEntityCombatObject; switch (type) { case AbilityStep_Restore.Type.Mana: ((PlayerCombatObject)target).ModifyMana(amount); break; } }
public override void TickPerTurn(params object[] parameters) { HealthEntityCombatObject target = parameters[0] as HealthEntityCombatObject; AbilityStep_Damage dam = CreateInstance <AbilityStep_Damage>(); dam.amount = amount; dam.damageType = AbilityStep_Damage.DamageType.True; dam.damageTypePerc = AbilityStep_Damage.DamageTypePerc.Flat; target.TakeDamage(dam, null); }
public void SelectTarget(HealthEntityCombatObject entity) { // Break if there is no selected card. if (currentSelectedCard == null) { return; } //HideTargettingButtons(); chosenTargets.Add(entity); targetFound = true; }
public void AddTarget(HealthEntityCombatObject entity, System.Action HideTargetingButtonsCallback) { chosenTargets.Add(entity); if (!multipleSpecificMode) { targetFound = true; HideTargetingButtonsCallback(); } else { multipleSpecificModeList.Add(entity); if (multipleSpecificModeList.Count == numberOfSpecificTargets) { targetFound = true; HideTargetingButtonsCallback(); } } }
void OnEnemyDeath(HealthEntityCombatObject entity) { EnemyCombatObject enemy = entity as EnemyCombatObject; FindObjectOfType <AudioManager>().PlayRandomClip(enemy.deathSounds); enemies.Remove(enemy); int i = 0; foreach (var e in enemies) { e.enemyIndex = i; i++; } if (enemies.Count == 0) { FindObjectOfType <AudioManager>().PlayClip(VictorySound); combatOver = true; StartCoroutine(EndBattleCoroutine(false)); } }
/// <summary> /// Figure out if the entity is a valid target regarding some arguments. /// </summary> /// <param name="entity">Referenced entity</param> /// <param name="canTargetUntargetable">Bypass the untargetable restriction</param> /// <param name="canTargetDead">Bypass the dead restriction</param> /// <returns></returns> bool ValidTarget(HealthEntityCombatObject entity, bool canTargetUntargetable, bool canTargetDead) { // If dead if (entity.IsDead && canTargetDead) { return(true); } // If NOT dead else if (!entity.IsDead) { if (canTargetUntargetable) { return(true); } else if (entity.IsTargetable()) { return(true); } } return(false); }
List <List <HealthEntityCombatObject> > SelectAbilityTargetEnemy(EnemyCombatObject enemy) { List <List <HealthEntityCombatObject> > targetsPerAbilityStep = new List <List <HealthEntityCombatObject> >(); AbilityStepsWithTargetingData_Enemy[] abilityStepsWithTargetingData = enemy.NextAbility.abilityStepsWithTargetingData; // Let's cycle through all ability steps in order to determine targets. foreach (var abilityStepWithTargetingData in abilityStepsWithTargetingData) { List <HealthEntityCombatObject> selectedTargets = new List <HealthEntityCombatObject>(); TargetData targetData = GetValidTargets(enemy, abilityStepWithTargetingData.targetingData); if (targetData.previousStepTargets > -1) { foreach (var entity in targetsPerAbilityStep[targetData.previousStepTargets]) { selectedTargets.Add(entity); } } else if (targetData.targetDecided) { foreach (var e in targetData.entities) { selectedTargets.Add(e); } } else { switch (abilityStepWithTargetingData.targetingData.targets) { case TargetingData_Base.Target.One: // Choose a random target for now selectedTargets.Add(targetData.entities[Random.Range(0, targetData.entities.Count)]); break; case TargetingData_Base.Target.Multiple: // Choose a random target for now selectedTargets.Add(targetData.entities[Random.Range(0, targetData.entities.Count)]); break; case TargetingData_Base.Target.MultipleSpecific: // Choose a random target for now // If it happens that there are less available targets than our ability wants us to target, // add them all. if (abilityStepWithTargetingData.targetingData.numberOfTargets < targetData.entities.Count) { foreach (var entity in targetData.entities) { selectedTargets.Add(entity); } } else { List <HealthEntityCombatObject> st = new List <HealthEntityCombatObject>(selectedTargets); for (int i = 0; i < abilityStepWithTargetingData.targetingData.numberOfTargets; i++) { HealthEntityCombatObject entity = targetData.entities[Random.Range(0, targetData.entities.Count)]; selectedTargets.Add(entity); st.Remove(entity); } } break; } } targetsPerAbilityStep.Add(selectedTargets); } // We have all chosen targets. // We now have to check whether any of those are multiple hits. for (int i = 0; i < targetsPerAbilityStep.Count; i++) { TargetingData_Base targetingData = enemy.NextAbility.abilityStepsWithTargetingData[i].targetingData; if (targetingData.targetAlignment == TargetingData_Base.TargetAlignment.Friendly) { if (targetingData.targets == TargetingData_Base.Target.Multiple) { EnemyCombatObject chosenTarget = (EnemyCombatObject)targetsPerAbilityStep[i][0]; List <EnemyCombatObject> nearbyEnemies = GetNearbyEnemies(chosenTarget, targetingData.numberOfTargets); foreach (var e in nearbyEnemies) { targetsPerAbilityStep[i].Add(e); } } } } return(targetsPerAbilityStep); }
public override void OnUnafflicted(params object[] parameters) { HealthEntityCombatObject afflictee = parameters[0] as HealthEntityCombatObject; afflictee.Stats.UnmodifyStat(stat, amount); }
public void ButtonInput_SelectTarget(HealthEntityCombatObject entity) { battleManager.AddTarget(entity, HideAllTargettingButtons); }
IEnumerator SelectTargets_Power(NativePowerScriptableObject nativePower) { PlayerCombatObject playerOnTurn = currentCardOwner; HealthEntityCombatObject caster = playerOnTurn; stepNumber = 0; targetsPerAbilityStep = new List <List <HealthEntityCombatObject> >(); AbilityStepsWithTargetingData_Player[] abilities = nativePower.abilityStepsWithTargetingData; // Let's cycle through all ability steps in order to determine targets. foreach (var abilityStepWithTargetingData in abilities) { chosenTargets = new List <HealthEntityCombatObject>(); targetFound = false; TargetData targetData = GetValidTargets(caster, abilityStepWithTargetingData.targetingData); if (targetData.multipleSpecificMode) { multipleSpecificMode = true; numberOfSpecificTargets = targetData.multipleSpecificNumber; multipleSpecificModeList = new List <HealthEntityCombatObject>(); } else { multipleSpecificMode = false; } if (targetData.previousStepTargets > -1) { targetFound = true; foreach (var entity in targetsPerAbilityStep[targetData.previousStepTargets]) { chosenTargets.Add(entity); } } else if (targetData.targetDecided) { targetFound = true; foreach (var e in targetData.entities) { chosenTargets.Add(e); } } else { if (targetData.entities.Count == 1 && targetData.entities[0] is PlayerCombatObject) { targetFound = true; chosenTargets.Add(targetData.entities[0]); } else { infoText.text = abilityStepWithTargetingData.targetingData.textForChoosing; ShowTargetingButton(targetData.entities); } } while (targetFound == false) { yield return(null); } stepNumber++; targetsPerAbilityStep.Add(chosenTargets); } // We have all chosen targets. // We now have to check whether any of those are multiple hits. for (int i = 0; i < targetsPerAbilityStep.Count; i++) { TargetingData_Base targetingData = nativePower.abilityStepsWithTargetingData[i].targetingData; if (targetingData.targetAlignment == TargetingData_Base.TargetAlignment.Hostile) { if (targetingData.targets == TargetingData_Base.Target.Multiple) { EnemyCombatObject chosenTarget = (EnemyCombatObject)targetsPerAbilityStep[i][0]; List <EnemyCombatObject> nearbyEnemies = GetNearbyEnemies(chosenTarget, targetingData.numberOfTargets); foreach (var e in nearbyEnemies) { targetsPerAbilityStep[i].Add(e); } } } } // Now we have full lists of all targets for each attribute. // Let's do the card trick. DoPowerTrick(); yield return(null); }
public DamageInfo TakeDamage(AbilityStep_Damage stepInfo, HealthEntityCombatObject attacker) { var result = DamageCalculator.CaclulateFlatDamage(stepInfo, attacker, this); /* * if (IsDead) * { * return default(DamageInfo); * } * * if (IsImmuneToDamage()) * { * Animator.SetTrigger("Block"); * DamageNumberCanvas canv = GameObject.Instantiate(FindObjectOfType<CombatManager>().damageNumberCanvasPrefab).GetComponent<DamageNumberCanvas>(); * canv.Display("Immune", Color.magenta); * canv.transform.position = transform.position; * return default(DamageInfo); * } */ DamageInfo damageInfo = new DamageInfo(); /* * * int amount = stepInfo.amount; * amount = Mathf.Max(0, amount); * if (attacker != null) * { * amount = (int)(amount * attacker.Stats.rawDamageMultiplier.Value); * } * * float random = Random.Range(0f, 1f); * float attackerCritChance = attacker.Stats.criticalChance.Value; * * foreach (var statusEffect in StatusEffects) * { * foreach (var behaviour in statusEffect.behaviour) * { * if (behaviour is WeakenBehaviour weaken) * { * attackerCritChance *= weaken.modifyCritChanceAgainst; * } * } * } * * bool crit = false; * if (attacker != null && random < attackerCritChance && stepInfo.canCriticallyStrike) * { * crit = true; * amount *= 2; * } * * switch (stepInfo.damageTypePerc) * { * case AbilityStep_Damage.DamageTypePerc.PercentageMaxHP: * amount = (int)(MaxHealth * (amount / 100f)); * break; * case AbilityStep_Damage.DamageTypePerc.None: * amount = 0; * break; * } * * switch (stepInfo.damageType) * { * case AbilityStep_Damage.DamageType.Physical: * amount = (int)Mathf.Ceil(amount * (1 - Mathf.Clamp01(Stats.armor.Value - ((attacker != null) ? attacker.Stats.armorPenetration.Value : 0)))); * break; * case AbilityStep_Damage.DamageType.Magic: * amount = (int)Mathf.Ceil(amount * (1 - Mathf.Clamp01(Stats.magicResist.Value - ((attacker != null) ? attacker.Stats.magicPenetration.Value : 0)))); * break; * case AbilityStep_Damage.DamageType.None: * amount = 0; * break; * }*/ //int amountRemaining = amount; switch (result.name) { case DamageCalculator.ClashResult.Name.Failed: return(default); case DamageCalculator.ClashResult.Name.Immune: Animator.SetTrigger("Block"); DamageNumberCanvas canv = GameObject.Instantiate(FindObjectOfType <CombatManager>().damageNumberCanvasPrefab).GetComponent <DamageNumberCanvas>(); canv.Display("Immune", Color.magenta); canv.transform.position = transform.position; return(default); } ReduceBlock(ref result.damage); /* * amountRemaining -= Block; * ModifyBlock(-amount); * * amountRemaining = Mathf.Clamp(amountRemaining, 0, amountRemaining);*/ if (result.damage > 0) { damageInfo.damageDealt = result.damage; DamageNumberCanvas canv = GameObject.Instantiate(FindObjectOfType <CombatManager>().damageNumberCanvasPrefab).GetComponent <DamageNumberCanvas>(); if (result.criticalHit) { canv.Display("CRIT! " + damageInfo.damageDealt.ToString(), Color.red); } else { canv.Display(damageInfo.damageDealt.ToString(), Color.red); } canv.transform.position = transform.position; Entity.Health -= damageInfo.damageDealt; Entity.Health = Mathf.Clamp(Health, 0, MaxHealth); if (Entity.Health > 0) { Animator.SetTrigger("Hit"); } } else { Animator.SetTrigger("Block"); DamageNumberCanvas canv = GameObject.Instantiate(FindObjectOfType <CombatManager>().damageNumberCanvasPrefab).GetComponent <DamageNumberCanvas>(); canv.Display("Blocked", Color.grey); canv.transform.position = transform.position; } if (attacker != null) { if (OnAttackedBehaviour != null) { OnAttackedBehaviour(attacker); } } if (Health <= 0) { Die(); OnDeath(this); } RefreshUI(); return(damageInfo); }
TargetData GetValidTargets(HealthEntityCombatObject caster, TargetingData_Base targetingData) { TargetData targetData = new TargetData(); targetData.previousStepTargets = -1; List <HealthEntityCombatObject> targets = new List <HealthEntityCombatObject>(); if (targetingData.targetingType == TargetingData_Base.TargetingType.NoTargeting) { // There is no targeting. Don't bother. } // We will use other step's targets. else if (targetingData.targetingType == TargetingData_Base.TargetingType.PreviousStep) { targetData.previousStepTargets = targetingData.useTargetsFromStepNumber; } // If the target is only self, do not check for anything else. else if (targetingData.onlySelf) { targets.Add(caster); targetData.targetDecided = true; } else { // Can we add self? bool selfIncluded = targetingData.selfIncluded; // Let's skip the check if we can only target ourselves. if (targetingData.onlySelf) { targets.Add(caster); } // We can target more than ourselves. Let's first check if we can target at all. else if (targetingData.targets != TargetingData_Base.Target.All) { switch (targetingData.targetAlignment) { case TargetingData_Base.TargetAlignment.Both: switch (targetingData.targets) { case TargetingData_Base.Target.One: // Select one from friendlies and from enemies. foreach (var f in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Both, selfIncluded)) { targets.Add(f); } break; case TargetingData_Base.Target.MultipleSpecific: // Select multiple specific from friendlies or enemies. // Add ourselves to the list. if (targetingData.selfIncluded) { } break; } break; case TargetingData_Base.TargetAlignment.Friendly: switch (targetingData.targets) { case TargetingData_Base.Target.One: // Select one from friendlies taking into account whether to add self. foreach (var f in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Friendly, selfIncluded)) { targets.Add(f); } break; case TargetingData_Base.Target.MultipleSpecific: // Select multiple specific friendlies taking into account whether to add self. break; case TargetingData_Base.Target.Multiple: // Select multiple friendlies taking into account whether to add self. foreach (var f in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Friendly, selfIncluded)) { targets.Add(f); } break; } break; case TargetingData_Base.TargetAlignment.Hostile: switch (targetingData.targets) { case TargetingData_Base.Target.One: // Select one from enemies. foreach (var e in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Hostile)) { targets.Add(e); } break; case TargetingData_Base.Target.MultipleSpecific: // Select multiple specific from enemies. targetData.multipleSpecificMode = true; targetData.multipleSpecificNumber = targetingData.numberOfTargets; foreach (var e in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Hostile)) { targets.Add(e); } break; case TargetingData_Base.Target.Multiple: // Select multiple from enemies. foreach (var e in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Hostile)) { targets.Add(e); } break; } break; } } // We cannot target so we choose all. else { switch (targetingData.targetAlignment) { case TargetingData_Base.TargetAlignment.Both: // Select all targets. foreach (var a in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Both, selfIncluded)) { targets.Add(a); } break; case TargetingData_Base.TargetAlignment.Friendly: // Select all allies taking into account if self included foreach (var a in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Friendly, selfIncluded, false, targetingData.canTargetDead)) { targets.Add(a); } break; case TargetingData_Base.TargetAlignment.Hostile: // Select all enemies. foreach (var e in GetEntitiesWithRelationTo(caster, TargetingData_Base.TargetAlignment.Hostile)) { targets.Add(e); } break; } targetData.targetDecided = true; } } targetData.entities = targets; return(targetData); }
void Update() { // Calculate zoom. cameraController.targetZoom = Input.mouseScrollDelta.y; foreach (var enemy in battleManager.enemies) { enemy.ClickableTile.Refresh(); } foreach (var player in battleManager.players) { player.ClickableTile.Refresh(); } // Mouse cursor is over UI AND is not in any state. if (eventSystem.IsPointerOverGameObject() && mouseState == MouseState.Free) { // Let's get all the info on what is under the mouse. PointerEventData pointer = new PointerEventData(eventSystem); pointer.position = Input.mousePosition; List <RaycastResult> raycastResults = new List <RaycastResult>(); // All results are stored in the raycastResults list. // Let's see if we need any of those. eventSystem.RaycastAll(pointer, raycastResults); // We need to see if we are over player hand. List <PlayerHand> playerHand = LookForPlayerHand(raycastResults); // If there is only one player hand under the cursor, // we can go ahead and tell the hand to update itself. if (playerHand.Count == 1) { currentHand = playerHand[0]; if (currentHand != null) { List <CardInHand> cardsUnderMouse = currentHand.GetAllCards(raycastResults); CardInHand selectedCard; currentHand.UpdateXD(cardsUnderMouse, out selectedCard); if (selectedCard != null) { DisplayCard(true, selectedCard); } } } // There are more hands under cursor OR there aren't any. else { UnhoverOverCard(); } // If the mouse is over GUI, break out. foreach (var rr in raycastResults) { if (rr.gameObject.transform.root == GUI) { return; } } } // Cursor is not in the UI OR is in another state. else if (!eventSystem.IsPointerOverGameObject() && mouseState == MouseState.Free) { UnhoverOverCard(); Ray ray = cameraController.camera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; int layerMask = 1 << (int)Layer.Clickable; foreach (var enemy in battleManager.enemies) { enemy.clickableTileClickable = true; /* * if (battleManager.multipleSpecificMode) * { * foreach (var entity in battleManager.multipleSpecificModeList) * { * ((EnemyCombatObject)entity).clickableTileClickable = false; * entity.ClickableTile.Selected = true; * ((EnemyCombatObject)entity).ClickableTile.GetComponent<Renderer>().material.color = Color.cyan; * } * } */ } if (Physics.Raycast(ray, out hit, 100f, layerMask, QueryTriggerInteraction.Collide)) { HealthEntityCombatObject entityHit = hit.transform.gameObject.GetComponentInParent <HealthEntityCombatObject>(); if (entityHit != null) { if (entityHit is PlayerCombatObject) { entityHit.ClickableTile.MouseOver(true); } if (entityHit is EnemyCombatObject) { if (battleManager.currentSelectedCard.card.abilityStepsWithTargetingData[battleManager.stepNumber].targetingData.targets == TargetingData_Base.Target.Multiple) { foreach (var enemy in battleManager.GetNearbyEnemies(((EnemyCombatObject)entityHit), battleManager.currentSelectedCard.card.abilityStepsWithTargetingData[battleManager.stepNumber].targetingData.numberOfTargets)) { enemy.ClickableTile.MouseOver(true); } } else if (battleManager.multipleSpecificMode) { foreach (var entity in battleManager.multipleSpecificModeList) { ((EnemyCombatObject)entity).ClickableTile.GetComponent <Renderer>().material.color = Color.cyan; } } entityHit.ClickableTile.MouseOver(true); } if (Input.GetMouseButtonDown(0)) { if (entityHit is EnemyCombatObject) { if (((EnemyCombatObject)entityHit).clickableTileClickable) { ButtonInput_SelectTarget(entityHit); } } else { ButtonInput_SelectTarget(entityHit); } } } } } HandleCameraTransform(); }
public static ClashResult CaclulateFlatDamage(AbilityStep_Damage step, HealthEntityCombatObject attacker, HealthEntityCombatObject defender) { ClashResult result = new ClashResult(); // If defender is dead, result fails. if (step == null || defender == null || defender.IsDead) { result.name = ClashResult.Name.Failed; return(result); } // If defender is immune to damage, result immune. if (defender.IsImmuneToDamage()) { result.name = ClashResult.Name.Immune; return(result); } // Grab the damage amount. result.damage = step.amount; if (attacker != null) { // Multiply with raw damage of the attacker. result.damage = (int)(result.damage * attacker.Stats.rawDamageMultiplier.Value); // Check for vulnerable if (defender.IsVulnerable()) { result.damage = (int)(result.damage * 1.5f); } // Crit calculator. if (step.canCriticallyStrike) { float attackerCritChance = attacker.Stats.criticalChance.Value; // Get negative crit multiplier on target. foreach (var behaviour in defender.GetCritMultiplierBehaviours()) { attackerCritChance *= behaviour.modifyCritChanceAgainst; } // Roll the crit and double the damage. float critValue = Random.Range(0f, 1f); // Critical is success. if (critValue < attackerCritChance) { result.damage *= 2; result.criticalHit = true; } } // Calculate damage against armor or magic resist. switch (step.damageType) { case AbilityStep_Damage.DamageType.None: result.damage = 0; break; case AbilityStep_Damage.DamageType.Physical: // defender armor - attacker armor pen => clamped between 0-1. float defenderPenetratedArmor = Mathf.Clamp01(defender.Stats.armor.Value - attacker.Stats.armorPenetration.Value); result.damage = (int)(result.damage * (1 - defenderPenetratedArmor)); break; case AbilityStep_Damage.DamageType.Magic: // defender MR - attacker mr pen => clamped between 0-1. float defenderPenetratedMR = Mathf.Clamp01(defender.Stats.magicResist.Value - attacker.Stats.magicPenetration.Value); result.damage = (int)(result.damage * (1 - defenderPenetratedMR)); break; } } // Clamp it to 0. result.damage = Mathf.Max(0, result.damage); // If the clamped damage is 0, result immune. if (result.damage < 1) { result.name = ClashResult.Name.Immune; return(result); } result.name = ClashResult.Name.Damage; return(result); }