forked from External/mage
GUI: improved choose creature type dialog - important creature types added to the start of the list and marked as my/opponent (closes #8478)
This commit is contained in:
parent
7b2e9b390c
commit
a974af3c61
41 changed files with 239 additions and 138 deletions
|
|
@ -36,14 +36,14 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
|
|||
mageObject = game.getObject(source);
|
||||
}
|
||||
if (controller != null && mageObject != null) {
|
||||
Choice typeChoice = new ChoiceCreatureType(mageObject);
|
||||
Choice typeChoice = new ChoiceCreatureType(game, source);
|
||||
if (controller.choose(outcome, typeChoice, game)) {
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
|
||||
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoiceKey());
|
||||
}
|
||||
game.getState().setValue(source.getSourceId() + "_type", SubType.byDescription(typeChoice.getChoice()));
|
||||
game.getState().setValue(source.getSourceId() + "_type", SubType.byDescription(typeChoice.getChoiceKey()));
|
||||
if (mageObject instanceof Permanent) {
|
||||
((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game);
|
||||
((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoiceKey()), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,22 +50,22 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect {
|
|||
Card card = game.getCard(source.getSourceId());
|
||||
String chosenType = "";
|
||||
if (player != null && card != null) {
|
||||
Choice typeChoice = new ChoiceCreatureType();
|
||||
Choice typeChoice = new ChoiceCreatureType(game, source);
|
||||
String msg = "Choose a creature type";
|
||||
if (nonWall) {
|
||||
msg += " other than Wall";
|
||||
}
|
||||
typeChoice.setMessage(msg);
|
||||
if (nonWall) {
|
||||
typeChoice.getChoices().remove(SubType.WALL.getDescription());
|
||||
typeChoice.getKeyChoices().remove(SubType.WALL.getDescription());
|
||||
}
|
||||
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
|
||||
if (!player.canRespond()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
game.informPlayers(card.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice());
|
||||
chosenType = typeChoice.getChoice();
|
||||
game.informPlayers(card.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoiceKey());
|
||||
chosenType = typeChoice.getChoiceKey();
|
||||
if (chosenType != null && !chosenType.isEmpty()) {
|
||||
// ADD TYPE TO TARGET
|
||||
ContinuousEffect effect = new BecomesCreatureTypeTargetEffect(duration, SubType.byDescription(chosenType));
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
package mage.choices;
|
||||
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.Copyable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
|
|
@ -107,4 +110,11 @@ public interface Choice extends Serializable, Copyable<Choice> {
|
|||
void setRandomChoice();
|
||||
|
||||
boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList);
|
||||
|
||||
/**
|
||||
* Run additional code before player start to choose (example: add info and hints for choosing player)
|
||||
*/
|
||||
void onChooseStart(Game game, UUID choosingPlayerId);
|
||||
|
||||
void onChooseEnd(Game game, UUID choosingPlayerId, String choiceResult);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,39 @@
|
|||
package mage.choices;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Game's choose dialog to ask about creature type. Return getChoice
|
||||
*/
|
||||
public class ChoiceCreatureType extends ChoiceImpl {
|
||||
|
||||
private static final String DEFAULT_MESSAGE = "Choose a creature type";
|
||||
|
||||
public ChoiceCreatureType() {
|
||||
this(true, DEFAULT_MESSAGE, null);
|
||||
public ChoiceCreatureType(Game game, Ability source) {
|
||||
this(game, source, true, DEFAULT_MESSAGE);
|
||||
}
|
||||
|
||||
public ChoiceCreatureType(MageObject source) {
|
||||
this(true, DEFAULT_MESSAGE, source);
|
||||
}
|
||||
|
||||
public ChoiceCreatureType(String chooseMessage, MageObject source) {
|
||||
this(true, chooseMessage, source);
|
||||
}
|
||||
|
||||
public ChoiceCreatureType(boolean required, String chooseMessage, MageObject source) {
|
||||
public ChoiceCreatureType(Game game, Ability source, boolean required, String chooseMessage) {
|
||||
super(required);
|
||||
this.setChoices(SubType.getCreatureTypes().stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
this.setMessage(chooseMessage);
|
||||
if (source != null) {
|
||||
this.setSubMessage(source.getIdName());
|
||||
MageObject sourceObject = source == null ? null : game.getObject(source);
|
||||
if (sourceObject != null) {
|
||||
this.setSubMessage(sourceObject.getLogName());
|
||||
}
|
||||
this.setSearchEnabled(true);
|
||||
this.setSearchEnabled(true);
|
||||
|
||||
// collect basic info
|
||||
// additional info will be added onChooseStart
|
||||
SubType.getCreatureTypes().stream().map(SubType::toString).forEach(value -> {
|
||||
this.withItem(value, value, null, null, null);
|
||||
});
|
||||
}
|
||||
|
||||
protected ChoiceCreatureType(final ChoiceCreatureType choice) {
|
||||
|
|
@ -40,4 +44,71 @@ public class ChoiceCreatureType extends ChoiceImpl {
|
|||
public ChoiceCreatureType copy() {
|
||||
return new ChoiceCreatureType(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChooseStart(Game game, UUID choosingPlayerId) {
|
||||
// add additional info about important creature types (collect it from all public zone and own hand)
|
||||
Set<String> myTypes = new HashSet<>();
|
||||
Set<String> opponentTypes = new HashSet<>();
|
||||
|
||||
game.getState().getPlayersInRange(choosingPlayerId, game).forEach(playerId -> {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> list = playerId.equals(choosingPlayerId) ? myTypes : opponentTypes;
|
||||
|
||||
// own hand
|
||||
if (playerId.equals(choosingPlayerId)) {
|
||||
player.getHand().getCards(game).forEach(card -> {
|
||||
list.addAll(card.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
});
|
||||
}
|
||||
|
||||
// battlefield
|
||||
game.getBattlefield().getAllActivePermanents(playerId).forEach(permanent -> {
|
||||
list.addAll(permanent.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
});
|
||||
|
||||
// graveyard
|
||||
player.getGraveyard().getCards(game).forEach(card -> {
|
||||
list.addAll(card.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
});
|
||||
|
||||
// exile
|
||||
game.getExile().getAllCards(game, playerId).forEach(card -> {
|
||||
list.addAll(card.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
});
|
||||
});
|
||||
|
||||
// stack
|
||||
game.getStack().forEach(stackObject -> {
|
||||
if (stackObject.isControlledBy(choosingPlayerId)) {
|
||||
myTypes.addAll(stackObject.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
} else {
|
||||
opponentTypes.addAll(stackObject.getSubtype(game).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
}
|
||||
});
|
||||
|
||||
// sort order: me -> opponent -> not used
|
||||
this.keyChoices.forEach((key, value) -> {
|
||||
String additionalInfo = "";
|
||||
Integer orderPriority = 0;
|
||||
if (myTypes.contains(key)) {
|
||||
additionalInfo += "me";
|
||||
orderPriority -= 100;
|
||||
}
|
||||
if (opponentTypes.contains(key)) {
|
||||
if (!additionalInfo.isEmpty()) {
|
||||
additionalInfo += ", ";
|
||||
}
|
||||
additionalInfo += "opponent";
|
||||
orderPriority -= 10;
|
||||
}
|
||||
|
||||
this.keyChoices.put(key, key + (additionalInfo.isEmpty() ? "" : " (" + additionalInfo + ")"));
|
||||
this.sortData.put(key, orderPriority);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package mage.choices;
|
||||
|
||||
import mage.game.Game;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.RandomUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
|
|
@ -400,4 +401,14 @@ public class ChoiceImpl implements Choice {
|
|||
logger.error("Empty choice dialog in " + this.getClass().getCanonicalName(), new Throwable());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChooseStart(Game game, UUID choosingPlayerId) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChooseEnd(Game game, UUID choosingPlayerId, String choiceResult) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import mage.players.Player;
|
|||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
|
|
@ -101,39 +100,43 @@ class VolosJournalTokenEffect extends OneShotEffect {
|
|||
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> types = VolosJournalToken.getNotedTypes(game, permanent);
|
||||
Set<String> notedTypes = VolosJournalToken.getNotedTypes(game, permanent);
|
||||
|
||||
ChoiceCreatureType choice = new ChoiceCreatureType();
|
||||
ChoiceCreatureType choice = new ChoiceCreatureType(game, source);
|
||||
|
||||
// By default ChoiceCreatureType pre-populates all creatures into choices
|
||||
// Limit the available choices to those on the creature being cast
|
||||
if (!spell.isAllCreatureTypes(game)) {
|
||||
choice.setChoices(
|
||||
spell.getSubtype(game)
|
||||
.stream()
|
||||
.filter(subType -> subType.getSubTypeSet() == SubTypeSet.CreatureType)
|
||||
.map(SubType::getDescription)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
choice.getKeyChoices().clear();
|
||||
spell.getSubtype(game)
|
||||
.stream()
|
||||
.filter(subType -> subType.getSubTypeSet() == SubTypeSet.CreatureType)
|
||||
.map(SubType::getDescription)
|
||||
.forEach(subType -> {
|
||||
choice.withItem(subType, subType, null, null, null);
|
||||
});
|
||||
}
|
||||
// Remove from the possible choices the subtypes which have already been chosen.
|
||||
choice.getChoices().removeIf(types::contains);
|
||||
choice.getKeyChoices().keySet().removeIf(notedTypes::contains);
|
||||
|
||||
switch (choice.getChoices().size()) {
|
||||
switch (choice.getKeyChoices().size()) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
types.add(choice.getChoices().stream().findFirst().get());
|
||||
notedTypes.add(choice.getKeyChoices().keySet().stream().findFirst().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
player.choose(outcome, choice, game);
|
||||
types.add(choice.getChoice());
|
||||
notedTypes.add(choice.getChoiceKey());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue