mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
cheats: added 2 new special commands (add card to hand, add lands to battlefield), added default special commands (no needs to put it in init.txt)
This commit is contained in:
parent
81d44e615f
commit
46911a82bb
2 changed files with 169 additions and 59 deletions
|
|
@ -13,11 +13,9 @@ import mage.cards.repository.CardCriteria;
|
||||||
import mage.cards.repository.CardInfo;
|
import mage.cards.repository.CardInfo;
|
||||||
import mage.cards.repository.CardRepository;
|
import mage.cards.repository.CardRepository;
|
||||||
import mage.choices.Choice;
|
import mage.choices.Choice;
|
||||||
|
import mage.choices.ChoiceHintType;
|
||||||
import mage.choices.ChoiceImpl;
|
import mage.choices.ChoiceImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.*;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Planes;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.GameCommanderImpl;
|
import mage.game.GameCommanderImpl;
|
||||||
|
|
@ -27,6 +25,7 @@ import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.Token;
|
import mage.game.permanent.token.Token;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
import mage.util.MultiAmountMessage;
|
||||||
import mage.util.RandomUtil;
|
import mage.util.RandomUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -60,12 +59,14 @@ public final class SystemUtil {
|
||||||
// [another group]
|
// [another group]
|
||||||
// command 2
|
// command 2
|
||||||
// command 3
|
// command 3
|
||||||
|
// [@special build-in command]
|
||||||
private static final String COMMAND_REF_PREFIX = "@";
|
private static final String COMMAND_REF_PREFIX = "@";
|
||||||
|
|
||||||
// transform special group names from init.txt to special commands in choose dialog:
|
// transform special group names from init.txt to special commands in choose dialog:
|
||||||
// [@mana add] -> MANA ADD
|
// [@mana add] -> MANA ADD
|
||||||
|
private static final String COMMAND_CARDS_ADD_TO_HAND = "@card add to hand";
|
||||||
|
private static final String COMMAND_LANDS_ADD_TO_BATTLEFIELD = "@lands add";
|
||||||
private static final String COMMAND_MANA_ADD = "@mana add"; // TODO: not implemented
|
private static final String COMMAND_MANA_ADD = "@mana add"; // TODO: not implemented
|
||||||
private static final String COMMAND_LANDS_ADD = "@lands add"; // TODO: not implemented
|
|
||||||
private static final String COMMAND_RUN_CUSTOM_CODE = "@run custom code"; // TODO: not implemented
|
private static final String COMMAND_RUN_CUSTOM_CODE = "@run custom code"; // TODO: not implemented
|
||||||
private static final String COMMAND_SHOW_OPPONENT_HAND = "@show opponent hand";
|
private static final String COMMAND_SHOW_OPPONENT_HAND = "@show opponent hand";
|
||||||
private static final String COMMAND_SHOW_OPPONENT_LIBRARY = "@show opponent library";
|
private static final String COMMAND_SHOW_OPPONENT_LIBRARY = "@show opponent library";
|
||||||
|
|
@ -76,8 +77,9 @@ public final class SystemUtil {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// special commands names in choose dialog
|
// special commands names in choose dialog
|
||||||
|
supportedCommands.put(COMMAND_CARDS_ADD_TO_HAND, "CARDS: ADD TO HAND");
|
||||||
supportedCommands.put(COMMAND_MANA_ADD, "MANA ADD");
|
supportedCommands.put(COMMAND_MANA_ADD, "MANA ADD");
|
||||||
supportedCommands.put(COMMAND_LANDS_ADD, "LANDS ADD");
|
supportedCommands.put(COMMAND_LANDS_ADD_TO_BATTLEFIELD, "LANDS: ADD TO BATTLEFIELD");
|
||||||
supportedCommands.put(COMMAND_RUN_CUSTOM_CODE, "RUN CUSTOM CODE");
|
supportedCommands.put(COMMAND_RUN_CUSTOM_CODE, "RUN CUSTOM CODE");
|
||||||
supportedCommands.put(COMMAND_SHOW_OPPONENT_HAND, "SHOW OPPONENT HAND");
|
supportedCommands.put(COMMAND_SHOW_OPPONENT_HAND, "SHOW OPPONENT HAND");
|
||||||
supportedCommands.put(COMMAND_SHOW_OPPONENT_LIBRARY, "SHOW OPPONENT LIBRARY");
|
supportedCommands.put(COMMAND_SHOW_OPPONENT_LIBRARY, "SHOW OPPONENT LIBRARY");
|
||||||
|
|
@ -295,48 +297,56 @@ public final class SystemUtil {
|
||||||
// 1. parse
|
// 1. parse
|
||||||
List<CommandGroup> groups = new ArrayList<>();
|
List<CommandGroup> groups = new ArrayList<>();
|
||||||
|
|
||||||
|
// read config
|
||||||
|
List<String> initLines = new ArrayList<>();
|
||||||
try (Scanner scanner = new Scanner(f)) {
|
try (Scanner scanner = new Scanner(f)) {
|
||||||
|
|
||||||
CommandGroup currentGroup = null;
|
|
||||||
|
|
||||||
while (scanner.hasNextLine()) {
|
while (scanner.hasNextLine()) {
|
||||||
String line = scanner.nextLine().trim();
|
initLines.add(scanner.nextLine().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// skip comments
|
// add default commands
|
||||||
if (line.isEmpty() || line.startsWith("#") || line.startsWith("//")) {
|
initLines.add(0, String.format("[%s]", COMMAND_LANDS_ADD_TO_BATTLEFIELD));
|
||||||
|
initLines.add(1, String.format("[%s]", COMMAND_CARDS_ADD_TO_HAND));
|
||||||
|
|
||||||
|
// collect all commands
|
||||||
|
CommandGroup currentGroup = null;
|
||||||
|
for (String line : initLines) {
|
||||||
|
|
||||||
|
// skip comments
|
||||||
|
if (line.isEmpty() || line.startsWith("#") || line.startsWith("//")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// group
|
||||||
|
Matcher matchGroup = patternGroup.matcher(line);
|
||||||
|
if (matchGroup.matches()) {
|
||||||
|
String groupName = matchGroup.group(1);
|
||||||
|
if (groupName.startsWith("@")) {
|
||||||
|
// special command group
|
||||||
|
if (supportedCommands.containsKey(groupName)) {
|
||||||
|
currentGroup = new CommandGroup(groupName, true);
|
||||||
|
groups.add(currentGroup);
|
||||||
|
} else {
|
||||||
|
String mes = String.format("Special group is not supported: %s", groupName);
|
||||||
|
errorsList.add(mes);
|
||||||
|
logger.warn(mes);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// basic group
|
||||||
|
currentGroup = new CommandGroup(groupName);
|
||||||
|
groups.add(currentGroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// group
|
|
||||||
Matcher matchGroup = patternGroup.matcher(line);
|
|
||||||
if (matchGroup.matches()) {
|
|
||||||
String groupName = matchGroup.group(1);
|
|
||||||
if (groupName.startsWith("@")) {
|
|
||||||
// special command group
|
|
||||||
if (supportedCommands.containsKey(groupName)) {
|
|
||||||
currentGroup = new CommandGroup(groupName, true);
|
|
||||||
groups.add(currentGroup);
|
|
||||||
} else {
|
|
||||||
String mes = String.format("Special group is not supported: %s", groupName);
|
|
||||||
errorsList.add(mes);
|
|
||||||
logger.warn(mes);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// basic group
|
|
||||||
currentGroup = new CommandGroup(groupName);
|
|
||||||
groups.add(currentGroup);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// command
|
|
||||||
if (currentGroup == null) {
|
|
||||||
currentGroup = new CommandGroup("default group");
|
|
||||||
groups.add(currentGroup);
|
|
||||||
}
|
|
||||||
currentGroup.commands.add(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// command
|
||||||
|
if (currentGroup == null) {
|
||||||
|
currentGroup = new CommandGroup("default group");
|
||||||
|
groups.add(currentGroup);
|
||||||
|
}
|
||||||
|
currentGroup.commands.add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. ask user
|
// 2. ask user
|
||||||
|
|
@ -388,31 +398,35 @@ public final class SystemUtil {
|
||||||
String info;
|
String info;
|
||||||
switch (runGroup.name) {
|
switch (runGroup.name) {
|
||||||
|
|
||||||
case COMMAND_SHOW_OPPONENT_HAND:
|
case COMMAND_SHOW_OPPONENT_HAND: {
|
||||||
if (opponent != null) {
|
if (opponent != null) {
|
||||||
info = getCardsListForSpecialInform(game, opponent.getHand(), runGroup.commands);
|
info = getCardsListForSpecialInform(game, opponent.getHand(), runGroup.commands);
|
||||||
game.informPlayer(feedbackPlayer, info);
|
game.informPlayer(feedbackPlayer, info);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case COMMAND_SHOW_OPPONENT_LIBRARY:
|
case COMMAND_SHOW_OPPONENT_LIBRARY: {
|
||||||
if (opponent != null) {
|
if (opponent != null) {
|
||||||
info = getCardsListForSpecialInform(game, opponent.getLibrary().getCardList(), runGroup.commands);
|
info = getCardsListForSpecialInform(game, opponent.getLibrary().getCardList(), runGroup.commands);
|
||||||
game.informPlayer(feedbackPlayer, info);
|
game.informPlayer(feedbackPlayer, info);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case COMMAND_SHOW_MY_HAND:
|
case COMMAND_SHOW_MY_HAND: {
|
||||||
info = getCardsListForSpecialInform(game, feedbackPlayer.getHand(), runGroup.commands);
|
info = getCardsListForSpecialInform(game, feedbackPlayer.getHand(), runGroup.commands);
|
||||||
game.informPlayer(feedbackPlayer, info);
|
game.informPlayer(feedbackPlayer, info);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case COMMAND_SHOW_MY_LIBRARY:
|
case COMMAND_SHOW_MY_LIBRARY: {
|
||||||
info = getCardsListForSpecialInform(game, feedbackPlayer.getLibrary().getCardList(), runGroup.commands);
|
info = getCardsListForSpecialInform(game, feedbackPlayer.getLibrary().getCardList(), runGroup.commands);
|
||||||
game.informPlayer(feedbackPlayer, info);
|
game.informPlayer(feedbackPlayer, info);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case COMMAND_ACTIVATE_OPPONENT_ABILITY:
|
case COMMAND_ACTIVATE_OPPONENT_ABILITY: {
|
||||||
// WARNING, maybe very bugged if called in wrong priority
|
// WARNING, maybe very bugged if called in wrong priority
|
||||||
// uses choose triggered ability dialog to select it
|
// uses choose triggered ability dialog to select it
|
||||||
UUID savedPriorityPlayer = null;
|
UUID savedPriorityPlayer = null;
|
||||||
|
|
@ -457,12 +471,91 @@ public final class SystemUtil {
|
||||||
game.firePriorityEvent(savedPriorityPlayer);
|
game.firePriorityEvent(savedPriorityPlayer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
case COMMAND_CARDS_ADD_TO_HAND: {
|
||||||
|
|
||||||
|
// card
|
||||||
|
String cardName;
|
||||||
|
Choice cardChoice = new ChoiceImpl(false, ChoiceHintType.CARD);
|
||||||
|
cardChoice.setChoices(CardRepository.instance.getNames());
|
||||||
|
cardChoice.setMessage("Choose card name to put in hand");
|
||||||
|
if (!feedbackPlayer.choose(Outcome.Detriment, cardChoice, game)
|
||||||
|
|| cardChoice.getChoice() == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cardName = cardChoice.getChoice();
|
||||||
|
|
||||||
|
// amount
|
||||||
|
int cardAmount = feedbackPlayer.getAmount(1, 100, "How many [" + cardName + "] to add?", game);
|
||||||
|
if (cardAmount == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to game
|
||||||
|
Set<Card> newCards = addNewCardsToGame(game, cardName, null, cardAmount, feedbackPlayer);
|
||||||
|
if (newCards == null) {
|
||||||
|
String mes = String.format("Can't add cards to hand: %s", cardName);
|
||||||
|
errorsList.add(mes);
|
||||||
|
logger.warn(mes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to hand
|
||||||
|
for (Card card : newCards) {
|
||||||
|
Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
|
||||||
|
fakeSourceAbility.setSourceId(card.getId());
|
||||||
|
putCardToZone(fakeSourceAbility, game, feedbackPlayer, card, Zone.HAND);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case COMMAND_LANDS_ADD_TO_BATTLEFIELD: {
|
||||||
|
// select lands
|
||||||
|
List<MultiAmountMessage> lands = new ArrayList<>();
|
||||||
|
lands.add(new MultiAmountMessage("{W} Plains", 0, 10, 5));
|
||||||
|
lands.add(new MultiAmountMessage("{U} Island", 0, 10, 5));
|
||||||
|
lands.add(new MultiAmountMessage("{B} Swamp", 0, 10, 5));
|
||||||
|
lands.add(new MultiAmountMessage("{R} Mountain", 0, 10, 5));
|
||||||
|
lands.add(new MultiAmountMessage("{G} Forest", 0, 10, 5));
|
||||||
|
lands.add(new MultiAmountMessage("{C} Ash Barrens", 0, 10, 0));
|
||||||
|
List<Integer> landsAmount = feedbackPlayer.getMultiAmountWithIndividualConstraints(
|
||||||
|
Outcome.Neutral, lands, 0, 100, MultiAmountType.CHEAT_LANDS, game
|
||||||
|
);
|
||||||
|
if (landsAmount == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to game
|
||||||
|
Set<Card> newCards = new LinkedHashSet<>();
|
||||||
|
for (int i = 0; i < landsAmount.size(); i++) {
|
||||||
|
int cardAmount = landsAmount.get(i);
|
||||||
|
String cardName = lands.get(i).message.substring("{W}".length() + 1);
|
||||||
|
if (cardAmount > 0) {
|
||||||
|
Set<Card> addedCards = addNewCardsToGame(game, cardName, null, cardAmount, feedbackPlayer);
|
||||||
|
if (addedCards != null) {
|
||||||
|
newCards.addAll(addedCards);
|
||||||
|
} else {
|
||||||
|
errorsList.add("Can't add land card to game: " + cardName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to battlefield
|
||||||
|
for (Card card : newCards) {
|
||||||
|
Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
|
||||||
|
fakeSourceAbility.setSourceId(card.getId());
|
||||||
|
putCardToZone(fakeSourceAbility, game, feedbackPlayer, card, Zone.BATTLEFIELD);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
String mes = String.format("Unknown system command: %s", runGroup.name);
|
String mes = String.format("Unknown system command: %s", runGroup.name);
|
||||||
errorsList.add(mes);
|
errorsList.add(mes);
|
||||||
logger.error(mes);
|
logger.error(mes);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sendCheatCommandsFeedback(game, feedbackPlayer, errorsList);
|
sendCheatCommandsFeedback(game, feedbackPlayer, errorsList);
|
||||||
return;
|
return;
|
||||||
|
|
@ -554,9 +647,8 @@ public final class SystemUtil {
|
||||||
} else if ("stack".equalsIgnoreCase(command.zone)) {
|
} else if ("stack".equalsIgnoreCase(command.zone)) {
|
||||||
// simple cast (without targets or modes)
|
// simple cast (without targets or modes)
|
||||||
|
|
||||||
// find card info
|
Set<Card> newCards = addNewCardsToGame(game, command.cardName, command.cardSet, command.Amount, player);
|
||||||
CardInfo cardInfo = CardLookup.instance.lookupCardInfo(command.cardName, command.cardSet).orElse(null);
|
if (newCards == null) {
|
||||||
if (cardInfo == null) {
|
|
||||||
String mes = String.format("Unknown card for stack command [%s]: %s",
|
String mes = String.format("Unknown card for stack command [%s]: %s",
|
||||||
command.cardName,
|
command.cardName,
|
||||||
line);
|
line);
|
||||||
|
|
@ -565,15 +657,8 @@ public final class SystemUtil {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// put card to game
|
|
||||||
Set<Card> cardsToLoad = new HashSet<>();
|
|
||||||
for (int i = 0; i < command.Amount; i++) {
|
|
||||||
cardsToLoad.add(cardInfo.getCard());
|
|
||||||
}
|
|
||||||
game.loadCards(cardsToLoad, player.getId());
|
|
||||||
|
|
||||||
// move card from exile to stack
|
// move card from exile to stack
|
||||||
for (Card card : cardsToLoad) {
|
for (Card card : newCards) {
|
||||||
Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
|
Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
|
||||||
fakeSourceAbility.setSourceId(card.getId());
|
fakeSourceAbility.setSourceId(card.getId());
|
||||||
putCardToZone(fakeSourceAbility, game, player, card, Zone.STACK);
|
putCardToZone(fakeSourceAbility, game, player, card, Zone.STACK);
|
||||||
|
|
@ -690,6 +775,27 @@ public final class SystemUtil {
|
||||||
game.informPlayers(String.format("%s: tried to apply cheat commands", feedbackPlayer.getLogName()));
|
game.informPlayers(String.format("%s: tried to apply cheat commands", feedbackPlayer.getLogName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For cheats only: add new cards to the game (it's put to outside zone, so you must move it to real zone after that)
|
||||||
|
*
|
||||||
|
* @param setCode can be null for latest set code
|
||||||
|
* @return added cards list
|
||||||
|
*/
|
||||||
|
private static Set<Card> addNewCardsToGame(Game game, String cardName, String setCode, int amount, Player owner) {
|
||||||
|
CardInfo cardInfo = CardLookup.instance.lookupCardInfo(cardName, setCode).orElse(null);
|
||||||
|
if (cardInfo == null || amount <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Card> cardsToLoad = new LinkedHashSet<>();
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
cardsToLoad.add(cardInfo.getCard());
|
||||||
|
}
|
||||||
|
game.loadCards(cardsToLoad, owner.getId());
|
||||||
|
|
||||||
|
return cardsToLoad;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put card to specified zone (battlefield zone will be tranformed to permanent with initialized effects)
|
* Put card to specified zone (battlefield zone will be tranformed to permanent with initialized effects)
|
||||||
* Use it for cheats and tests only
|
* Use it for cheats and tests only
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ public class CardLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<CardInfo> lookupCardInfo(String name, String set) {
|
public Optional<CardInfo> lookupCardInfo(String name, String set) {
|
||||||
|
if (set == null) {
|
||||||
|
return lookupCardInfo(name);
|
||||||
|
}
|
||||||
|
|
||||||
Optional<CardInfo> result = lookupCardInfo(new CardCriteria().name(name).setCodes(set))
|
Optional<CardInfo> result = lookupCardInfo(new CardCriteria().name(name).setCodes(set))
|
||||||
.stream()
|
.stream()
|
||||||
.findAny();
|
.findAny();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue