use of mage.game.command.CommandObject in project mage by magefree.
the class CardTestPlayerAPIImpl method assertEmblemCount.
/**
* Assert emblem count under player's control
*
* @param player
* @param count
* @throws AssertionError
*/
@Override
public void assertEmblemCount(Player player, int count) throws AssertionError {
int actualCount = 0;
for (CommandObject commandObject : currentGame.getState().getCommand()) {
if (commandObject.getControllerId().equals(player.getId())) {
actualCount++;
}
}
Assert.assertEquals("Emblem counts are not equal", count, actualCount);
}
use of mage.game.command.CommandObject in project mage by magefree.
the class ArcaneAdaptationEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (controller == null || subType == null) {
return false;
}
// in graveyard
for (UUID cardId : controller.getGraveyard()) {
Card card = game.getCard(cardId);
if (card != null && card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
// on Hand
for (UUID cardId : controller.getHand()) {
Card card = game.getCard(cardId);
if (card != null && card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
// in Exile
for (Card card : game.getState().getExile().getAllCards(game)) {
if (card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
// in Library (e.g. for Mystical Teachings)
for (Card card : controller.getLibrary().getCards(game)) {
if (card.isOwnedBy(controller.getId()) && card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
// commander in command zone
for (CommandObject commandObject : game.getState().getCommand()) {
if (commandObject instanceof Commander) {
Card card = game.getCard(((Commander) commandObject).getId());
if (card != null && card.isOwnedBy(controller.getId()) && card.isCreature(game) && !card.hasSubtype(subType, game)) {
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
}
// creature spells you control
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
StackObject stackObject = iterator.next();
if (stackObject instanceof Spell && stackObject.isControlledBy(source.getControllerId()) && stackObject.isCreature(game) && !stackObject.hasSubtype(subType, game)) {
Card card = ((Spell) stackObject).getCard();
game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
}
}
// creatures you control
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterControlledCreaturePermanent(), source.getControllerId(), game);
for (Permanent creature : creatures) {
if (creature != null) {
creature.addSubType(game, subType);
}
}
return true;
}
use of mage.game.command.CommandObject in project mage by magefree.
the class CardImpl method removeFromZone.
@Override
public boolean removeFromZone(Game game, Zone fromZone, Ability source) {
boolean removed = false;
MageObject lkiObject = null;
switch(fromZone) {
case GRAVEYARD:
removed = game.getPlayer(ownerId).removeFromGraveyard(this, game);
break;
case HAND:
removed = game.getPlayer(ownerId).removeFromHand(this, game);
break;
case LIBRARY:
removed = game.getPlayer(ownerId).removeFromLibrary(this, game);
break;
case EXILED:
if (game.getExile().getCard(getId(), game) != null) {
removed = game.getExile().removeCard(this, game);
}
break;
case STACK:
StackObject stackObject;
if (getSpellAbility() != null) {
stackObject = game.getStack().getSpell(getSpellAbility().getId(), false);
} else {
stackObject = game.getStack().getSpell(this.getId(), false);
}
// handle half of Split Cards on stack
if (stackObject == null && (this instanceof SplitCard)) {
stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId(), false);
if (stackObject == null) {
stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId(), false);
}
}
// handle half of Modal Double Faces Cards on stack
if (stackObject == null && (this instanceof ModalDoubleFacesCard)) {
stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getLeftHalfCard().getId(), false);
if (stackObject == null) {
stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getRightHalfCard().getId(), false);
}
}
if (stackObject == null && (this instanceof AdventureCard)) {
stackObject = game.getStack().getSpell(((AdventureCard) this).getSpellCard().getId(), false);
}
if (stackObject == null) {
stackObject = game.getStack().getSpell(getId(), false);
}
if (stackObject != null) {
removed = game.getStack().remove(stackObject, game);
lkiObject = stackObject;
}
break;
case COMMAND:
for (CommandObject commandObject : game.getState().getCommand()) {
if (commandObject.getId().equals(objectId)) {
lkiObject = commandObject;
}
}
if (lkiObject != null) {
removed = game.getState().getCommand().remove(lkiObject);
}
break;
case OUTSIDE:
if (isCopy()) {
// copied cards have no need to be removed from a previous zone
removed = true;
} else if (game.getPlayer(ownerId).getSideboard().contains(this.getId())) {
game.getPlayer(ownerId).getSideboard().remove(this.getId());
removed = true;
} else if (game.getPhase() == null) {
// E.g. Commander of commander game
removed = true;
} else {
// Unstable - Summon the Pack
removed = true;
}
break;
case // for sacrificing permanents or putting to library
BATTLEFIELD:
removed = true;
break;
default:
MageObject sourceObject = game.getObject(source.getSourceId());
logger.fatal("Invalid from zone [" + fromZone + "] for card [" + this.getIdName() + "] source [" + (sourceObject != null ? sourceObject.getName() : "null") + ']');
break;
}
if (removed) {
if (fromZone != Zone.OUTSIDE) {
game.rememberLKI(lkiObject != null ? lkiObject.getId() : objectId, fromZone, lkiObject != null ? lkiObject : this);
}
} else {
logger.warn("Couldn't find card in fromZone, card=" + getIdName() + ", fromZone=" + fromZone);
// possible reason: you to remove card from wrong zone or card already removed,
// e.g. you added copy card to wrong graveyard (see owner) or removed card from graveyard before moveToZone call
}
return removed;
}
use of mage.game.command.CommandObject in project mage by magefree.
the class RollPlanarDieEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
PlanarDieRollResult planarRoll = controller.rollPlanarDie(outcome, source, game);
if (planarRoll == PlanarDieRollResult.CHAOS_ROLL && chaosEffects != null && chaosTargets != null) {
for (int i = 0; i < chaosTargets.size(); i++) {
Target target = chaosTargets.get(i);
if (target != null) {
target.clearChosen();
}
}
for (int i = 0; i < chaosEffects.size(); i++) {
Effect effect = chaosEffects.get(i);
Target target = null;
if (chaosTargets.size() > i) {
target = chaosTargets.get(i);
}
boolean done = false;
while (controller.canRespond() && effect != null && !done) {
if (target != null && !target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game)) {
controller.chooseTarget(Outcome.Benefit, target, source, game);
source.addTarget(target);
}
if (target != null) {
effect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
}
try {
effect.apply(game, source);
} catch (UnsupportedOperationException exception) {
}
if (effect instanceof ContinuousEffect) {
game.addEffect((ContinuousEffect) effect, source);
}
done = true;
}
}
} else if (planarRoll == PlanarDieRollResult.PLANAR_ROLL) {
// Steps: 1) Remove the last plane and set its effects to discarded
for (CommandObject cobject : game.getState().getCommand()) {
if (cobject instanceof Plane) {
if (cobject.getAbilities() != null) {
for (Ability ability : cobject.getAbilities()) {
for (Effect effect : ability.getEffects()) {
if (effect instanceof ContinuousEffect) {
((ContinuousEffect) effect).discard();
}
}
}
}
game.getState().removeTriggersOfSourceId(cobject.getId());
game.getState().getCommand().remove(cobject);
break;
}
}
// 2) Choose a new random plane we haven't been to, or reset if we've been everywhere
List<String> planesVisited = game.getState().getSeenPlanes();
if (game.getState().getSeenPlanes() != null) {
if (planesVisited.size() == Planes.values().length) {
game.getState().resetSeenPlanes();
}
}
boolean foundNextPlane = false;
while (!foundNextPlane) {
Plane plane = Plane.createRandomPlane();
try {
if (plane != null && !planesVisited.contains(plane.getName())) {
foundNextPlane = true;
plane.setControllerId(controller.getId());
game.addPlane(plane, null, controller.getId());
}
} catch (Exception ex) {
}
}
}
return true;
}
return false;
}
use of mage.game.command.CommandObject in project mage by magefree.
the class PlayerImpl method getPlayable.
/**
* Returns a list of all available spells and abilities the player can
* currently cast/activate with his available resources.
* Without target validation.
*
* @param game
* @param hidden also from hidden objects (e.g. turned face down cards ?)
* @param fromZone of objects from which zone (ALL = from all zones)
* @param hideDuplicatedAbilities if equal abilities exist return only the
* first instance
* @return
*/
public List<ActivatedAbility> getPlayable(Game game, boolean hidden, Zone fromZone, boolean hideDuplicatedAbilities) {
List<ActivatedAbility> playable = new ArrayList<>();
if (shouldSkipGettingPlayable(game)) {
return playable;
}
boolean previousState = game.inCheckPlayableState();
game.setCheckPlayableState(true);
try {
// get available mana options (mana pool and conditional mana added (but conditional still lose condition))
ManaOptions availableMana = getManaAvailable(game);
boolean fromAll = fromZone.equals(Zone.ALL);
if (hidden && (fromAll || fromZone == Zone.HAND)) {
for (Card card : hand.getCards(game)) {
for (Ability ability : card.getAbilities(game)) {
// gets this activated ability from hand? (Morph?)
if (ability.getZone().match(Zone.HAND)) {
boolean isPlaySpell = (ability instanceof SpellAbility);
boolean isPlayLand = (ability instanceof PlayLandAbility);
// play land restrictions
if (isPlayLand && game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability, this.getId()), ability, game, true)) {
continue;
}
// cast spell restrictions 1
GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability, this.getId());
castEvent.setZone(fromZone);
if (isPlaySpell && game.getContinuousEffects().preventedByRuleModification(castEvent, ability, game, true)) {
continue;
}
// cast spell restrictions 2
GameEvent castLateEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, ability.getId(), ability, this.getId());
castLateEvent.setZone(fromZone);
if (isPlaySpell && game.getContinuousEffects().preventedByRuleModification(castLateEvent, ability, game, true)) {
continue;
}
ActivatedAbility playAbility = findActivatedAbilityFromPlayable(card, availableMana, ability, game);
if (playAbility != null && !playable.contains(playAbility)) {
playable.add(playAbility);
}
}
}
}
}
if (fromAll || fromZone == Zone.GRAVEYARD) {
for (UUID playerId : game.getState().getPlayersInRange(getId(), game)) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
for (Card card : player.getGraveyard().getCards(game)) {
getPlayableFromObjectAll(game, Zone.GRAVEYARD, card, availableMana, playable);
}
}
}
if (fromAll || fromZone == Zone.EXILED) {
for (ExileZone exile : game.getExile().getExileZones()) {
for (Card card : exile.getCards(game)) {
getPlayableFromObjectAll(game, Zone.EXILED, card, availableMana, playable);
}
}
}
// check to play revealed cards
if (fromAll) {
for (Cards revealedCards : game.getState().getRevealed().values()) {
for (Card card : revealedCards.getCards(game)) {
// revealed cards can be from any zones
getPlayableFromObjectAll(game, game.getState().getZone(card.getId()), card, availableMana, playable);
}
}
}
// outside cards
if (fromAll || fromZone == Zone.OUTSIDE) {
// companion cards
for (Cards companionCards : game.getState().getCompanion().values()) {
for (Card card : companionCards.getCards(game)) {
getPlayableFromObjectAll(game, Zone.OUTSIDE, card, availableMana, playable);
}
}
// sideboard cards (example: Wish)
for (UUID sideboardCardId : this.getSideboard()) {
Card sideboardCard = game.getCard(sideboardCardId);
if (sideboardCard != null) {
getPlayableFromObjectAll(game, Zone.OUTSIDE, sideboardCard, availableMana, playable);
}
}
}
// check if it's possible to play the top card of a library
if (fromAll || fromZone == Zone.LIBRARY) {
for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
Player player = game.getPlayer(playerInRangeId);
if (player != null && player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game);
if (card != null) {
getPlayableFromObjectAll(game, Zone.LIBRARY, card, availableMana, playable);
}
}
}
}
// AI games: computer can see and play cards from opponent's hand without reveal
if (fromAll || fromZone == Zone.HAND) {
for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
Player player = game.getPlayer(playerInRangeId);
if (player != null && !player.getHand().isEmpty()) {
for (Card card : player.getHand().getCards(game)) {
if (card != null) {
getPlayableFromObjectAll(game, Zone.HAND, card, availableMana, playable);
}
}
}
}
}
// eliminate duplicate activated abilities (uses for AI plays)
Map<String, ActivatedAbility> activatedUnique = new HashMap<>();
List<ActivatedAbility> activatedAll = new ArrayList<>();
// activated abilities from battlefield objects
if (fromAll || fromZone == Zone.BATTLEFIELD) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
boolean canUseActivated = permanent.canUseActivatedAbilities(game);
List<ActivatedAbility> currentPlayable = new ArrayList<>();
getPlayableFromObjectAll(game, Zone.BATTLEFIELD, permanent, availableMana, currentPlayable);
for (ActivatedAbility ability : currentPlayable) {
if (ability instanceof SpecialAction || canUseActivated) {
activatedUnique.putIfAbsent(ability.toString(), ability);
activatedAll.add(ability);
}
}
}
}
// activated abilities from stack objects
if (fromAll || fromZone == Zone.STACK) {
for (StackObject stackObject : game.getState().getStack()) {
List<ActivatedAbility> currentPlayable = new ArrayList<>();
getPlayableFromObjectAll(game, Zone.STACK, stackObject, availableMana, currentPlayable);
for (ActivatedAbility ability : currentPlayable) {
activatedUnique.put(ability.toString(), ability);
activatedAll.add(ability);
}
}
}
// activated abilities from objects in the command zone (emblems or commanders)
if (fromAll || fromZone == Zone.COMMAND) {
for (CommandObject commandObject : game.getState().getCommand()) {
List<ActivatedAbility> currentPlayable = new ArrayList<>();
getPlayableFromObjectAll(game, Zone.COMMAND, commandObject, availableMana, currentPlayable);
for (ActivatedAbility ability : currentPlayable) {
activatedUnique.put(ability.toString(), ability);
activatedAll.add(ability);
}
}
}
if (hideDuplicatedAbilities) {
playable.addAll(activatedUnique.values());
} else {
playable.addAll(activatedAll);
}
} finally {
game.setCheckPlayableState(previousState);
}
return playable;
}
Aggregations