/// <summary> /// an action in a fight is one of: /// * player play card /// * player drink pot /// * player end turn /// /// * enemy play card (enemyAttack) /// * enemy buff (or do nothing) /// * enemy playerStatusATtack /// </summary> public FightAction(FightActionEnum fightActionType, CardInstance card = null, IList <CardInstance> cardTargets = null, Potion potion = null, IEntity target = null, List <string> history = null, long?key = null, List <long> keys = null, bool hadRandomEffects = false, bool playable = true) { CardTargets = cardTargets; FightActionType = fightActionType; Potion = potion?.Copy(); CardInstance = card?.Copy(); Target = target; History = history; Keys = keys; Key = key; Random = hadRandomEffects; // For console view, whether it can actually be chosen/played. Playable = playable; switch (fightActionType) { case FightActionEnum.Potion: if (hadRandomEffects != potion.Random) { throw new Exception("Enemy moves always random."); } break; case FightActionEnum.PlayCard: if (hadRandomEffects && !card.Card.RandomEffects) { throw new Exception("Unexpected"); } //had => rE but RE !=> had since not every randomizable effect card will actually have an effect every time. break; case FightActionEnum.EndTurn: case FightActionEnum.StartTurnEffect: case FightActionEnum.EndTurnEffect: case FightActionEnum.EndTurnDeckEffect: case FightActionEnum.EndTurnOtherEffect: case FightActionEnum.StartFightEffect: case FightActionEnum.EndFightEffect: case FightActionEnum.EnemyDied: case FightActionEnum.EndEnemyTurn: case FightActionEnum.WonFight: case FightActionEnum.LostFight: case FightActionEnum.TooLong: case FightActionEnum.NotInitialized: case FightActionEnum.StartTurn: if (hadRandomEffects) { throw new Exception($"{fightActionType} is not random since deck was already shuffled."); } break; case FightActionEnum.StartFight: if (!hadRandomEffects) { throw new Exception($"StartFight should be random."); } break; case FightActionEnum.EnemyMove: if (!hadRandomEffects) { throw new Exception("Enemy moves always random."); } //I need a key to disambiguate the same actions. //i.e. if a monster has two choices that would be key 0 and key 1. //harder is to find a way to handle draws. ideally it'd be hand.GetHash() break; } Validate(); }
private void ApplyEffectSet(EffectSet ef, Player player, IEnemy enemy, List <string> history, Potion potion = null, CardInstance ci = null, bool subEffectSet = false) { //TODO not clear if this order is the most sensible really or not. //complex effects like afterImage + playing defend with neg dex. //What happens if a deckeffect has further effects like exhausting a card, and the player has a status that triggers on this? //TODO this is complicated. Evolve actually adds new deckeffects in the deckeffect evaluation. foreach (var f in ef.DeckEffect) { f.Invoke(_Deck, history); } GainBlock(player, ef.PlayerEffect, history); ReceiveDamage(enemy, ef.EnemyEffect, ef, history, ci); GainBlock(enemy, ef.EnemyEffect, history); ReceiveDamage(player, ef.PlayerEffect, ef, history, ci); ApplyStatus(player, ef.PlayerEffect.Status, history); ApplyStatus(enemy, ef.EnemyEffect.Status, history); if (ef.PlayerEnergy != 0) { _Player.Energy += ef.PlayerEnergy; history.Add($"Gained ${ef.PlayerEnergy} to {_Player.Energy}"); } ef.FightEffect.ForEach(fe => fe.Action.Invoke(this, _Deck, history)); foreach (var en in _Enemies) { if (!en.Dead) { if (en.HP <= 0) { history.Add($"{en.Name} Died at {en.HP} HP"); Died(en, history); } } } if (_Player.HP <= 0) { if (!_Player.Dead) { history.Add("Player Died"); Died(_Player, history); } } if (!subEffectSet) { while (ef.NextEffectSet.Count > 0) { var next = ef.NextEffectSet.First(); ef.NextEffectSet.RemoveAt(0); ApplyEffectSet(next, player, enemy, history, potion, ci); } } }
public List <string> GetList() { var label = FightActionType.ToString(); //Certain types are always labelled switch (FightActionType) { case FightActionEnum.PlayCard: label = $"{CardInstance}"; break; case FightActionEnum.Potion: label = "Potion:" + Potion.ToString(); break; case FightActionEnum.EnemyDied: label = $"Enemy {Target} died"; break; case FightActionEnum.StartTurn: break; case FightActionEnum.EndTurn: case FightActionEnum.WonFight: case FightActionEnum.LostFight: case FightActionEnum.TooLong: break; case FightActionEnum.EnemyMove: break; case FightActionEnum.StartFight: break; case FightActionEnum.StartFightEffect: case FightActionEnum.EndFightEffect: case FightActionEnum.StartTurnEffect: case FightActionEnum.EndTurnEffect: case FightActionEnum.EndTurnDeckEffect: case FightActionEnum.EndTurnOtherEffect: case FightActionEnum.EndEnemyTurn: break; case FightActionEnum.NotInitialized: break; default: throw new System.Exception(); } //we always return a fighthistory. var res = new List <string>() { label }; if (History != null) { res.AddRange(History); } if (Random) { //possibly unnecessary in interactive context. res.Add($" R:{Key}"); } return(res); }