/// <summary> /// This method reflects changes for both the Showboat track and the MoveTricks track. /// </summary> /// <param name="attacker">The attacker defeated</param> public override void WinFight(AttackerSandbox attacker) { DefeatedSoFar++; if (Services.Rulebook.GetType() != typeof(Tutorial.TutorialTurnManager)) { powerupReadyParticle.SetActive(CheckUpgradeStatus()); //don't play particle in tutorial; it's distracting } Services.UI.ReviseNextLabel(defeatsToNextUpgrade, DefeatedSoFar); //when the Ranger fights, they use up an attack. If they defeat the attacker, they get an extra attack for next turn. if (currentShowboat > ShowboatTrack.None) { currentAttacks--; extraAttacks++; Services.UI.OpponentStatement(ReviseAttackText()); DisplayAvailableAttacks(); } FinishWithCard(); if (currentAttacks <= 0 && currentShowboat > ShowboatTrack.None) { DoneFighting(); } if (currentMoveTricks == MoveTricksTrack.The_Last_Chance && !Services.Tasks.CheckForTaskOfType <TeleportDefenderTask>()) { Services.Tasks.AddTask(new TeleportDefenderTask(this, TeleportDefenderTask.PossibleDestinations.Adjacent)); } }
private void ChooseTankardKick(Event e) { Debug.Assert(e.GetType() == typeof(InputEvent), "Non-InputEvent in ChooseTankardKick."); InputEvent inputEvent = e as InputEvent; if (inputEvent.selected.tag == BOARD_TAG) { SpaceBehavior space = inputEvent.selected.GetComponent <SpaceBehavior>(); if (CheckAllAdjacent(GridLoc, space.GridLocation)) { KickTankard(space); } } else if (inputEvent.selected.tag == ATTACKER_TAG || inputEvent.selected.tag == LEADER_TAG || inputEvent.selected.tag == MINION_TAG) { AttackerSandbox attacker = inputEvent.selected.GetComponent <AttackerSandbox>(); SpaceBehavior space = Services.Board.GetSpace(attacker.XPos, attacker.ZPos); if (CheckAllAdjacent(GridLoc, space.GridLocation)) { KickTankard(space); } } }
/// <summary> /// The Ranger has special combat benefits if moving up the showboat track. /// </summary> /// <param name="attacker">The attacker this defender is fighting.</param> public override void TryFight(AttackerSandbox attacker) { if (currentShowboat == ShowboatTrack.None) //don't do anything special if the Ranger isn't showboating { base.TryFight(attacker); return; } if (!CheckInRange(attacker)) { return; //don't fight if the attacker is out of range } //if the Ranger gets this far, a fight will actually occur; get a combat card for the attacker int attackerValue = Services.AttackDeck.GetAttackerCard().Value; int damage = (ChosenCard.Value + AttackMod) - (attackerValue + DetermineAttackerModifier(attacker) + DetermineAttackerArmor(attacker)); damage = damage < 0 ? 0 : damage; //don't let damage be negative, "healing" the attacker Services.Tasks.AddTask(new CombatExplanationTask(attacker, this, attackerValue, ChosenCard.Value, DetermineAttackerModifier(attacker), AttackMod, damage)); Services.UI.ReviseCardsAvail(GetAvailableValues()); }
/// <summary> /// Carries out everything that happens when a defender loses a fight (card + modifer < attacker's card + modifier). /// </summary> /// <param name="attacker">The attacker in the fight; generic defenders don't need this, but the Brawler does.</param> public virtual void LoseFight(AttackerSandbox attacker) { attacker.FailToDamage(); Services.Events.Fire(new MissedFightEvent()); FinishWithCard(); DoneFighting(); }
/// <summary> /// Carries out everything that happens when a defender wins a fight (card + modifer > attacker's card + modifier). /// </summary> /// <param name="attacker">The attacker who lost the fight; generic defenders don't need this, but the Brawler does.</param> public virtual void WinFight(AttackerSandbox attacker) { FinishWithCard(); DefeatAttacker(); Services.UI.ReviseNextLabel(defeatsToNextUpgrade, DefeatedSoFar); DoneFighting(); }
//the attacker's attack modifier can be altered, or nullified, depending on the Ranger's showboating status and their relative position private int DetermineAttackerModifier(AttackerSandbox attacker) { if (attacker.ZPos >= GridLoc.z) { return(attacker.AttackMod); //the Ranger has to be behind the attacker (greater Z position) to get a benefit } int temp = 0; switch (currentShowboat) { case ShowboatTrack.Effortless: temp = attacker.AttackMod - 1; break; case ShowboatTrack.Pull_Ahead: case ShowboatTrack.Set_the_Standard: temp = 0; break; default: temp = attacker.AttackMod; break; } return(temp); }
/// <summary> /// Is an attacker directly north of this defender? /// </summary> /// <returns><c>true</c> if the attacker is one space north, <c>false</c> otherwise.</returns> /// <param name="attacker">The attacker being checked.</param> protected bool CheckIsNorth(AttackerSandbox attacker) { if (attacker.XPos == GridLoc.x && attacker.ZPos == GridLoc.z + 1) { return(true); } return(false); }
public override void TryFight(AttackerSandbox attacker) { Directions dir = GetAttackerDir(attacker); if (dir == Directions.Error) { return; //if the player clicked on an enemy they can't possibly fight, do nothing } if (currentRampage == RampageTrack.None) { base.TryFight(attacker); return; } if (!UseUpAttacks(dir)) { return; } if (currentRampage == RampageTrack.The_Last_One_Standing && //dir != Directions.North && //this is removed so that the Brawler is not limited to a single attack ahead !defeatedLastTarget) { return; //the Brawler stops in The LastOneStanding mode after missing a hit } //if the Brawler gets this far, a fight will actually occur; get a card for the Attacker int attackerValue = Services.AttackDeck.GetAttackerCard().Value; int damage = (ChosenCard.Value + AttackMod) - (attackerValue + attacker.AttackMod + attacker.Armor); damage = damage < 0 ? 0 : damage; //don't allow damage to be negative, "healing" the attacker Services.Tasks.AddTask(new CombatExplanationTask(attacker, this, attackerValue, ChosenCard.Value, attacker.AttackMod, AttackMod, damage)); if ((ChosenCard.Value + AttackMod) > (attackerValue + attacker.AttackMod)) //successful attack { if (damage >= attacker.Health) { } //inflicting damage is handled by the combat explanation task, if appropriate } else //the Brawler's value was too low { } if (currentRampage != RampageTrack.None) { SetAvailableFeedback(); } Services.UI.ReviseCardsAvail(GetAvailableValues()); }
/// <summary> /// Rangers who are moving up the Showboat track can attack in any direction, including diagonals. /// </summary> /// <returns><c>true</c> if the attacker is orthogonally or diagonally adjacent, <c>false</c> otherwise.</returns> /// <param name="attacker">The attacker being fought.</param> private bool CheckInRange(AttackerSandbox attacker) { if (Mathf.Abs(GridLoc.x - attacker.XPos) <= 1 && Mathf.Abs(GridLoc.z - attacker.ZPos) <= 1) { return(true); } return(false); }
/// <summary> /// The Guardian's combat math changes when mastering single combat. /// </summary> /// <returns>A string explaining the math behind each combat.</returns> /// <param name="attacker">The attacker this defender is fighting.</param> /// <param name="attackerValue">The value of the attacker's card.</param> protected override string DisplayCombatMath(AttackerSandbox attacker, int attackerValue) { int damage = (ChosenCard.Value + DetermineAttackMod(attacker)) - (attackerValue + attacker.AttackMod + attacker.Armor); damage = damage < 0 ? 0 : damage; return(DEFENDER_VALUE + ChosenCard.Value + PLUS + DetermineAttackMod(attacker) + NEWLINE + ATTACKER_VALUE + attackerValue + PLUS + attacker.AttackMod + NEWLINE + HITS + ((ChosenCard.Value + DetermineAttackMod(attacker)) - (attackerValue + attacker.AttackMod)).ToString() + NEWLINE + DAMAGE + damage.ToString());; }
public override void TieFight(AttackerSandbox attacker) { Directions dir = GetAttackerDir(attacker); if (dir == Directions.East || dir == Directions.West) { defeatedLastTarget = false; //only important for The Last One Standing } Services.Events.Fire(new MissedFightEvent()); FinishWithCard(); }
/// <summary> /// Determines this Guardian's attack mofidier, taking Single Combat track bonuses into account. /// </summary> /// <returns>The attack mod.</returns> /// <param name="attacker">The attacker the Guardian is fighting.</param> private int DetermineAttackMod(AttackerSandbox attacker) { if (currentSingleCombat == SingleCombatTrack.None || currentSingleCombat == SingleCombatTrack.Single_Combat || attacker.tag != LEADER_TAG) { return(AttackMod); } else { return(AttackMod + SINGLE_COMBAT_ATTACK_BONUS); } }
/// <summary> /// Inflicts damage on any attacker found at a given grid location, regardless of its armor, etc. /// </summary> /// <param name="x">The grid x coordinate.</param> /// <param name="z">The grid z coordinate.</param> private void DamageAtLoc(int x, int z) { if (Services.Board.CheckValidSpace(x, z)) { if (Services.Board.GeneralSpaceQuery(x, z) == SpaceBehavior.ContentType.Attacker) { AttackerSandbox attacker = Services.Board.GetThingInSpace(x, z).GetComponent <AttackerSandbox>(); if (attacker.Health <= LANDSLIDE_DAMAGE) { DefeatedSoFar++; } attacker.TakeDamage(LANDSLIDE_DAMAGE); } } }
private void ChooseAttacker(global::Event e) { Debug.Assert(e.GetType() == typeof(InputEvent), "Non-InputEvent in ChooseAttacker"); InputEvent inputEvent = e as InputEvent; if (inputEvent.selected.tag == attackerType.ToString()) { AttackerSandbox attacker = inputEvent.selected.GetComponent <AttackerSandbox>(); attacker.TakeDamage(attacker.Health); defender.DefeatAttacker(); SetStatus(TaskStatus.Success); } }
/// <summary> /// If the Ranger is behind the attacker and at maximum showboating, the Ranger nullifies their armor. /// </summary> /// <returns>The attacker's armor value.</returns> /// <param name="attacker">The attacker the Ranger is fighting.</param> private int DetermineAttackerArmor(AttackerSandbox attacker) { if (attacker.ZPos >= GridLoc.z) { return(attacker.Armor); } else if (currentShowboat == ShowboatTrack.Set_the_Standard) { return(0); } else { return(attacker.Armor); } }
/// <summary> /// At certain points on the Single Combat track, the Guardian upgrades especially quickly /// </summary> /// <returns>The defeated so far.</returns> private int DetermineDefeatedSoFar(AttackerSandbox attacker) { int temp = DefeatedSoFar; if ((currentSingleCombat == SingleCombatTrack.Single_Combat || currentSingleCombat == SingleCombatTrack.Youre_Mine || currentSingleCombat == SingleCombatTrack.Run_Fools) && attacker.tag == LEADER_TAG) { temp = defeatsToNextUpgrade; } else { temp++; } return(temp); }
/// <summary> /// Try to damage any attackers in the relevant space, and then be done. /// </summary> public override void Tick() { if (Services.Board.GeneralSpaceQuery(loc.x, loc.z) == SpaceBehavior.ContentType.Attacker) { AttackerSandbox attacker = Services.Board.GetThingInSpace(loc.x, loc.z).GetComponent <AttackerSandbox>(); //credit the defender who's doing the damage with defeating the attacker, if appropriate if (attacker.Health <= damage) { defender.DefeatAttacker(); } attacker.TakeDamage(damage); } SetStatus(TaskStatus.Success); }
public override void TieFight(AttackerSandbox attacker) { Services.Events.Fire(new MissedFightEvent()); if (currentShowboat > ShowboatTrack.None) { currentAttacks--; Services.UI.OpponentStatement(ReviseAttackText()); DisplayAvailableAttacks(); } FinishWithCard(); if (currentAttacks <= 0 && currentShowboat > ShowboatTrack.None) { DoneFighting(); } }
public override void WinFight(AttackerSandbox attacker) { DefeatedSoFar = DetermineDefeatedSoFar(attacker); Services.UI.ReviseNextLabel(defeatsToNextUpgrade, DefeatedSoFar); if (currentSingleCombat >= SingleCombatTrack.Run_Fools) { Services.Events.Fire(new ReduceMomentumEvent()); } if (currentSingleCombat == SingleCombatTrack.Champion) { DefeatRetinue(attacker); } if (Services.Rulebook.GetType() != typeof(Tutorial.TutorialTurnManager)) { powerupReadyParticle.SetActive(CheckUpgradeStatus()); //don't play particle in tutorial; it's distracting } FinishWithCard(); DoneFighting(); }
/// <summary> /// Finds the direction of an attacker, relative to this defender. /// </summary> /// <returns>The attacker's direction.</returns> /// <param name="attacker">The attacker whose location is being checked.</param> private Directions GetAttackerDir(AttackerSandbox attacker) { if (attacker.XPos == GridLoc.x && attacker.ZPos == GridLoc.z + 1) { return(Directions.North); } else if (attacker.XPos + 1 == GridLoc.x && attacker.ZPos == GridLoc.z) { return(Directions.West); } else if (attacker.XPos - 1 == GridLoc.x && attacker.ZPos == GridLoc.z) { return(Directions.East); } else { return(Directions.Error); } }
/// <summary> /// The Guardian is especially effective against Warlords when on the Single Combat track. /// </summary> /// <param name="attacker">The attacker this defender is fighting.</param> public override void TryFight(AttackerSandbox attacker) { if (!CheckIsNorth(attacker)) { return; //don't fight if the attacker isn't directly to the north } //if the Defender gets this far, a fight will actually occur; get a combat card for the attacker int attackerValue = Services.AttackDeck.GetAttackerCard().Value; int damage = (ChosenCard.Value + DetermineAttackMod(attacker)) - (attackerValue + attacker.AttackMod + attacker.Armor); damage = damage < 0 ? 0 : damage; //don't let damage be negative, "healing" the attacker Services.Tasks.AddTask(new CombatExplanationTask(attacker, this, attackerValue, ChosenCard.Value, attacker.AttackMod, DetermineAttackMod(attacker), damage)); Services.UI.ReviseCardsAvail(GetAvailableValues()); }
///////////////////////////////////////////// /// Functions ///////////////////////////////////////////// //constructor public CombatExplanationTask(AttackerSandbox attacker, DefenderSandbox defender, int attackerValue, int defenderValue, int attackerMod, int defenderMod, int damage) { attackerScript = attacker; defenderScript = defender; int index = 0; index = attacker.gameObject.name.IndexOf(AttackerManager.DIVIDER); attackerName = attacker.gameObject.name.Substring(0, index); defenderName = defender.gameObject.name; this.attackerValue = attackerValue; this.defenderValue = defenderValue; this.attackerMod = attackerMod; this.defenderMod = defenderMod; this.damage = damage; }
public override void WinFight(AttackerSandbox attacker) { DefeatAttacker(); Services.UI.ReviseNextLabel(defeatsToNextUpgrade, DefeatedSoFar); if (currentRampage == RampageTrack.Wade_In || currentRampage == RampageTrack.Berserk || currentRampage == RampageTrack.The_Last_One_Standing) { if (lastDefeatedLoc != null) { Services.Board.HighlightSpace(lastDefeatedLoc.x, lastDefeatedLoc.z, BoardBehavior.OnOrOff.Off); } lastDefeatedLoc = new TwoDLoc(attacker.XPos, attacker.ZPos); if (Services.Board.GeneralSpaceQuery(attacker.XPos, attacker.ZPos) != SpaceBehavior.ContentType.Attacker) { Services.Board.HighlightSpace(attacker.XPos, attacker.ZPos, BoardBehavior.OnOrOff.On); } } defeatedLastTarget = true; //only important for The Last One Standing FinishWithCard(); }
/// <summary> /// Damages an attacker if it is directly north and the player has chosen a stronger card than its value. /// </summary> /// <param name="attacker">The attacker this defender is fighting.</param> public virtual void TryFight(AttackerSandbox attacker) { if (!CheckIsNorth(attacker)) { return; //don't fight if the attacker isn't directly to the north } //if the Defender gets this far, a fight will actually occur; get a combat card for the attacker int attackerValue = Services.AttackDeck.GetAttackerCard().Value; int damage = (ChosenCard.Value + AttackMod) - (attackerValue + attacker.AttackMod + attacker.Armor); damage = damage < 0 ? 0 : damage; //don't allow damage to be negative, "healing" the attacker Services.Tasks.AddTask(new CombatExplanationTask(attacker, this, attackerValue, ChosenCard.Value, attacker.AttackMod, AttackMod, damage)); //CombatExplanationTask handles all combat effects when the player dismisses the combat explanation Services.UI.ReviseCardsAvail(GetAvailableValues()); }
/// <summary> /// When at the end of the Single Combat track, the Guardian defeats a leader's retinue after defeating the leader. /// </summary> /// <param name="attacker">The attacker the Guardian is fighting.</param> private void DefeatRetinue(AttackerSandbox attacker) { if (attacker.tag != LEADER_TAG) { return; } if (TryDefeatRetinueMember(attacker.XPos, attacker.ZPos + 1)) { DefeatedSoFar++; } if (TryDefeatRetinueMember(attacker.XPos, attacker.ZPos - 1)) { DefeatedSoFar++; } if (TryDefeatRetinueMember(attacker.XPos - 1, attacker.ZPos)) { DefeatedSoFar++; } if (TryDefeatRetinueMember(attacker.XPos + 1, attacker.ZPos)) { DefeatedSoFar++; } }
public override void LoseFight(AttackerSandbox attacker) { TieFight(attacker); }
public override void TieFight(AttackerSandbox attacker) { Services.Events.Fire(new MissedFightEvent()); FinishWithCard(); DoneFighting(); }
public void EliminateAttacker(AttackerSandbox attacker) { attacker.UnregisterForEvents(); attackers.Remove(attacker); }
///////////////////////////////////////////// /// Functions ///////////////////////////////////////////// //constructor public AttackerDefeatedEvent(AttackerSandbox attacker) { this.attacker = attacker; location = new TwoDLoc(this.attacker.XPos, this.attacker.ZPos); }
/// <summary> /// Currently intentionally blank. This is expected to be necessary for features down the road. /// </summary> /// <param name="attacker">The attacker being taken out of the game.</param> public void EliminateAttacker(AttackerSandbox attacker) { }