use of mage.MageObject in project mage by magefree.
the class HumanPlayer method chooseTargetAmount.
@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
// human can choose or un-choose MULTIPLE targets at once
if (gameInCheckPlayableState(game)) {
return true;
}
UUID abilityControllerId = playerId;
if (target.getAbilityController() != null) {
abilityControllerId = target.getAbilityController();
}
int amountTotal = target.getAmountTotal(game, source);
// 1. Select targets
while (canRespond()) {
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
if (possibleTargets.isEmpty() || target.getSize() >= target.getNumberOfTargets()) {
required = false;
}
// selected
Map<String, Serializable> options = getOptions(target, null);
java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
// selectable
java.util.List<UUID> choosable = new ArrayList<>();
for (UUID targetId : possibleTargets) {
if (target.canTarget(abilityControllerId, targetId, source, game)) {
choosable.add(targetId);
}
}
if (!choosable.isEmpty()) {
options.put("choosable", (Serializable) choosable);
}
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
if (required && choosable.isEmpty()) {
required = false;
}
updateGameStatePriority("chooseTargetAmount", game);
prepareForResponse(game);
if (!isExecutingMacro()) {
// target amount uses for damage only, if you see another use case then message must be changed here and on getMultiAmount call
String message = String.format("Select targets to distribute %d damage (selected %d)", amountTotal, target.getTargets().size());
game.fireSelectTargetEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), possibleTargets, required, options);
}
waitForResponse(game);
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
if (target.contains(responseId)) {
// unselect
target.remove(responseId);
} else if (possibleTargets.contains(responseId) && target.canTarget(abilityControllerId, responseId, source, game)) {
// select
target.addTarget(responseId, source, game);
}
} else if (!required) {
break;
}
}
// no targets to choose or disconnected
List<UUID> targets = target.getTargets();
if (targets.isEmpty()) {
return false;
}
// 2. Distribute amount between selected targets
// prepare targets list with p/t or life stats (cause that's dialog used for damage distribute)
List<String> targetNames = new ArrayList<>();
for (UUID targetId : targets) {
MageObject targetObject = game.getObject(targetId);
if (targetObject != null) {
targetNames.add(String.format("%s, P/T: %d/%d", targetObject.getIdName(), targetObject.getPower().getValue(), targetObject.getToughness().getValue()));
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
targetNames.add(String.format("%s, life: %d", player.getName(), player.getLife()));
} else {
targetNames.add("ERROR, unknown target " + targetId.toString());
}
}
}
// ask and assign new amount
List<Integer> targetValues = getMultiAmount(outcome, targetNames, 1, amountTotal, MultiAmountType.DAMAGE, game);
for (int i = 0; i < targetValues.size(); i++) {
int newAmount = targetValues.get(i);
UUID targetId = targets.get(i);
if (newAmount <= 0) {
// remove target
target.remove(targetId);
} else {
// set amount
target.setTargetAmount(targetId, newAmount, source, game);
}
}
return true;
}
use of mage.MageObject in project mage by magefree.
the class HumanPlayer method chooseTriggeredAbility.
@Override
public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
// choose triggered abilitity from list
if (gameInCheckPlayableState(game)) {
return null;
}
String autoOrderRuleText = null;
boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
while (canRespond()) {
// try to set trigger auto order
java.util.List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
TriggeredAbility abilityOrderLast = null;
for (TriggeredAbility ability : abilities) {
if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
return ability;
}
MageObject object = game.getObject(ability.getSourceId());
String rule = ability.getRule(object != null ? object.getName() : null);
if (triggerAutoOrderNameFirst.contains(rule)) {
return ability;
}
if (triggerAutoOrderAbilityLast.contains(ability.getOriginalId())) {
abilityOrderLast = ability;
continue;
}
if (triggerAutoOrderNameLast.contains(rule)) {
abilityOrderLast = ability;
continue;
}
if (autoOrderUse) {
if (autoOrderRuleText == null) {
autoOrderRuleText = rule;
} else if (!rule.equals(autoOrderRuleText)) {
autoOrderUse = false;
}
}
abilitiesWithNoOrderSet.add(ability);
}
if (abilitiesWithNoOrderSet.isEmpty()) {
return abilityOrderLast;
}
if (abilitiesWithNoOrderSet.size() == 1 || autoOrderUse) {
return abilitiesWithNoOrderSet.iterator().next();
}
macroTriggeredSelectionFlag = true;
updateGameStatePriority("chooseTriggeredAbility", game);
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetTriggeredAbilityEvent(playerId, "Pick triggered ability (goes to the stack first)", abilitiesWithNoOrderSet);
}
waitForResponse(game);
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
for (TriggeredAbility ability : abilitiesWithNoOrderSet) {
if (ability.getId().equals(responseId) || (!macroTriggeredSelectionFlag && ability.getSourceId().equals(responseId))) {
if (recordingMacro) {
PlayerResponse tResponse = new PlayerResponse();
tResponse.setUUID(ability.getSourceId());
actionQueueSaved.add(tResponse);
logger.debug("Adding Triggered Ability Source: " + tResponse);
}
macroTriggeredSelectionFlag = false;
return ability;
}
}
}
}
macroTriggeredSelectionFlag = false;
return null;
}
use of mage.MageObject in project mage by magefree.
the class ComputerPlayer method logList.
protected void logList(String message, List<MageObject> list) {
StringBuilder sb = new StringBuilder();
sb.append(message).append(": ");
for (MageObject object : list) {
sb.append(object.getName()).append(',');
}
log.info(sb.toString());
}
use of mage.MageObject in project mage by magefree.
the class BeaconOfDestinyEffect method applies.
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
// check source
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
}
if (!object.getId().equals(damageSource.getFirstTarget()) && (!(object instanceof Spell) || !((Spell) object).getSourceId().equals(damageSource.getFirstTarget()))) {
return false;
}
TargetPermanent target = new TargetPermanent();
target.add(source.getSourceId(), game);
this.redirectTarget = target;
// check player
Player player = game.getPlayer(event.getTargetId());
if (player != null) {
if (player.getId().equals(source.getControllerId())) {
return true;
}
}
return false;
}
use of mage.MageObject in project mage by magefree.
the class BorderlandExplorerEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
// Store for each player the cards to discard, that's important because all discard shall happen at the same time
Map<UUID, Cards> cardsToDiscard = new HashMap<>();
// Store for each player the lands to reveal, that's important because all reveals shall happen at the same time
Map<UUID, Cards> cardsToReveal = new HashMap<>();
// choose cards to discard
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Target target = new TargetDiscard(0, 1, new FilterCard(), playerId);
player.chooseTarget(outcome, target, source, game);
Cards cards = new CardsImpl(target.getTargets());
cardsToDiscard.put(playerId, cards);
}
}
// discard all chosen cards
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Cards cardsPlayer = cardsToDiscard.get(playerId);
if (cardsPlayer != null) {
for (UUID cardId : cardsPlayer) {
Card card = game.getCard(cardId);
player.discard(card, false, source, game);
}
}
}
}
// search for a land for each player that discarded
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Cards cardsPlayer = cardsToDiscard.get(playerId);
if (cardsPlayer != null && !cardsPlayer.isEmpty()) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND);
if (player.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
Cards cards = new CardsImpl(target.getTargets());
cards.addAll(target.getTargets());
cardsToReveal.put(playerId, cards);
}
}
}
}
}
// reveal the searched lands, put in hands, and shuffle
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Cards cardsPlayer = cardsToReveal.get(playerId);
if (cardsPlayer != null) {
for (UUID cardId : cardsPlayer) {
Card card = game.getCard(cardId);
Cards cards = new CardsImpl(game.getCard(cardId));
if (card != null && !cards.isEmpty()) {
player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ')', cards, game);
player.moveCards(card, Zone.HAND, source, game);
player.shuffleLibrary(source, game);
}
}
}
}
}
return true;
}
return false;
}
Aggregations