public void MoveEnemies(MinionAnimationSequence animation) { List<MinionMove> minionMoves = new List<MinionMove>(); HashSet<Minion> minionsStillMoving = new HashSet<Minion>(); MinionAnimationBatch stepBatch = animation.AddBatch(this, Game1.WALK_ANIM_DURATION); // enemies walk forward Point levelSize = levelScript.levelSize; for (int x = 0; x < levelSize.X; x++) //NB processing these in ascending X order - this matters { for (int y = levelSize.Y - 1; y >= 0; y--) { Minion m = getMinionAt(new Point(x, y)); if(m == null) continue; if(m.isEnemy && m.stats.move > 0) { HandleTriggers(new TriggerEvent(TriggerType.beforeMove, m)); Vector2 oldDrawPos = m.drawPos; if (m.stats.move == 1 && m.stats.hasKeyword(Keyword.slow) && !m.slow_movedHalfWay) { m.slow_movedHalfWay = true; stepBatch.AddAnimation(m, oldDrawPos, m.drawPos); } else { MinionMove mmove = new MinionMove(m); minionMoves.Add(mmove); minionsStillMoving.Add(m); } } } } CleanUp(animation); bool hasMoreMoves = true; bool firstPass = true; while(hasMoreMoves) { foreach (MinionMove mmove in minionMoves) { if (mmove.movesLeft <= 0) continue; if (levelScript.Blocks(mmove.moveTo, TargetType.empty)) { mmove.movesLeft = 0; mmove.moveSpent = true; minionsStillMoving.Remove(mmove.minion); } else if (minions.ContainsKey(mmove.moveTo) && !minionsStillMoving.Contains(getMinionAt(mmove.moveTo))) { // If I'm blocked: if (mmove.minion.stats.hasKeyword(Keyword.unstoppable) || getMinionAt(mmove.moveTo).stats.hasKeyword(Keyword.intangible)) { Destroyed(mmove.moveTo, mmove.minion); } mmove.moveSpent = true; } } CleanUp(animation); hasMoreMoves = false; foreach (MinionMove mmove in minionMoves) { if (mmove.movesLeft > 0) { if (TryMove(mmove, mmove.moveTo)) { mmove.moveSpent = true; mmove.minion.slow_movedHalfWay = false; stepBatch.AddAnimation(mmove.minion, mmove.currentAnimPos, mmove.minion.drawPos); mmove.currentAnimPos = mmove.minion.drawPos; } if (mmove.moveSpent) { mmove.movesLeft--; mmove.moveSpent = false; } if (mmove.movesLeft > 0) { hasMoreMoves = true; } else { minionsStillMoving.Remove(mmove.minion); } } } if (firstPass) { levelScript.Apply(this, stepBatch); firstPass = false; } stepBatch.SetInitialGameState(new GameState(this)); stepBatch = animation.AddBatch(this, Game1.WALK_ANIM_DURATION); } }
public void ResolveWaitingTriggers(MinionAnimationSequence animation) { int loopCount = 0; while(triggersWaiting.Count > 0) { loopCount++; List<WaitingTrigger> triggersResolving = triggersWaiting; triggersWaiting = new List<WaitingTrigger>(); bool hasAttackTriggers = false; foreach(WaitingTrigger trigger in triggersResolving) { if (trigger.ability.isAttackTrigger) hasAttackTriggers = true; else trigger.ability.Apply(new EffectContext(this, null, trigger.permanent, TriggerItem.create(trigger.permanent), trigger.evt, animation)); } if (hasAttackTriggers) { MinionAnimationBatch attackAnim = animation.AddBatch(new GameState(this), Game1.ATTACK_ANIM_DURATION); MinionAnimationBatch recoverAnim = animation.AddBatch(this, Game1.RECOVER_ANIM_DURATION); foreach (WaitingTrigger trigger in triggersResolving) { if (trigger.ability.isAttackTrigger) trigger.ability.Apply(new EffectContext(this, trigger.permanent, trigger.position, trigger.evt, attackAnim, recoverAnim, animation)); } recoverAnim.SetInitialGameState(new GameState(this)); } DeadMinionsDie(); if (loopCount > 100) { triggersWaiting.Clear(); } } }
public void MinionsAttack(MinionAnimationSequence animation) { HandleTriggers(new TriggerEvent(TriggerType.beforeCombat)); CleanUp(animation); MinionAnimationBatch attack = null; MinionAnimationBatch recover = null; if (animation != null) { attack = animation.AddBatch(new GameState(this), Game1.ATTACK_ANIM_DURATION); recover = animation.AddBatch(this, Game1.RECOVER_ANIM_DURATION); } for (int y = levelScript.levelSize.Y - 1; y >= 0; y--) { for (int x = 0; x < levelScript.levelSize.X; x++) { Minion p = getMinionAt(new Point(x, y)); if (p != null) { p.CheckAttacks(this, 0, attack, recover, animation); } } } recover.SetInitialGameState(new GameState(this)); HandleTriggers(new TriggerEvent(TriggerType.afterCombat)); CleanUp(animation); }