@Override public boolean activateAbility(ActivatedAbility ability, Game game) { getManaPool().setStock(); // needed for the "mana already in the pool has to be used manually" option return super.activateAbility(ability, game); }
@Override public List<Permanent> getAvailableAttackers(Game game) { // TODO: get available opponents and their planeswalkers, check for each if permanent can attack one return getAvailableAttackers(null, game); }
protected void addVariableXOptions(List<Ability> options, Ability option, int targetNum, Game game) { addTargetOptions(options, option, targetNum, game); }
if (!shouldSkipGettingPlayable(game)) { ManaOptions availableMana = getManaAvailable(game); availableMana.addMana(manaPool.getMana()); for (ConditionalMana conditionalMana : manaPool.getConditionalMana()) { if (!(ability instanceof PlayLandAbility) || !game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) { if (canPlay((ActivatedAbility) ability, availableMana, card, game)) { playable.add(ability); if (canLandPlayAlternateSourceCostsAbility(card, availableMana, ability, game)) { // e.g. Land with Morph playable.add(ability); getPlayableFromGraveyardCard(game, splitCard.getLeftHalfCard(), splitCard.getLeftHalfCard().getAbilities(), availableMana, playable); getPlayableFromGraveyardCard(game, splitCard.getRightHalfCard(), splitCard.getRightHalfCard().getAbilities(), availableMana, playable); getPlayableFromGraveyardCard(game, splitCard, splitCard.getSharedAbilities(), availableMana, playable); } else { getPlayableFromGraveyardCard(game, card, card.getAbilities(), availableMana, playable); getOtherUseableActivatedAbilities(card, Zone.GRAVEYARD, game, useable); playable.addAll(useable.values()); if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) { for (Ability ability : card.getAbilities()) { if (ability.getZone().match(Zone.HAND)) { ability.setControllerId(this.getId()); // controller must be set for case owner != caster if (ability instanceof ActivatedAbility) { if (((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) {
) { Set<UUID> playable = new HashSet<>(); if (!shouldSkipGettingPlayable(game)) { ManaOptions available = getManaAvailable(game); available.addMana(manaPool.getMana()); break; if (canPlay((ActivatedAbility) ability, available, card, game)) { playable.add(card.getId()); break Abilities; case ACTIVATED: case SPELL: if (canPlay((ActivatedAbility) ability, available, card, game)) { playable.add(card.getId()); break Abilities; case STATIC: if (card.isLand() && ability instanceof AlternativeSourceCosts) { if (canLandPlayAlternateSourceCostsAbility(card, available, ability, game)) { // e.g. Land with Morph if (game.canPlaySorcery(getId())) { playable.add(card.getId());
/** * Only used for AIs * * @param ability * @param game * @return */ @Override public List<Ability> getPlayableOptions(Ability ability, Game game) { List<Ability> options = new ArrayList<>(); if (ability.isModal()) { addModeOptions(options, ability, game); } else if (!ability.getTargets().getUnchosen().isEmpty()) { // TODO: Handle other variable costs than mana costs if (!ability.getManaCosts().getVariableCosts().isEmpty()) { addVariableXOptions(options, ability, 0, game); } else { addTargetOptions(options, ability, 0, game); } } else if (!ability.getCosts().getTargets().getUnchosen().isEmpty()) { addCostTargetOptions(options, ability, 0, game); } return options; }
@SuppressWarnings({"null", "ConstantConditions"}) private int doDamage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable, List<UUID> appliedEffects) { if (damage > 0) { if (canDamage(game.getObject(sourceId), game)) { GameEvent event = new DamagePlayerEvent(playerId, sourceId, playerId, damage, preventable, combatDamage); event.setAppliedEffects(appliedEffects); addCounters(CounterType.POISON.createInstance(actualDamage), game); } else { GameEvent damageToLifeLossEvent = new GameEvent(EventType.DAMAGE_CAUSES_LIFE_LOSS, playerId, sourceId, playerId, actualDamage, combatDamage); if (!game.replaceEvent(damageToLifeLossEvent)) { this.loseLife(damageToLifeLossEvent.getAmount(), game, combatDamage); game.informPlayers(damage + " damage " + (sourceObject == null ? "" : "from " + sourceObject.getLogName()) + " to " + getLogName() + (damage > 1 ? " were" : "was") + " prevented because of protection.");
private void addModeOptions(List<Ability> options, Ability option, Game game) { // TODO: Support modal spells with more than one selectable mode for (Mode mode : option.getModes().values()) { Ability newOption = option.copy(); newOption.getModes().getSelectedModes().clear(); newOption.getModes().getSelectedModes().add(mode.getId()); newOption.getModes().setActiveMode(mode); if (!newOption.getTargets().getUnchosen().isEmpty()) { if (!newOption.getManaCosts().getVariableCosts().isEmpty()) { addVariableXOptions(options, newOption, 0, game); } else { addTargetOptions(options, newOption, 0, game); } } else if (!newOption.getCosts().getTargets().getUnchosen().isEmpty()) { addCostTargetOptions(options, newOption, 0, game); } else { options.add(newOption); } } }
protected void addTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) { for (Target target : option.getTargets().getUnchosen().get(targetNum).getTargetOptions(option, game)) { Ability newOption = option.copy(); if (target instanceof TargetAmount) { for (UUID targetId : target.getTargets()) { int amount = target.getTargetAmount(targetId); newOption.getTargets().get(targetNum).addTarget(targetId, amount, newOption, game, true); } } else { for (UUID targetId : target.getTargets()) { newOption.getTargets().get(targetNum).addTarget(targetId, newOption, game, true); } } if (targetNum < option.getTargets().size() - 2) { addTargetOptions(options, newOption, targetNum + 1, game); } else if (!option.getCosts().getTargets().isEmpty()) { addCostTargetOptions(options, newOption, 0, game); } else { options.add(newOption); } } }
@Override public void leave() { this.passed = true; this.loses = true; this.left = true; this.abort(); //20100423 - 800.4a this.hand.clear(); this.graveyard.clear(); this.library.clear(); }
private void addCostTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) { for (UUID targetId : option.getCosts().getTargets().get(targetNum).possibleTargets(option.getSourceId(), playerId, game)) { Ability newOption = option.copy(); newOption.getCosts().getTargets().get(targetNum).addTarget(targetId, option, game, true); if (targetNum < option.getCosts().getTargets().size() - 1) { addCostTargetOptions(options, newOption, targetNum + 1, game); } else { options.add(newOption); } } }
protected Attackers getPotentialAttackers(Game game) { log.debug("getAvailableAttackers"); Attackers attackers = new Attackers(); List<Permanent> creatures = super.getAvailableAttackers(game); for (Permanent creature : creatures) { int potential = combatPotential(creature, game); if (potential > 0 && creature.getPower().getValue() > 0) { List<Permanent> l = attackers.get(potential); if (l == null) { attackers.put(potential, l = new ArrayList<>()); } l.add(creature); } } return attackers; }
@Override public boolean activateAbility(ActivatedAbility ability, Game game) { if (!isTestMode()) { // Test player already sends target event as he selects the target for (Target target : ability.getModes().getMode().getTargets()) { for (UUID targetId : target.getTargets()) { game.fireEvent(GameEvent.getEvent(EventType.TARGETED, targetId, ability.getId(), ability.getControllerId())); } } } return super.activateAbility(ability, game); }