/// <summary> /// Attempts to afflict the entity with a StatusEffect based on its properties and status percentage for the StatusEffect. /// </summary> /// <param name="inflictionChance">The chance of inflicting the StatusEffect.</param> /// <param name="status">The StatusEffect to afflict the entity with.</param> /// <returns>true if the StatusEffect was successfully afflicted, false otherwise.</returns> public bool TryAfflictStatus(double inflictionChance, StatusEffect status) { //Test for StatusEffect immunity - if the entity is immune to a particular alignment, don't allow the StatusEffect to be inflicted bool positiveStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.PositiveStatusImmune); bool negativeStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.NegativeStatusImmune); bool neutralStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.NeutralStatusImmune); if ((status.Alignment == StatusEffect.StatusAlignments.Positive && positiveStatusImmune == true) || (status.Alignment == StatusEffect.StatusAlignments.Negative && negativeStatusImmune == true) || (status.Alignment == StatusEffect.StatusAlignments.Neutral && neutralStatusImmune == true)) { return(false); } StatusPropertyHolder statusProperty = GetStatusProperty(status.StatusType); //If the entity is immune to this particular StatusEffect, don't allow it to be inflicted if (statusProperty.Immune == true) { Debug.Log($"{Entity.Name} is immune to {status.StatusType}!"); return(false); } //Test the percentage double percentage = statusProperty.StatusPercentage; return(UtilityGlobals.TestRandomCondition(inflictionChance, percentage)); }
private void HealFP(InteractionHolder damageInfo) { //The entity doesn't recover FP if dead (TEST THIS) or if the damage dealt was 0 or less if (EntityEquipped.IsDead == false && damageInfo.TotalDamage > 0) { //Test for recovering FP if (UtilityGlobals.TestRandomCondition(FPRecoverChance) == true) { //Recover FP EntityEquipped.HealFP(FPRecoverAmount); } } }
/// <summary> /// Determines if the BattleEntity gets affected by the Confused status, if it has it. /// If the BattleEntity is affected, it may perform a different action or target different entities with its original one. /// </summary> /// <param name="action">The BattleAction originally used.</param> /// <param name="targets">The original set of BattleEntities to target</param> /// <returns>An ActionHolder with a new BattleAction to perform or a different target list if the entity was affected by Confused. /// If not affected, the originals of each will be returned.</returns> private BattleGlobals.ActionHolder HandleConfusion(MoveAction action, params BattleEntity[] targets) { MoveAction actualAction = action; BattleEntity[] actualTargets = targets; //Check for Confusion's effects and change actions or targets depending on what happens int percent = EntityProperties.GetAdditionalProperty <int>(AdditionalProperty.ConfusionPercent); //See if Confusion should take effect if (UtilityGlobals.TestRandomCondition(percent) == true) { Debug.Log($"{Name} is affected by Confusion and will do something unpredictable!"); //int changeAction = 0; //Check if the action can target entities to see if we should change targets //if (actualAction.MoveProperties.TargetsEntity == true) //{ // //Get the opposite type of entities to target // //Items targets enemies, but attacks target allies // EntityTypes oppositeType = actualAction.MoveProperties.EntityType; // if (oppositeType == EntityTypes.Player) oppositeType = EntityTypes.Enemy; // else if (oppositeType == EntityTypes.Enemy) oppositeType = EntityTypes.Player; //} int changeTargets = 0; //Don't give a chance to change targets if the action doesn't have targets //NOTE: This means we'll need to handle changing actions first, as not all actions target something if (targets != null && targets.Length > 0) { changeTargets = GeneralGlobals.Randomizer.Next(0, 2); } //NOTE: Find a way to make it so we can control what happens based on the type of action. //For example, if Tattle was used, it doesn't target anyone else. //If you use a Healing item, it uses it on the opposing side, whereas if you use an attack it uses it on an ally. //Change to an ally /*Steps: * 1. If the action hits the first entity, find the adjacent allies. If not, find all allies * 2. Filter by heights based on what the action can hit * 3. Filter out dead allies * 4. If the action hits everyone, go with the remaining list. Otherwise, choose a random ally to attack * 5. If there are no allies to attack after all the filtering, make the entity do nothing*/ if (changeTargets == 1) { List <BattleEntity> allies = new List <BattleEntity>(); //If this action targets only the first player/enemy, look for adjacent allies if (actualAction.MoveProperties.SelectionType == TargetSelectionMenu.EntitySelectionType.First) { Debug.Log($"{Name} is looking for valid adjacent allies to attack!"); //Find adjacent allies and filter out all non-ally entities BattleManager.Instance.GetAdjacentEntities(allies, this); allies.RemoveAll((adjacent) => adjacent.EntityType != EntityType); } else { //Find all allies BattleManager.Instance.GetEntityAllies(allies, this); } //Filter by heights BattleManager.Instance.FilterEntitiesByHeights(allies, actualAction.MoveProperties.HeightsAffected); //Filter dead entities BattleManager.Instance.FilterDeadEntities(allies); //Choose a random ally to attack if the action only targets one entity if (allies.Count > 0 && actualAction.MoveProperties.SelectionType != TargetSelectionMenu.EntitySelectionType.All) { int randTarget = GeneralGlobals.Randomizer.Next(0, allies.Count); BattleEntity target = allies[randTarget]; allies.Clear(); allies.Add(target); Debug.Log($"{Name} is choosing to attack ally {allies[0].Name} in Confusion!"); } //If you can't attack any allies, do nothing if (allies.Count == 0) { actualAction = new NoAction(); Debug.Log($"{Name} did nothing as there either are no allies to attack or they're not in range!"); } else { //Set the actual targets to be the set of allies actualTargets = allies.ToArray(); //Disable action commands when attacking allies from Confusion, if the action has an Action Command if (actualAction.HasActionCommand == true) { actualAction.EnableActionCommand = false; } } } } return(new BattleGlobals.ActionHolder(actualAction, actualTargets)); }
/// <summary> /// Checks if the entity's attempt to hit another entity is successful based on the entity's Accuracy and the victim's Evasion. /// </summary> /// <param name="victim">The entity trying to evade.</param> /// <returns>true if the entity hits and the victim doesn't evade, otherwise false.</returns> //NOTE: When dealing with Badges such as Close Call, we should compare the entity's Evasion first, then perform //the test again with the Badges' Evasion added in. If the Badges' Evasion bonus allows the entity to evade the attack, //that's when we'd play the "LUCKY" animation public bool AttemptHitEntity(BattleEntity victim) { return(UtilityGlobals.TestRandomCondition(BattleStats.GetTotalAccuracy(), victim.BattleStats.GetTotalEvasion())); }