use of mage.game.GameImpl in project mage by magefree.
the class KarnPlayerExileEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject == null) {
return false;
}
List<Card> cards = new ArrayList<>();
for (ExileZone zone : game.getExile().getExileZones()) {
exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (zone.getId().equals(exileId)) {
for (Card card : zone.getCards(game)) {
if (!card.hasSubtype(SubType.AURA, game) && card.isPermanent(game)) {
cards.add(card);
}
}
}
}
// dirty hack for game restart, can cause bugs due strange clear code (some data like ZCC keeping on new game)
// see testCommanderRestoredToBattlefieldAfterKarnUltimate for more details
game.getState().clearOnGameRestart();
// default watchers init, TODO: remove all restart/init code to game
((GameImpl) game).initGameDefaultWatchers();
for (Card card : game.getCards()) {
game.getState().addCard(card);
}
for (Player player : game.getPlayers().values()) {
if (player.canRespond()) {
// only players alive are in the restarted game
player.getGraveyard().clear();
player.getHand().clear();
player.getLibrary().clear();
for (Card card : game.getCards()) {
if (// no copies
card.isOwnedBy(player.getId()) && !card.isCopy() && !player.getSideboard().contains(card.getId()) && !cards.contains(card)) {
// not the exiled cards
if (game.getCommandersIds(player, CommanderCardType.ANY, false).contains(card.getId())) {
// TODO: check restart and init
game.addCommander(new Commander(card));
// no needs in initCommander call -- it's used on game startup (init)
game.setZone(card.getId(), Zone.COMMAND);
} else {
player.getLibrary().putOnTop(card, game);
}
}
}
((GameImpl) game).initPlayerDefaultWatchers(player.getId());
player.init(game);
}
}
for (Card card : cards) {
game.getState().setZone(card.getId(), Zone.EXILED);
game.getExile().add(exileId, sourceObject.getIdName(), card);
}
game.addDelayedTriggeredAbility(new KarnLiberatedDelayedTriggeredAbility(exileId), source);
game.setStartingPlayerId(source.getControllerId());
game.start(null);
return true;
}
use of mage.game.GameImpl in project mage by magefree.
the class TestPlayer method priority.
@Override
public boolean priority(Game game) {
// later remove actions (ai commands related)
if (actionsToRemoveLater.size() > 0) {
List<PlayerAction> removed = new ArrayList<>();
actionsToRemoveLater.forEach((action, step) -> {
if (game.getStep().getType() != step) {
action.onActionRemovedLater(game, this);
actions.remove(action);
removed.add(action);
}
});
removed.forEach(actionsToRemoveLater::remove);
}
// fake test ability for triggers and events
Ability source = new SimpleStaticAbility(Zone.OUTSIDE, new InfoEffect("adding testing cards"));
source.setControllerId(this.getId());
int numberOfActions = actions.size();
List<PlayerAction> tempActions = new ArrayList<>();
tempActions.addAll(actions);
for (PlayerAction action : tempActions) {
if (action.getTurnNum() == game.getTurnNum() && action.getStep() == game.getStep().getType()) {
if (action.getAction().startsWith(ACTIVATE_ABILITY)) {
String command = action.getAction();
command = command.substring(command.indexOf(ACTIVATE_ABILITY) + ACTIVATE_ABILITY.length());
groupsForTargetHandling = null;
String[] groups = command.split("\\$");
if (groups.length > 2 && !checkExecuteCondition(groups, game)) {
break;
}
// must process all duplicated abilities (aliases need objects to search)
for (ActivatedAbility ability : computerPlayer.getPlayable(game, true, Zone.ALL, false)) {
// add wrong action log?
if (hasAbilityTargetNameOrAlias(game, ability, groups[0])) {
int bookmark = game.bookmarkState();
ActivatedAbility newAbility = ability.copy();
if (groups.length > 1 && !groups[1].equals("target=" + NO_TARGET)) {
groupsForTargetHandling = groups;
}
if (computerPlayer.activateAbility(newAbility, game)) {
actions.remove(action);
groupsForTargetHandling = null;
// Reset enless loop check because of no action
foundNoAction = 0;
return true;
} else {
computerPlayer.restoreState(bookmark, ability.getRule(), game);
// skip failed command
if (!choices.isEmpty() && choices.get(0).equals(SKIP_FAILED_COMMAND)) {
actions.remove(action);
choices.remove(0);
return true;
}
}
groupsForTargetHandling = null;
}
}
// TODO: fix wrong commands (on non existing card), it's HUGE (350+ failed tests with wrong commands)
// Assert.fail("Can't find ability to activate command: " + command);
} else if (action.getAction().startsWith(ACTIVATE_MANA)) {
String command = action.getAction();
command = command.substring(command.indexOf(ACTIVATE_MANA) + ACTIVATE_MANA.length());
String[] groups = command.split("\\$");
List<MageObject> manaObjects = computerPlayer.getAvailableManaProducers(game);
for (MageObject mageObject : manaObjects) {
if (mageObject instanceof Permanent) {
for (Ability manaAbility : ((Permanent) mageObject).getAbilities(game).getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, getId(), game)) {
if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
Ability newManaAbility = manaAbility.copy();
computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
actions.remove(action);
return true;
}
}
} else if (mageObject instanceof Card) {
for (Ability manaAbility : ((Card) mageObject).getAbilities(game).getAvailableActivatedManaAbilities(game.getState().getZone(mageObject.getId()), getId(), game)) {
if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
Ability newManaAbility = manaAbility.copy();
computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
actions.remove(action);
return true;
}
}
} else {
for (Ability manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(game.getState().getZone(mageObject.getId()), getId(), game)) {
if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
Ability newManaAbility = manaAbility.copy();
computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
actions.remove(action);
return true;
}
}
}
}
List<Permanent> manaPermsWithCost = computerPlayer.getAvailableManaProducersWithCost(game);
for (Permanent perm : manaPermsWithCost) {
for (ActivatedManaAbilityImpl manaAbility : perm.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, getId(), game)) {
if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game).canActivate()) {
Ability newManaAbility = manaAbility.copy();
computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
actions.remove(action);
return true;
}
}
}
} else if (action.getAction().startsWith("addCounters:")) {
String command = action.getAction();
command = command.substring(command.indexOf("addCounters:") + 12);
String[] groups = command.split("\\$");
for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
if (hasObjectTargetNameOrAlias(permanent, groups[0])) {
CounterType counterType = CounterType.findByName(groups[1]);
Assert.assertNotNull("Invalid counter type " + groups[1], counterType);
Counter counter = counterType.createInstance(Integer.parseInt(groups[2]));
permanent.addCounters(counter, source.getControllerId(), source, game);
actions.remove(action);
return true;
}
}
} else if (action.getAction().startsWith("waitStackResolved")) {
boolean skipOneStackObjectOnly = action.getAction().equals("waitStackResolved:1");
if (game.getStack().isEmpty()) {
// all done, can use next command
actions.remove(action);
continue;
} else {
// need to wait (don't remove command, except one skip only)
tryToPlayPriority(game);
if (skipOneStackObjectOnly) {
actions.remove(action);
}
return true;
}
} else if (action.getAction().startsWith("playerAction:")) {
String command = action.getAction();
command = command.substring(command.indexOf("playerAction:") + 13);
groupsForTargetHandling = null;
String[] groups = command.split("\\$");
if (groups.length > 0) {
if (groups[0].equals("Rollback")) {
if (groups.length > 2 && groups[1].startsWith("turns=") && groups[2].startsWith("rollbackBlock=")) {
int turns = Integer.parseInt(groups[1].substring(6));
int rollbackBlockNumber = Integer.parseInt(groups[2].substring(14));
game.rollbackTurns(turns);
actions.remove(action);
addActionsAfterRollback(game, rollbackBlockNumber);
return true;
} else {
Assert.fail("Rollback command misses parameter: " + command);
}
}
if (groups[0].equals("Concede")) {
game.concede(getId());
((GameImpl) game).checkConcede();
actions.remove(action);
return true;
}
}
} else if (action.getAction().startsWith(AI_PREFIX)) {
String command = action.getAction();
command = command.substring(command.indexOf(AI_PREFIX) + AI_PREFIX.length());
// play priority
if (command.equals(AI_COMMAND_PLAY_PRIORITY)) {
// disable on action's remove
AIRealGameSimulation = true;
computerPlayer.priority(game);
actions.remove(action);
return true;
}
// play step
if (command.equals(AI_COMMAND_PLAY_STEP)) {
// disable on action's remove
AIRealGameSimulation = true;
actionsToRemoveLater.put(action, game.getStep().getType());
computerPlayer.priority(game);
return true;
}
Assert.fail("Unknown ai command: " + command);
} else if (action.getAction().startsWith(RUN_PREFIX)) {
String command = action.getAction();
command = command.substring(command.indexOf(RUN_PREFIX) + RUN_PREFIX.length());
// custom code execute
if (command.equals(RUN_COMMAND_CODE)) {
action.getCodePayload().run(action.getActionName(), computerPlayer, game);
actions.remove(action);
return true;
}
Assert.fail("Unknown run command: " + command);
} else if (action.getAction().startsWith(CHECK_PREFIX)) {
String command = action.getAction();
command = command.substring(command.indexOf(CHECK_PREFIX) + CHECK_PREFIX.length());
String[] params = command.split(CHECK_PARAM_DELIMETER);
boolean wasProccessed = false;
if (params.length > 0) {
// check PT: card name, P, T
if (params[0].equals(CHECK_COMMAND_PT) && params.length == 4) {
assertPT(action, game, computerPlayer, params[1], Integer.parseInt(params[2]), Integer.parseInt(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check damage: card name, damage
if (params[0].equals(CHECK_COMMAND_DAMAGE) && params.length == 3) {
assertDamage(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check life: life
if (params[0].equals(CHECK_COMMAND_LIFE) && params.length == 2) {
assertLife(action, game, computerPlayer, Integer.parseInt(params[1]));
actions.remove(action);
wasProccessed = true;
}
// check player in game: target player, must be in game
if (params[0].equals(CHECK_COMMAND_PLAYER_IN_GAME) && params.length == 3) {
assertPlayerInGame(action, game, game.getPlayer(UUID.fromString(params[1])), Boolean.parseBoolean(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check ability: card name, ability class, must have
if (params[0].equals(CHECK_COMMAND_ABILITY) && params.length == 4) {
assertAbility(action, game, computerPlayer, params[1], params[2], Boolean.parseBoolean(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check playable ability: ability text, must have
if (params[0].equals(CHECK_COMMAND_PLAYABLE_ABILITY) && params.length == 3) {
assertPlayableAbility(action, game, computerPlayer, params[1], Boolean.parseBoolean(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check battlefield count: target player, card name, count
if (params[0].equals(CHECK_COMMAND_PERMANENT_COUNT) && params.length == 4) {
assertPermanentCount(action, game, game.getPlayer(UUID.fromString(params[1])), params[2], Integer.parseInt(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check permanent tapped count: target player, card name, tapped status, count
if (params[0].equals(CHECK_COMMAND_PERMANENT_TAPPED) && params.length == 5) {
assertPermanentTapped(action, game, game.getPlayer(UUID.fromString(params[1])), params[2], Boolean.parseBoolean(params[3]), Integer.parseInt(params[4]));
actions.remove(action);
wasProccessed = true;
}
// check permanent counters: card name, counter type, count
if (params[0].equals(CHECK_COMMAND_PERMANENT_COUNTERS) && params.length == 4) {
assertPermanentCounters(action, game, computerPlayer, params[1], CounterType.findByName(params[2]), Integer.parseInt(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check card counters: card name, counter type, count
if (params[0].equals(CHECK_COMMAND_CARD_COUNTERS) && params.length == 4) {
assertCardCounters(action, game, computerPlayer, params[1], CounterType.findByName(params[2]), Integer.parseInt(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check exile count: card name, count
if (params[0].equals(CHECK_COMMAND_EXILE_COUNT) && params.length == 3) {
assertExileCount(action, game, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check graveyard count: card name, count
if (params[0].equals(CHECK_COMMAND_GRAVEYARD_COUNT) && params.length == 3) {
assertGraveyardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check library count: card name, count
if (params[0].equals(CHECK_COMMAND_LIBRARY_COUNT) && params.length == 3) {
assertLibraryCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check hand count: count
if (params[0].equals(CHECK_COMMAND_HAND_COUNT) && params.length == 2) {
assertHandCount(action, game, computerPlayer, Integer.parseInt(params[1]));
actions.remove(action);
wasProccessed = true;
}
// check hand card count: card name, count
if (params[0].equals(CHECK_COMMAND_HAND_CARD_COUNT) && params.length == 3) {
assertHandCardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check command card count: card name, count
if (params[0].equals(CHECK_COMMAND_COMMAND_CARD_COUNT) && params.length == 3) {
assertCommandCardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check color: card name, colors, must have
if (params[0].equals(CHECK_COMMAND_COLOR) && params.length == 4) {
assertColor(action, game, computerPlayer, params[1], params[2], Boolean.parseBoolean(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check type: card name, type, must have
if (params[0].equals(CHECK_COMMAND_TYPE) && params.length == 4) {
assertType(action, game, computerPlayer, params[1], CardType.fromString(params[2]), Boolean.parseBoolean(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check subtype: card name, subtype, must have
if (params[0].equals(CHECK_COMMAND_SUBTYPE) && params.length == 4) {
assertSubType(action, game, computerPlayer, params[1], SubType.fromString(params[2]), Boolean.parseBoolean(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check mana pool: colors, amount
if (params[0].equals(CHECK_COMMAND_MANA_POOL) && params.length == 3) {
assertManaPool(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
// check alias at zone: alias name, zone, must have (only for TestPlayer)
if (params[0].equals(CHECK_COMMAND_ALIAS_ZONE) && params.length == 4) {
assertAliasZone(action, game, this, params[1], Zone.valueOf(params[2]), Boolean.parseBoolean(params[3]));
actions.remove(action);
wasProccessed = true;
}
// check stack size: need size
if (params[0].equals(CHECK_COMMAND_STACK_SIZE) && params.length == 2) {
assertStackSize(action, game, Integer.parseInt(params[1]));
actions.remove(action);
wasProccessed = true;
}
// check stack object: stack ability name, amount
if (params[0].equals(CHECK_COMMAND_STACK_OBJECT) && params.length == 3) {
assertStackObject(action, game, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
}
if (wasProccessed) {
return true;
} else {
Assert.fail("Unknown check command or params: " + command);
}
} else if (action.getAction().startsWith(SHOW_PREFIX)) {
String command = action.getAction();
command = command.substring(command.indexOf(SHOW_PREFIX) + SHOW_PREFIX.length());
String[] params = command.split(CHECK_PARAM_DELIMETER);
boolean wasProccessed = false;
if (params.length > 0) {
// show library
if (params[0].equals(SHOW_COMMAND_LIBRARY) && params.length == 1) {
printStart(action.getActionName());
// do not sort
printCards(computerPlayer.getLibrary().getCards(game), false);
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show hand
if (params[0].equals(SHOW_COMMAND_HAND) && params.length == 1) {
printStart(action.getActionName());
printCards(computerPlayer.getHand().getCards(game));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show command
if (params[0].equals(SHOW_COMMAND_COMMAND) && params.length == 1) {
printStart(action.getActionName());
CardsImpl cards = new CardsImpl(game.getCommandersIds(computerPlayer, CommanderCardType.ANY, false));
printCards(cards.getCards(game));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show battlefield
if (params[0].equals(SHOW_COMMAND_BATTLEFIELD) && params.length == 1) {
printStart(action.getActionName());
printPermanents(game, game.getBattlefield().getAllActivePermanents(computerPlayer.getId()));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show graveyard
if (params[0].equals(SHOW_COMMAND_GRAVEYEARD) && params.length == 1) {
printStart(action.getActionName());
printCards(computerPlayer.getGraveyard().getCards(game));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show exile
if (params[0].equals(SHOW_COMMAND_EXILE) && params.length == 1) {
printStart(action.getActionName());
printCards(game.getExile().getAllCards(game).stream().filter(card -> card.isOwnedBy(computerPlayer.getId())).collect(Collectors.toList()), true);
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show available abilities
if (params[0].equals(SHOW_COMMAND_AVAILABLE_ABILITIES) && params.length == 1) {
printStart(action.getActionName());
printAbilities(game, computerPlayer.getPlayable(game, true));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show available mana
if (params[0].equals(SHOW_COMMAND_AVAILABLE_MANA) && params.length == 1) {
printStart(action.getActionName());
printMana(game, computerPlayer.getManaAvailable(game));
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show aliases
if (params[0].equals(SHOW_COMMAND_ALIASES) && params.length == 1) {
printStart(action.getActionName());
printAliases(game, this);
printEnd();
actions.remove(action);
wasProccessed = true;
}
// show stack
if (params[0].equals(SHOW_COMMAND_STACK) && params.length == 1) {
printStart(action.getActionName());
printStack(game);
printEnd();
actions.remove(action);
wasProccessed = true;
}
}
if (wasProccessed) {
return true;
} else {
Assert.fail("Unknown show command or params: " + command);
}
}
// you don't need to use stack command all the time, so some cast commands can be skiped to next check
if (game.getStack().isEmpty()) {
this.chooseStrictModeFailed("cast/activate", game, "Can't find available command - " + action.getAction() + " (use checkPlayableAbility for \"non available\" checks)", true);
}
}
// turn/step
}
tryToPlayPriority(game);
// check to prevent endless loops
if (numberOfActions == actions.size()) {
foundNoAction++;
if (foundNoAction > maxCallsWithoutAction) {
throw new AssertionError("Too much priority calls to " + getName() + " without taking any action than allowed (" + maxCallsWithoutAction + ") on turn " + game.getTurnNum());
}
} else {
foundNoAction = 0;
}
return false;
}
Aggregations