/// <summary> /// add to hand if hand isn't too bigyet. /// </summary> private void TryAddToHand(CardInstance ci, EffectSet ef) { if (Hand.Count < 10) { Hand.Add(ci); DrawCard?.Invoke(ci, ef); } else { DiscardPile.Add(ci); } }
private void AttackResponse(EffectSet ef) { var si = Entity.StatusInstances.Single(el => el.Status.Name == nameof(FlameBarrierStatus)); //triggers when player with this status is targeted. //we grab the progression from the damage pattern I'd receive, with default values of zero. //and this must be an enemy action. var th = Repeat(si.Intensity, ef.PlayerEffect.AttackCount); ef.EnemyEffect.SetInitialDamage(th.ToArray()); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var dmg = upgradeCount == 0 ? new List <int>() { 2, 2, 2, 2 } : new List <int>() { 2, 2, 2, 2, 2 }; ef.EnemyEffect.SetInitialDamage(dmg.ToArray()); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var dmg = upgradeCount == 0 ? 21 : 28; ef.EnemyEffect.SetInitialDamage(dmg); ef.DeckEffect.Add((Deck d, List <string> h) => { var burn = new CardInstance(new Burn(), 0); d.AddToDiscardPile(burn); h.Add("Added burn to discard pile"); }); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var dmg = upgradeCount == 0 ? 6 : 8; ef.EnemyEffect.SetInitialDamage(dmg); ef.DeckEffect.Add((Deck d, List <string> h) => { var copy = new CardInstance(this, upgradeCount); d.AddToDiscardPile(copy); h.Add("Duplicated Anger into discard pile"); }); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var dmg = upgradeCount == 0 ? 7 : 10; ef.DeckEffect.Add((Deck d, List <string> h) => { var dazed = new CardInstance(new Dazed(), 0); var position = d.AddToRandomSpotInDrawPile(dazed, key); h.Add($"Reckless charge added dazed to draw position {position}"); }); ef.EnemyEffect.SetInitialDamage(dmg); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var oe = new OneEffect { Action = (Fight f, Deck d, List <string> history) => { f._Player.Energy += 2; history.Add("Gained 2 energy mana from SeeingRed"); } }; ef.FightEffect.Add(oe); }
public void Reshuffle(EffectSet ef, List <string> history) { DeckShuffle?.Invoke(ef, history); foreach (var d in DiscardPile) { DrawPile.Add(d); } DiscardPile = new List <CardInstance>(); ShuffleDrawPile(); ef.HadRandomness = true; ef.Key = GenerateCardSetKey(DrawPile); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var cardAmt = upgradeCount == 0 ? 1 : 2; var dmg = upgradeCount == 0 ? 9 : 10; ef.EnemyEffect.SetInitialDamage(dmg); ef.DeckEffect.Add((Deck d, List <string> history) => { var drawn = d.DrawToHand(targets, cardAmt, true, player, ef, history); history.Add($"PommelstrikeDrew {string.Join(',', drawn)}"); }); }
public override void EndFight(Deck d, EffectSet relicEf) { var oe = new OneEffect(); //TODO why is this weird. oneEffect can actually cause multiple histories. So probably refactor the return value. oe.Action = (Fight f, Deck d, List <string> history) => { f._Player.HealFor(6, out string healres); history.Add($"Burning Blood Heal {healres}"); }; relicEf.FightEffect.Add(oe); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { int amount; if (upgradeCount == 0) { amount = 5; } else { amount = 8; } ef.PlayerEffect.AddBlockStep("Sentinel", amount); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var exi = player.StatusInstances.SingleOrDefault(el => el.Status.StatusType == StatusType.Strength); if (exi == null) { } else { //we could just double this in place but cleaner to reapply the same status var statusCopy = new StatusInstance(exi.Status, exi.Intensity); ef.PlayerEffect.Status.Add(statusCopy); } }
private void FeelNoPainStatusResponseToExhaustion(EffectSet ef) { //for some reason we look up the player's SI again even though we var si = Entity.StatusInstances.SingleOrDefault(el => el.Status.StatusType == StatusType.FeelNoPainStatus); if (si == null) { //we bind the event once on creation, then unbind when it decays to zero. //we get the SI so we know the intensity. return; } //can we just set player block? No never. Because there are things like "do damage when gain block". ef.PlayerEffect.AddBlockStep("FNP Blocks", si.Intensity); }
public void EndTurn() { if (!PlayerTurn) { throw new Exception("Not your turn"); } var history = new List <string>(); if (TurnNumber == 0) { throw new Exception("Calling EndTurn without firstturn started."); } history.Add($"End turn block & energy: (B{_Player.Block} E{_Player.Energy})"); var endTurnEf = new EffectSet(); foreach (var ci in _Deck.GetHand) { ci.LeftInHandAtEndOfTurn(endTurnEf.PlayerEffect); } _Deck.TurnEnds(endTurnEf, history); ApplyEffectSet(endTurnEf, _Player, _Enemies[0], history); //todo why do I have two EFs here? var relicEf = new EffectSet(); var endTurnPlayerEf = new EffectSet(); foreach (var si in _Player.StatusInstances) { si.EndTurn(_Player, endTurnPlayerEf.PlayerEffect, endTurnPlayerEf.EnemyEffect); } _Player.StatusInstances = _Player.StatusInstances.Where(el => el.Duration != 0 && el.Intensity != 0).ToList(); foreach (var relic in _Player.Relics) { relic.EndTurn(_Player, _Enemies[0], relicEf); } ApplyEffectSet(endTurnPlayerEf, _Player, _Enemies[0], history); ApplyEffectSet(relicEf, _Player, _Enemies[0], history); AssignLastAction(new FightAction(FightActionEnum.EndTurn, history: history)); PlayerTurn = false; EnemyDone = false; }
private void ReceiveDamage(IEntity entity, IndividualEffect ie, EffectSet ef, List <string> history, CardInstance ci) { if (ie.GetInitialDamage() == null && ie.DamageAdjustments?.Count > 0) { throw new Exception("should not happen"); //Vuln will only add a progression if initialdamage != null } //We don't actually want to if (ie.GetInitialDamage() != null) { var val = ie.GetInitialDamage().Select(el => (double)el); foreach (var prog in ie.DamageAdjustments.OrderBy(el => el.Order)) { val = prog.Fun(val.ToList()); } var usingVal = val.Select(el => (int)Math.Floor(el)); history.Add($"{entity.Name} got attacked for {string.Join(',', usingVal)}"); foreach (var el in usingVal) { var elCopy = el; if (elCopy > 0) { //handle block here. if (entity.Block > 0) { if (elCopy > entity.Block) { elCopy = elCopy - entity.Block; history.Add($"{entity.Name} blocked {entity.Block}"); entity.Block = 0; } else { entity.Block -= el; history.Add($"{entity.Name} blocked {el}"); elCopy = 0; } } if (elCopy > 0) { entity.ApplyDamage(elCopy, ef, ci, history); } } } //history.Add($"{entity.Details()}"); } }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { if (Amount.HasValue) { ef.PlayerEffect.SetInitialDamage(Helpers.Repeat(Amount.Value, Count.Value).ToArray()); } if (PlayerStatusAttack != null) { ef.PlayerEffect.Status.AddRange(PlayerStatusAttack); } if (Buffs != null) { ef.EnemyEffect.Status.AddRange(Buffs); } }
public override void StartFight(Deck d, EffectSet ef) { if (Charges > 0) { Charges--; ef.FightEffect.Add(new OneEffect() { Action = (Fight f, Deck d, List <string> history) => { f.SetEnemyHp(1); history.Add("Set enemy HP to 1"); } }); } }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var amt = 4; var tot = 0; while (upgradeCount > 0) { tot += amt; amt++; upgradeCount--; } var dmg = 12 + tot; ef.EnemyEffect.SetInitialDamage(dmg); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { int amt; if (upgradeCount == 0) { amt = 2; } else { amt = 3; } ef.PlayerEffect.Status.Add(new StatusInstance(new Dexterity(), amt)); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var str = player.StatusInstances.SingleOrDefault(el => el.Status.StatusType == StatusType.Strength); int dmg; if (str == null) { dmg = 14; } else { var mult = upgradeCount == 0 ? 3 : 5; dmg = 14 + mult * str.Intensity; } ef.EnemyEffect.SetInitialDamage(dmg); }
/// <summary> /// Enemy statuses actually apply at the start of their turn. /// </summary> private void StartEnemyTurn(List <string> history) { if (PlayerTurn) { throw new Exception("Out of order."); } var endTurnEnemyEf = new EffectSet(); foreach (var si in ((Entity)_Enemies[0]).StatusInstances) { si.EndTurn((Entity)_Enemies[0], endTurnEnemyEf.EnemyEffect, endTurnEnemyEf.PlayerEffect); } ApplyEffectSet(endTurnEnemyEf, _Player, _Enemies[0], history); _Enemies[0].StatusInstances = _Enemies[0].StatusInstances.Where(el => el.Duration != 0 && el.Intensity != 0).ToList(); }
/// <summary> /// Todo: Why do I manually use the components of the monster move ef rather than just using /// applyEffectSet? /// </summary> /// <param name="cardInstance"></param> /// <param name="history"></param> public void _Attack(CardInstance cardInstance, List <string> history) { var enemy = _Enemies[0]; var player = _Player; var ef = new EffectSet(); cardInstance.Play(ef, _Player, _Enemies[0]); _Player.NotifyAttacked(ef); foreach (var si in enemy.StatusInstances) { var statusIsTargeted = false; si.Apply(cardInstance.Card, ef.EnemyEffect, ef.PlayerEffect, statusIsTargeted, false); } foreach (var si in player.StatusInstances) { var statusIsTargeted = true; si.Apply(cardInstance.Card, ef.EnemyEffect, ef.PlayerEffect, statusIsTargeted, false); } //this won't be right for Torii for example. foreach (var relic in _Player.Relics) { relic.CardPlayed(cardInstance.Card, ef, player: _Player, enemy: _Enemies[0]); } GainBlock(_Player, ef.PlayerEffect, history); GainBlock(_Enemies[0], ef.EnemyEffect, history); ReceiveDamage(_Enemies[0], ef.EnemyEffect, ef, history, cardInstance); ReceiveDamage(_Player, ef.PlayerEffect, ef, history, cardInstance); ApplyStatus(_Player, ef.PlayerEffect.Status, history); ApplyStatus(_Enemies[0], ef.EnemyEffect.Status, history); //enemy dying of flame barrier status while killing the player, still results in a loss for the player. if (_Player.HP <= 0) { history.Add("Player Died from enemy attack"); Died(_Player, history); return; } if (_Enemies[0].HP <= 0) { history.Add("Enemy Died on his turn"); Died(_Enemies[0], history); } }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { //I need some way to: // * make sure the childnode from playing this ends up in the random list (not choices) // * distinguish between those random entries. ef.DeckEffect.Add((Deck d, List <string> h) => { var newCi = new CardInstance(new Wound(), 0); var position = d.AddToRandomSpotInDrawPile(newCi, key); h.Add($"Wound added to draw pile position:{position}"); }); var dmg = upgradeCount == 0 ? 12 : 17; ef.EnemyEffect.SetInitialDamage(dmg); ef.HadRandomness = true; ef.Key = key ?? 0; }
/// <summary> /// Bit annoying that targets actually covers two cases: /// 1. AI forcing a certain random choice /// 2. Normal play of the upgraded card, specifying the target /// </summary> internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var amt = upgradeCount == 0 ? 7 : 10; ef.PlayerEffect.AddBlockStep("TrueGrit", amt); ef.DeckEffect.Add((Deck d, List <string> h) => { //target determination: // upgraded + specify // upgraded + ask user // upgraded + default to random (!interactiveContext) // nonupgraded + specify // nonupgraded + random CardInstance target; var spec = ""; if (targets == null) { if (upgradeCount == 0) { target = d.GetRandomCardFromHand(); spec = "Picked random card from hand"; } else { target = d.ChooseCardFromHand(filter: null, prompt: "Pick a card to exhaust with True Grit"); spec = "Prompted to pick card from hand."; } } else { target = targets[0]; spec = "used target"; } if (target == null) { h.Add($"True Grit: {spec} Nothing to exhaust"); } else { h.Add($"True Grit: {spec}: {target}"); d.ExhaustFromHand(target, ef, h); } }); }
public void StartFight(List <string> history = null) { if (history == null) { history = new List <string>(); } var startEf = new EffectSet(); foreach (var relic in _Player.Relics) { relic.Apply(this, _Deck, _Player); relic.StartFight(_Deck, startEf); } _Deck.StartFight(); ApplyEffectSet(startEf, _Player, _Enemies[0], history); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { int dmg; StatusInstance si; if (upgradeCount == 0) { dmg = 12; si = new StatusInstance(new Weak(), 2); } else { dmg = 14; si = new StatusInstance(new Weak(), 3); } ef.EnemyEffect.SetInitialDamage(dmg); ef.EnemyEffect.Status.Add(si); }
/// <summary> /// Returns whether there was randomness involved in drinking the potion. /// </summary> public bool DrinkPotion(Potion p, Enemy enemy) { if (!PlayerTurn) { throw new Exception("Not your turn"); } var fakePotion = _Player.Potions.First(el => el.ToString() == p.ToString()); _Player.Potions.Remove(fakePotion); var history = new List <string>(); var ef = new EffectSet(); p.Apply(this, _Player, enemy, ef); ApplyEffectSet(ef, _Player, enemy, history); AssignLastAction(new FightAction(FightActionEnum.Potion, potion: p, target: enemy, history: history, hadRandomEffects: ef.HadRandomness, key: ef.Key)); return(false); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { var mult = upgradeCount == 0 ? 2 : 3; int count = 1; //PS itself is in a nether region now - played, but not yet in discard pile. //don't do anything with backup cards. Just look in draw, hand, discard. foreach (var list in new List <IList <CardInstance> >() { deck.GetDrawPile, deck.GetDiscardPile, deck.GetHand }) { var others = list.Where(el => RelatedCards.Contains(el.Card.Name)); count += others.Count(); } var dmg = 6 + mult * count; ef.EnemyEffect.SetInitialDamage(dmg); }
public List <CardInstance> DrawCards(int drawCount, EffectSet ef, List <string> history) { var actuallyDrawn = new List <CardInstance>(); Hand = new List <CardInstance>(); IList <CardInstance> which; which = WouldDraw(drawCount); var gap = drawCount - which.Count; if (gap > 0) { history.Add($"No cards left to draw {gap} more"); } foreach (var copy in which) { var orig = FindIdenticalCardInSource(DrawPile, copy, failureOkay: true); if (orig != null && DrawPile.Contains(orig)) { DrawPile.Remove(orig); TryAddToHand(orig, ef); actuallyDrawn.Add(orig); } else { Reshuffle(ef, history); //this should only happen 0-1 times orig = FindIdenticalCardInSource(DrawPile, copy, failureOkay: false); if (DrawPile.Contains(orig)) { DrawPile.Remove(orig); TryAddToHand(orig, ef); actuallyDrawn.Add(orig); } else { throw new Exception("Card missing after reshuffle"); } } } return(actuallyDrawn); }
internal override void Play(EffectSet ef, Player player, IEnemy enemy, int upgradeCount, IList <CardInstance> targets = null, Deck deck = null, long?key = null) { int weak; int vuln; if (upgradeCount == 0) { weak = 1; vuln = 1; } else { weak = 2; vuln = 2; } ef.EnemyEffect.SetInitialDamage(13); ef.EnemyEffect.Status.Add(new StatusInstance(new Vulnerable(), vuln)); ef.EnemyEffect.Status.Add(new StatusInstance(new Weak(), weak)); }