/// <returns>true if all damages are assigned</returns> public bool CheckStackForUnasignedDamage() { foreach (Damage d in this.ToArray().OfType <Damage>()) { if (d.Target == null) { Magic.AddLog(d.Amount + " damage from " + d.Source.Model.Name + " to assign"); return(false); } } return(true); }
public override bool TryToAddTarget(object target) { if (!WaitForTarget) { if (RemainingCost != null) { if (RemainingCost.RequiredTargetCount > 0 && target is CardInstance) { CardInstance cat = target as CardInstance; RemainingCost = RemainingCost.Pay(ref cat, CardSource); if (cat == null) { return(true); } } } return(false); } if (target is CardInstance) { CardInstance ci = target as CardInstance; if (ci.BindedAction != null) { target = ci.BindedAction; } } //other target group are possible, should change foreach (Target ct in ValidTargets) { if (ct.Accept(target, CardSource)) { if (Source.Effects.AcceptTarget(target)) { SelectedTargets.Add(target); return(true); } } } Magic.AddLog("Invalid target: " + target.ToString()); return(false); }
public AbilityActivation(CardInstance _source, Ability a, bool isInChoice = false) : base(_source) { Source = a; if (!Cost.IsNullOrCountIsZero(Source.ActivationCost)) { remainingCost = Source.ActivationCost.Clone(); remainingCost.OrderFirst(Source.ActivationCost.GetDominantMana()); } // else//if it's a spell ab, no cost and no message // return; if (CardSource != null && !isInChoice) { if (Source.Mandatory) { Magic.AddLog(CardSource.Model.Name + " ability activation."); } else { Magic.AddLog(Source.Message); } if (CardSource.Controler.ManaPool != null && remainingCost != null) { PayCost(ref CardSource.Controler.ManaPool); CardSource.Controler.NotifyValueChange("ManaPoolElements", CardSource.Controler.ManaPoolElements); } } if (Source.Category == AbilityCategory.Spell) { return; } if (IsComplete && GoesOnStack) { MagicEngine.CurrentEngine.GivePriorityToNextPlayer(); } }
public Spell(CardInstance _cardInstance) : base(_cardInstance) { _cardInstance.BindedAction = this; if (_cardInstance.Model.Cost != null) { remainingCost = _cardInstance.Model.Cost.Clone(); remainingCost.OrderFirst(_cardInstance.Model.Cost.GetDominantMana()); } Magic.AddLog("Trying to cast: " + CardSource.Model.Name); if (CardSource.Controler.ManaPool != null) { PayCost(ref CardSource.Controler.ManaPool); CardSource.Controler.NotifyValueChange("ManaPoolElements", CardSource.Controler.ManaPoolElements); } if (IsComplete && GoesOnStack) { MagicEngine.CurrentEngine.GivePriorityToNextPlayer(); } }
/// <summary> /// Check completeness of last action on stack. /// </summary> public void CheckLastActionOnStack() { if (this.Count == 0) { return; } MagicAction ma = this.Peek() as MagicAction; if (ma == null) { return; } if (ma.CardSource != null) { if (ma.CardSource.Controler != engine.pp) { return; } } //Magic.CurrentGameWin.CursorVisible = true; if (!ma.IsComplete) { if (ma.remainingCost == CostTypes.Tap) { ma.remainingCost = null; ma.CardSource.Tap(); } else if ((engine.pp.AvailableManaOnTable + engine.pp.ManaPool) < ma.RemainingCost?.ManaCost) { Magic.AddLog("Not enough mana available"); CancelLastActionOnStack(); return; } else if (engine.pp.ManaPool != null && ma.RemainingCost?.ManaCost != null) { string lastRemCost = ma.RemainingCost.ToString(); ma.PayCost(ref engine.pp.ManaPool); bool skipUpdateUI = false; if (ma.RemainingCost != null) { if (string.Equals(ma.RemainingCost.ToString(), lastRemCost, StringComparison.Ordinal)) { skipUpdateUI = true; } } if (!skipUpdateUI) { engine.pp.NotifyValueChange("ManaPoolElements", engine.pp.ManaPoolElements); notifyStackElementChange(); } } // if (ma.IsComplete && ma.GoesOnStack) // GivePriorityToNextPlayer (); } if (ma.IsComplete) { if (ma.GoesOnStack) { //should show spell to player... //UpdateStackLayouting(); engine.GivePriorityToNextPlayer(); } else { PopMSE(); ma.Resolve(); } return; } engine.pp.UpdateUi(); // AbilityActivation aa = ma as AbilityActivation; // //mana doest go on stack // if (aa != null){ // if (aa.Source.AbilityType == AbilityEnum.Mana) { // MagicEvent (new AbilityEventArg (aa.Source, aa.CardSource)); // MagicStack.Pop; // return; // } // } }
public override void Process() { MagicEngine e = MagicEngine.CurrentEngine; switch (CurrentState) { case PlayerStates.Init: return; case PlayerStates.PlayDrawChoice: //chose to play first e.currentPlayerIndex = e.getPlayerIndex(this); CurrentState = PlayerStates.InitialDraw; return; case PlayerStates.InitialDraw: initialDraw(); CurrentState = PlayerStates.KeepMuliganChoice; return; case PlayerStates.KeepMuliganChoice: //choose to keep CurrentState = PlayerStates.Ready; e.RaiseMagicEvent(new MagicEventArg(MagicEventType.PlayerIsReady, this)); return; } if (e.pp != this || e.State < EngineStates.CurrentPlayer) { return; } if (HasActionPending) { ActivateAvailableMana(e); return; } if (e.cp == this) { switch (e.CurrentPhase) { case GamePhases.Untap: PhaseDone = true; break; case GamePhases.Upkeep: PhaseDone = true; break; case GamePhases.Draw: PhaseDone = true; break; case GamePhases.Main1: case GamePhases.Main2: if (AllowedLandsToBePlayed > 0) { if (AITryToPlayLand()) { break; } } if (!CastAvailableAndAllowedCreature()) { PhaseDone = true; } break; case GamePhases.BeforeCombat: PhaseDone = true; break; case GamePhases.DeclareAttacker: AITryToAttack(); PhaseDone = true; break; case GamePhases.DeclareBlocker: PhaseDone = true; break; case GamePhases.FirstStrikeDame: PhaseDone = true; break; case GamePhases.CombatDamage: PhaseDone = true; break; case GamePhases.EndOfCombat: PhaseDone = true; break; case GamePhases.EndOfTurn: PhaseDone = true; break; case GamePhases.CleanUp: PhaseDone = true; break; } } else { if (e.pp == this) { Magic.AddLog("AI just had priority"); e.GivePriorityToNextPlayer(); } // switch (e.CurrentPhase) // { // case GamePhases.Untap: // PhaseDone = true; // break; // case GamePhases.Upkeep: // PhaseDone = true; // break; // case GamePhases.Draw: // PhaseDone = true; // break; // case GamePhases.Main1: // PhaseDone = true; // break; // case GamePhases.BeforeCombat: // PhaseDone = true; // break; // case GamePhases.DeclareAttacker: // PhaseDone = true; // break; // case GamePhases.DeclareBlocker: // PhaseDone = true; // break; // case GamePhases.FirstStrikeDame: // PhaseDone = true; // break; // case GamePhases.CombatDamage: // PhaseDone = true; // break; // case GamePhases.EndOfCombat: // PhaseDone = true; // break; // case GamePhases.Main2: // PhaseDone = true; // break; // case GamePhases.EndOfTurn: // PhaseDone = true; // break; // case GamePhases.CleanUp: // PhaseDone = true; // break; // } } }
void MagicEngine_MagicEvent(MagicEventArg arg) { Magic.AddLog("MAGIC EVENT: " + arg.ToString()); #region check triggers //check cards in play having trigger effects foreach (CardInstance ci in CardsInPlayHavingTriggers) { foreach (Trigger t in ci.Model.Triggers) { if (t.ExecuteIfMatch(arg, ci)) { Magic.AddLog("=> " + t.ToString()); } } } //check pump effect //todo should simplify trigger checking with a single function foreach (CardInstance ci in CardsInPlayHavingPumpEffects) { List <EffectGroup> egToRemove = new List <EffectGroup>(); foreach (EffectGroup eg in ci.PumpEffect) { if (eg.TrigEnd != null) { if (eg.TrigEnd.Type != arg.Type) { continue; } switch (eg.TrigEnd.Type) { case MagicEventType.EndTurn: egToRemove.Add(eg); break; } } } foreach (EffectGroup egtr in egToRemove) { ci.PumpEffect.Remove(egtr); } } #endregion switch (arg.Type) { case MagicEventType.PlayerIsReady: //check if all players are ready foreach (Player p in Players) { if (p.CurrentState != Player.PlayerStates.Ready) { return; } } startGame(); break; case MagicEventType.BeginPhase: processPhaseBegin(arg as PhaseEventArg); break; case MagicEventType.EndPhase: processPhaseEnd(arg as PhaseEventArg); break; case MagicEventType.PlayLand: break; case MagicEventType.ActivateAbility: break; case MagicEventType.CastSpell: break; case MagicEventType.TapCard: break; case MagicEventType.ChangeZone: if (arg.Source.IsToken) { arg.Source.CurrentGroup.Cards.Remove(arg.Source); } break; case MagicEventType.Unset: break; default: break; } CheckCardInstanceUpdates(); foreach (Player p in Players) //TODO:too wide update { p.InPlay.UpdateLayout(); } }