private void GainBlock(IEntity entity, IndividualEffect ef, List <string> history) { //unlike attacks, initialBlock defaults to zero so that you can have adjustments on zero // (for example, exhausting a card with Feel No Pain on.) var val = 0d; foreach (var prog in ef.GetBlockActions.OrderBy(el => el.Order)) { if (prog.Additive) { val += prog.Amount; } else { val *= prog.Amount; } history.Add($"{prog} affected block"); } if (val > 0) { var gain = (int)val; entity.Block += gain; history.Add($"{entity} gained {gain}B"); } }
internal override void CardWasPlayed(Card card, IndividualEffect sourceSet, IndividualEffect targetSet, int intensity, bool statusIsTargeted, bool playerAction) { if (card.CardType == CardType.Attack && statusIsTargeted) { if (targetSet.GetInitialDamage() != null) { targetSet.DamageAdjustments.Add(new AttackProgression("Vuln", (el) => el.Select(qq => qq > 0 ? qq * 1.5 : 0).ToList())); } } }
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()}"); } }
public override void LeftInHandAtEndOfTurn(IndividualEffect ie, int upgradeCount) { var dmg = upgradeCount == 0 ? 2 : 4; //in this context (end of player turn), there is no pattern of initialdamage/damage mods. more like a seq of events. //todo: fix this to just have independent sequences of damage. if (ie.GetInitialDamage() == null) { ie.SetInitialDamage(dmg); } else { var old = ie.GetInitialDamage().ToList(); old.Add(dmg); ie.SetInitialDamage(old.ToArray()); } }
internal override void CardWasPlayed(Card card, IndividualEffect playerSet, IndividualEffect enemySet, int intensity, bool statusIsTargeted, bool playerAction) { //TODO: it would be better if this was a running total of defense so we could directly compare. //only add block if it's actually a block card (not entrench) if (card.CardType == CardType.Skill && statusIsTargeted) { //dex only adds block if there is an existing additive. //i.e. entrench doesn't quality. foreach (var existingSteps in playerSet.GetBlockActions.Where(el => el.Order < 10)) { if (existingSteps.Additive) { playerSet.AddBlockStep("Dex", intensity); break; } } } }
public void EndTurn(Entity parent, IndividualEffect statusHolderIe, IndividualEffect otherIe) { if (!Status.Permanent) { Duration--; } //remove them externally since we're iterating here. if (Duration < 0) { throw new Exception("Negative Duration"); } //shoudl I just return here, to not apply the status? if (Duration == 0) { return; //throw new Exception("Expired status being applied."); } Status.StatusEndTurn(parent, this, statusHolderIe, otherIe); }
internal override void CardWasPlayed(Card card, IndividualEffect playerSet, IndividualEffect enemySet, int intensity, bool statusIsTargeted, bool playerAction) { if (card.CardType == CardType.Attack && !statusIsTargeted && enemySet.GetInitialDamage() != null) { enemySet.DamageAdjustments.Add(new AttackProgression("PenNibDD", (el) => { if (intensity > 0) { //removal of pen nib whenever we play an attack. var negativePenNib = new StatusInstance(new PenNibStatus(), -1); //whoah, this will be applied when the attack is actually resolved. //since here we're playerSet.Status.Add(negativePenNib); return(el.Select(qq => qq > 0 ? qq * 2 : 0).ToList()); } return(el); })); } }
internal override void CardWasPlayed(Card card, IndividualEffect sourceSet, IndividualEffect targetSet, int intensity, bool statusIsTargeted, bool playerAction) { //statusIsTargeted means the target has the status. //in this case we only care if the subject has the status. if (card.CardType == CardType.Attack && !statusIsTargeted) { if (card.Name == "HeavyBlade") { //already calculated. return; } if (targetSet.GetInitialDamage() == null) { throw new System.Exception("Why am i calculating strength without having a base damage?"); } //strength always calculated immediately after initial damage. //this should be genericized; here it's assuming strength only hits enemy when actually it hits whoever the target is. targetSet.DamageAdjustments.Insert(0, new AttackProgression("StrengthStatus", (el) => el.Select(qq => qq + intensity).ToList())); } }
public void StartTurn(Entity parent, IndividualEffect statusHolderIe, IndividualEffect otherIe) { Status.StatusStartTurn(parent, this, statusHolderIe, otherIe); }
public void Apply(Card card, IndividualEffect sourceSet, IndividualEffect targetSet, bool statusIsTargeted, bool playerAction) { Status.CardWasPlayed(card, sourceSet, targetSet, Intensity, statusIsTargeted, playerAction); }
internal void LeftInHandAtEndOfTurn(IndividualEffect playerEffect) { Card.LeftInHandAtEndOfTurn(playerEffect, UpgradeCount); }
public virtual void LeftInHandAtEndOfTurn(IndividualEffect playerEffect, int upgradeCount) { }