Merge pull request #1902 from Northmoc/spaceb

UNF: space_beleren.txt and support
This commit is contained in:
Anthony Calosa
2022-11-22 08:54:01 +08:00
committed by GitHub
24 changed files with 189 additions and 14 deletions

View File

@@ -1,11 +1,7 @@
package forge.ai; package forge.ai;
import java.security.InvalidParameterException; import java.security.InvalidParameterException;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import forge.game.keyword.Keyword; import forge.game.keyword.Keyword;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -591,6 +587,11 @@ public class PlayerControllerAi extends PlayerController {
return ComputerUtil.vote(player, options, sa, votes, forPlayer); return ComputerUtil.vote(player, options, sa, votes, forPlayer);
} }
@Override
public String chooseSector(Card assignee, String ai, List<String> sectors) {
return Aggregates.random(sectors);
}
@Override @Override
public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) { public boolean mulliganKeepHand(Player firstPlayer, int cardsToReturn) {
return !ComputerUtil.wantMulligan(player, cardsToReturn); return !ComputerUtil.wantMulligan(player, cardsToReturn);

View File

@@ -47,6 +47,7 @@ public enum SpellApiToAi {
.put(ApiType.ChooseEvenOdd, ChooseEvenOddAi.class) .put(ApiType.ChooseEvenOdd, ChooseEvenOddAi.class)
.put(ApiType.ChooseNumber, ChooseNumberAi.class) .put(ApiType.ChooseNumber, ChooseNumberAi.class)
.put(ApiType.ChoosePlayer, ChoosePlayerAi.class) .put(ApiType.ChoosePlayer, ChoosePlayerAi.class)
.put(ApiType.ChooseSector, AlwaysPlayAi.class)
.put(ApiType.ChooseSource, ChooseSourceAi.class) .put(ApiType.ChooseSource, ChooseSourceAi.class)
.put(ApiType.ChooseType, ChooseTypeAi.class) .put(ApiType.ChooseType, ChooseTypeAi.class)
.put(ApiType.Clash, ClashAi.class) .put(ApiType.Clash, ClashAi.class)

View File

@@ -37,6 +37,7 @@ import forge.game.mulligan.MulliganService;
import forge.game.player.GameLossReason; import forge.game.player.GameLossReason;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerCollection;
import forge.game.player.PlayerPredicates; import forge.game.player.PlayerPredicates;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
import forge.game.replacement.ReplacementResult; import forge.game.replacement.ReplacementResult;
@@ -1317,7 +1318,11 @@ public class GameAction {
CardCollection desCreats = null; CardCollection desCreats = null;
CardCollection unAttachList = new CardCollection(); CardCollection unAttachList = new CardCollection();
CardCollection sacrificeList = new CardCollection(); CardCollection sacrificeList = new CardCollection();
PlayerCollection spaceSculptors = new PlayerCollection();
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) { for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
if (c.hasKeyword(Keyword.SPACE_SCULPTOR)) {
spaceSculptors.add(c.getController());
}
if (c.isCreature()) { if (c.isCreature()) {
// Rule 704.5f - Put into grave (no regeneration) for toughness <= 0 // Rule 704.5f - Put into grave (no regeneration) for toughness <= 0
if (c.getNetToughness() <= 0) { if (c.getNetToughness() <= 0) {
@@ -1393,6 +1398,9 @@ public class GameAction {
} }
for (Player p : game.getPlayers()) { for (Player p : game.getPlayers()) {
if (!spaceSculptors.isEmpty() && !spaceSculptors.contains(p)) {
checkAgain |= stateBasedAction704_5u(p);
}
if (handleLegendRule(p, noRegCreats)) { if (handleLegendRule(p, noRegCreats)) {
checkAgain = true; checkAgain = true;
} }
@@ -1412,6 +1420,11 @@ public class GameAction {
checkAgain = true; checkAgain = true;
} }
} }
if (!spaceSculptors.isEmpty()) {
for (Player p : spaceSculptors) {
checkAgain |= stateBasedAction704_5u(p);
}
}
// 704.5m World rule // 704.5m World rule
checkAgain |= handleWorldRule(noRegCreats); checkAgain |= handleWorldRule(noRegCreats);
// only check static abilities once after destroying all the creatures // only check static abilities once after destroying all the creatures
@@ -1551,6 +1564,37 @@ public class GameAction {
return checkAgain; return checkAgain;
} }
private boolean stateBasedAction704_5u(Player p) {
boolean checkAgain = false;
CardCollection toAssign = new CardCollection();
for (final Card c : p.getCreaturesInPlay().threadSafeIterable()) {
if (!c.hasSector()) {
toAssign.add(c);
if (!checkAgain) {
checkAgain = true;
}
}
}
final StringBuilder sb = new StringBuilder();
for (Card assignee : toAssign) { // probably would be nice for players to pick order of assigning?
String sector = p.getController().chooseSector(assignee, "Assign");
assignee.assignSector(sector);
if (sb.length() == 0) {
sb.append(p).append(" ").append(Localizer.getInstance().getMessage("lblAssigns")).append("\n");
}
String creature = CardTranslation.getTranslatedName(assignee.getName()) + " (" + assignee.getId() + ")";
sb.append(creature).append(" ").append(sector).append("\n");
}
if (sb.length() > 0) {
notifyOfValue(null, p, sb.toString(), p);
}
return checkAgain;
}
private boolean stateBasedAction903_9a(Card c) { private boolean stateBasedAction903_9a(Card c) {
if (c.isRealCommander() && c.canMoveToCommandZone()) { if (c.isRealCommander() && c.canMoveToCommandZone()) {
// FIXME: need to flush the tracker to make sure the Commander is properly updated // FIXME: need to flush the tracker to make sure the Commander is properly updated
@@ -1938,9 +1982,11 @@ public class GameAction {
/** Delivers a message to all players. (use reveal to show Cards) */ /** Delivers a message to all players. (use reveal to show Cards) */
public void notifyOfValue(SpellAbility saSource, GameObject relatedTarget, String value, Player playerExcept) { public void notifyOfValue(SpellAbility saSource, GameObject relatedTarget, String value, Player playerExcept) {
if (saSource != null) {
String name = CardTranslation.getTranslatedName(saSource.getHostCard().getName()); String name = CardTranslation.getTranslatedName(saSource.getHostCard().getName());
value = TextUtil.fastReplace(value, "CARDNAME", name); value = TextUtil.fastReplace(value, "CARDNAME", name);
value = TextUtil.fastReplace(value, "NICKNAME", Lang.getInstance().getNickName(name)); value = TextUtil.fastReplace(value, "NICKNAME", Lang.getInstance().getNickName(name));
}
for (Player p : game.getPlayers()) { for (Player p : game.getPlayers()) {
if (playerExcept == p) continue; if (playerExcept == p) continue;
p.getController().notifyOfValue(saSource, relatedTarget, value); p.getController().notifyOfValue(saSource, relatedTarget, value);

View File

@@ -44,6 +44,7 @@ public enum ApiType {
ChooseEvenOdd (ChooseEvenOddEffect.class), ChooseEvenOdd (ChooseEvenOddEffect.class),
ChooseNumber (ChooseNumberEffect.class), ChooseNumber (ChooseNumberEffect.class),
ChoosePlayer (ChoosePlayerEffect.class), ChoosePlayer (ChoosePlayerEffect.class),
ChooseSector (ChooseSectorEffect.class),
ChooseSource (ChooseSourceEffect.class), ChooseSource (ChooseSourceEffect.class),
ChooseType (ChooseTypeEffect.class), ChooseType (ChooseTypeEffect.class),
Clash (ClashEffect.class), Clash (ClashEffect.class),

View File

@@ -0,0 +1,15 @@
package forge.game.ability.effects;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
public class ChooseSectorEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
final Card card = sa.getHostCard();
final String chosen = card.getController().getController().chooseSector(null, sa.getParamOrDefault("AILogic", ""));
card.setChosenSector(chosen);
}
}

View File

@@ -290,6 +290,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private Direction chosenDirection = null; private Direction chosenDirection = null;
private String chosenMode = ""; private String chosenMode = "";
private String currentRoom = null; private String currentRoom = null;
private String sector = null;
private String chosenSector = null;
private Card exiledWith; private Card exiledWith;
private Player exiledBy; private Player exiledBy;
@@ -1898,6 +1900,23 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return false; return false;
} }
public String getSector() {
return sector;
}
public void assignSector(String s) {
sector = s;
view.updateSector(this);
}
public boolean hasSector() {
return sector != null;
}
public String getChosenSector() {
return chosenSector;
}
public final void setChosenSector(final String s) {
chosenSector = s;
}
// used for cards like Meddling Mage... // used for cards like Meddling Mage...
public final String getNamedCard() { public final String getNamedCard() {
return getChosenName(); return getChosenName();
@@ -2183,7 +2202,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|| keyword.equals("Ascend") || keyword.equals("Totem armor") || keyword.equals("Ascend") || keyword.equals("Totem armor")
|| keyword.equals("Battle cry") || keyword.equals("Devoid") || keyword.equals("Riot") || keyword.equals("Battle cry") || keyword.equals("Devoid") || keyword.equals("Riot")
|| keyword.equals("Daybound") || keyword.equals("Nightbound") || keyword.equals("Daybound") || keyword.equals("Nightbound")
|| keyword.equals("Friends forever") || keyword.equals("Choose a Background")) { || keyword.equals("Friends forever") || keyword.equals("Choose a Background")
|| keyword.equals("Space sculptor")) {
sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")"); sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")");
} else if (keyword.startsWith("Partner:")) { } else if (keyword.startsWith("Partner:")) {
final String[] k = keyword.split(":"); final String[] k = keyword.split(":");

View File

@@ -120,6 +120,14 @@ public class CardProperty {
if (source.hasChosenCard(card)) { if (source.hasChosenCard(card)) {
return false; return false;
} }
} else if (property.equals("ChosenSector")) {
if (!source.getChosenSector().equals(card.getSector())) {
return false;
}
} else if (property.equals("DifferentSector")) {
if (source.getSector().equals(card.getSector())) {
return false;
}
} else if (property.equals("DoubleFaced")) { } else if (property.equals("DoubleFaced")) {
if (!card.isDoubleFaced()) { if (!card.isDoubleFaced()) {
return false; return false;

View File

@@ -479,6 +479,13 @@ public class CardView extends GameEntityView {
set(TrackableProperty.Remembered, sb.toString()); set(TrackableProperty.Remembered, sb.toString());
} }
public String getSector() {
return get(TrackableProperty.Sector);
}
void updateSector(Card c) {
set(TrackableProperty.Sector, c.getSector());
}
public String getNamedCard() { public String getNamedCard() {
return get(TrackableProperty.NamedCard); return get(TrackableProperty.NamedCard);
} }

View File

@@ -157,6 +157,7 @@ public enum Keyword {
SCAVENGE("Scavenge", KeywordWithCost.class, false, "%s, Exile this card from your graveyard: Put a number of +1/+1 counters equal to this card's power on target creature. Scavenge only as a sorcery."), SCAVENGE("Scavenge", KeywordWithCost.class, false, "%s, Exile this card from your graveyard: Put a number of +1/+1 counters equal to this card's power on target creature. Scavenge only as a sorcery."),
SOULBOND("Soulbond", SimpleKeyword.class, true, "You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them."), SOULBOND("Soulbond", SimpleKeyword.class, true, "You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them."),
SOULSHIFT("Soulshift", KeywordWithAmount.class, false, "When this creature dies, you may return target Spirit card with mana value %d or less from your graveyard to your hand."), SOULSHIFT("Soulshift", KeywordWithAmount.class, false, "When this creature dies, you may return target Spirit card with mana value %d or less from your graveyard to your hand."),
SPACE_SCULPTOR("Space sculptor", SimpleKeyword.class, true, "CARDNAME divides the battlefield into alpha, beta, and gamma sectors. If a creature isn't assigned to a sector, its controller assigns it to one. Opponents assign first."),
SPECIALIZE("Specialize", KeywordWithCost.class, false, "%s, Choose a color, discard a card of that color or associated basic land type: This card perpetually specializes into that color. Activate only as a sorcery."), SPECIALIZE("Specialize", KeywordWithCost.class, false, "%s, Choose a color, discard a card of that color or associated basic land type: This card perpetually specializes into that color. Activate only as a sorcery."),
SPECTACLE("Spectacle", KeywordWithCost.class, false, "You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn."), SPECTACLE("Spectacle", KeywordWithCost.class, false, "You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn."),
SPLICE("Splice", KeywordWithCostAndType.class, false, "As you cast an %2$s spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell."), SPLICE("Splice", KeywordWithCostAndType.class, false, "As you cast an %2$s spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell."),

View File

@@ -1,5 +1,6 @@
package forge.game.player; package forge.game.player;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -183,6 +184,12 @@ public abstract class PlayerController {
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false); return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
} }
public abstract String chooseSector(Card assignee, String ai, List<String> sectors);
public final String chooseSector(Card assignee, String ai) {
final List<String> sectors = Arrays.asList("Alpha", "Beta", "Gamma");
return chooseSector(assignee, ai, sectors);
}
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer); public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer);
public abstract CardCollectionView getCardsToMulligan(Player firstPlayer); public abstract CardCollectionView getCardsToMulligan(Player firstPlayer);

View File

@@ -68,6 +68,8 @@ public enum TrackableProperty {
ChosenDirection(TrackableTypes.EnumType(Direction.class)), ChosenDirection(TrackableTypes.EnumType(Direction.class)),
ChosenEvenOdd(TrackableTypes.EnumType(EvenOdd.class)), ChosenEvenOdd(TrackableTypes.EnumType(EvenOdd.class)),
ChosenMode(TrackableTypes.StringType), ChosenMode(TrackableTypes.StringType),
ChosenSector(TrackableTypes.StringType),
Sector(TrackableTypes.StringType),
ClassLevel(TrackableTypes.IntegerType), ClassLevel(TrackableTypes.IntegerType),
CurrentRoom(TrackableTypes.StringType), CurrentRoom(TrackableTypes.StringType),
Intensity(TrackableTypes.IntegerType), Intensity(TrackableTypes.IntegerType),

View File

@@ -55,10 +55,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Default harmless implementation for tests. * Default harmless implementation for tests.
@@ -496,6 +493,11 @@ public class PlayerControllerForTests extends PlayerController {
return chooseItem(validTypes); return chooseItem(validTypes);
} }
@Override
public String chooseSector(Card assignee, String ai, List<String> sectors) {
return chooseItem(sectors);
}
@Override @Override
public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) { public Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer) {
return chooseItem(options); return chooseItem(options);

View File

@@ -1,6 +1,6 @@
Name:Alluring Scent Name:Alluring Scent
ManaCost:1 G G ManaCost:1 G G
Types:Sorcery Types:Sorcery
A:SP$ Pump | Cost$ 1 G G | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN All creatures able to block CARDNAME do so. | SpellDescription$ All creatures able to block target creature this turn do so. A:SP$ Pump | ValidTgts$ Creature | KW$ HIDDEN All creatures able to block CARDNAME do so. | StackDescription$ All creatures able to block {c:Targeted} this turn do so. | SpellDescription$ All creatures able to block target creature this turn do so.
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:All creatures able to block target creature this turn do so. Oracle:All creatures able to block target creature this turn do so.

View File

@@ -0,0 +1,14 @@
Name:Space Beleren
ManaCost:2 W U
Types:Legendary Planeswalker Jace
Loyalty:3
K:Space sculptor
A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | StaticAbilities$ SectorBlock | SpellDescription$ Creatures in each sector can be blocked this turn only by creatures in the same sector.
SVar:SectorBlock:Mode$ CantBlockBy | ValidAttacker$ Creature | ValidBlockerRelative$ Creature.DifferentSector | Description$ Creatures in each sector can be blocked this turn only by creatures in the same sector.
A:AB$ ChooseSector | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | SubAbility$ DBPutCounterAll | AILogic$ Pump | SpellDescription$ Put a +1/+1 counter on each creature in the sector of your choice.
SVar:DBPutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.ChosenSector | CounterType$ P1P1 | StackDescription$ None
A:AB$ ChooseSector | Cost$ SubCounter<5/LOYALTY> | Planeswalker$ True | Ultimate$ True | SubAbility$ DBDestroyAll | AILogic$ Destroy | SpellDescription$ Destroy all creatures in the sector of your choice.
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Creature.ChosenSector | StackDescription$ None
DeckHas:Ability$Counters
AI:RemoveDeck:All
Oracle:Space sculptor (Space Beleren divides the battlefield into alpha, beta, and gamma sectors. If a creature isn't assigned to a sector, its controller assigns it to one. Opponents assign first.)\n[+1]: Creatures in each sector can be blocked this turn only by creatures in the same sector.\n[1]: Put a +1/+1 counter on each creature in the sector of your choice.\n[5]: Destroy all creatures in the sector of your choice.

View File

@@ -1231,6 +1231,8 @@ lblSelectANumber=Wähle eine Zahl
lblCut=Ausschneiden lblCut=Ausschneiden
lblCopy=Kopieren lblCopy=Kopieren
lblPaste=Einfügen lblPaste=Einfügen
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Suche lblSearch=Suche
#InputBase.java #InputBase.java
@@ -1342,6 +1344,8 @@ lblThereNoCardInPlayerZone=Es sind kein Karten in {0} {1}
lblPutCardsOnTheTopLibraryOrGraveyard=Lege {0} oben auf Bibliothek oder Friedhof? lblPutCardsOnTheTopLibraryOrGraveyard=Lege {0} oben auf Bibliothek oder Friedhof?
lblLibrary=Bibliothek lblLibrary=Bibliothek
lblGraveyard=Friedhof lblGraveyard=Friedhof
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=Oben drauf lblTop=Oben drauf
lblBottom=Unten drunter lblBottom=Unten drunter
lblNColorManaFromCard={0} {1} Mana von {2} lblNColorManaFromCard={0} {1} Mana von {2}

View File

@@ -1232,6 +1232,8 @@ lblSelectANumber=Select a number
lblCut=Cut lblCut=Cut
lblCopy=Copy lblCopy=Copy
lblPaste=Paste lblPaste=Paste
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Search lblSearch=Search
#InputBase.java #InputBase.java
@@ -1344,6 +1346,8 @@ lblThereNoCardInPlayerZone=There are no cards in {0} {1}
lblPutCardsOnTheTopLibraryOrGraveyard=Put {0} on the top of library or graveyard? lblPutCardsOnTheTopLibraryOrGraveyard=Put {0} on the top of library or graveyard?
lblLibrary=Library lblLibrary=Library
lblGraveyard=Graveyard lblGraveyard=Graveyard
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=Top lblTop=Top
lblBottom=Bottom lblBottom=Bottom
lblNColorManaFromCard={0} {1} mana from {2} lblNColorManaFromCard={0} {1} mana from {2}

View File

@@ -1231,6 +1231,8 @@ lblSelectANumber=Selecciona un número
lblCut=Cortar lblCut=Cortar
lblCopy=Copiar lblCopy=Copiar
lblPaste=Pegar lblPaste=Pegar
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Buscar lblSearch=Buscar
#InputBase.java #InputBase.java
@@ -1342,6 +1344,8 @@ lblThereNoCardInPlayerZone=No hay cartas en {0} {1}
lblPutCardsOnTheTopLibraryOrGraveyard=¿Poner {0} en la parte superior de la biblioteca o en el cementerio? lblPutCardsOnTheTopLibraryOrGraveyard=¿Poner {0} en la parte superior de la biblioteca o en el cementerio?
lblLibrary=Biblioteca lblLibrary=Biblioteca
lblGraveyard=Cementerio lblGraveyard=Cementerio
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=Superior lblTop=Superior
lblBottom=Fondo lblBottom=Fondo
lblNColorManaFromCard={0} {1} maná de {2} lblNColorManaFromCard={0} {1} maná de {2}

View File

@@ -1233,6 +1233,8 @@ lblSelectANumber=Sélectionner un numéro
lblCut=Couper lblCut=Couper
lblCopy=Copier lblCopy=Copier
lblPaste=Coller lblPaste=Coller
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Rechercher lblSearch=Rechercher
#InputBase.java #InputBase.java

View File

@@ -1230,6 +1230,8 @@ lblSelectANumber=Seleziona un numero
lblCut=Taglia lblCut=Taglia
lblCopy=Copia lblCopy=Copia
lblPaste=Incolla lblPaste=Incolla
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Ricerca lblSearch=Ricerca
#InputBase.java #InputBase.java
@@ -1342,6 +1344,8 @@ lblThereNoCardInPlayerZone=Non ci sono carte in {0} {1}
lblPutCardsOnTheTopLibraryOrGraveyard=Metti {0} in cima al grimorio o nel cimitero? lblPutCardsOnTheTopLibraryOrGraveyard=Metti {0} in cima al grimorio o nel cimitero?
lblLibrary=Grimorio lblLibrary=Grimorio
lblGraveyard=Cimitero lblGraveyard=Cimitero
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=Cima lblTop=Cima
lblBottom=Fondo lblBottom=Fondo
lblNColorManaFromCard={0} {1} mana da {2} lblNColorManaFromCard={0} {1} mana da {2}

View File

@@ -1232,6 +1232,8 @@ lblSelectANumber=数字を選択してください
lblCut=切り取り lblCut=切り取り
lblCopy=コピー lblCopy=コピー
lblPaste=貼り付け lblPaste=貼り付け
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=検索 lblSearch=検索
#InputBase.java #InputBase.java
@@ -1343,6 +1345,8 @@ lblThereNoCardInPlayerZone={0} {1}にカードがありません
lblPutCardsOnTheTopLibraryOrGraveyard=ライブラリまたは墓地の一番上に{0}を置きますか? lblPutCardsOnTheTopLibraryOrGraveyard=ライブラリまたは墓地の一番上に{0}を置きますか?
lblLibrary=ライブラリー lblLibrary=ライブラリー
lblGraveyard=墓地 lblGraveyard=墓地
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=タップ lblTop=タップ
lblBottom=ボトム lblBottom=ボトム
lblNColorManaFromCard={2}から {0} {1} のマナ lblNColorManaFromCard={2}から {0} {1} のマナ

View File

@@ -1260,6 +1260,8 @@ lblSelectANumber=Selecione um número
lblCut=Cortar lblCut=Cortar
lblCopy=Copiar lblCopy=Copiar
lblPaste=Colar lblPaste=Colar
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=Buscar lblSearch=Buscar
#InputBase.java #InputBase.java
@@ -1373,6 +1375,8 @@ lblThereNoCardInPlayerZone=Sem cartas em {0} {1}
lblPutCardsOnTheTopLibraryOrGraveyard=Colocar {0} no topo do grimório ou cemitério? lblPutCardsOnTheTopLibraryOrGraveyard=Colocar {0} no topo do grimório ou cemitério?
lblLibrary=Grimório lblLibrary=Grimório
lblGraveyard=Cemitério lblGraveyard=Cemitério
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop=Topo lblTop=Topo
lblBottom=Fundo lblBottom=Fundo
lblNColorManaFromCard={0} {1} mana de {2} lblNColorManaFromCard={0} {1} mana de {2}

View File

@@ -1232,6 +1232,8 @@ lblSelectANumber=选择一个数
lblCut=剪切 lblCut=剪切
lblCopy=复制 lblCopy=复制
lblPaste=粘贴 lblPaste=粘贴
#GameAction.java
lblAssigns=assigns:
#ListChooser.java #ListChooser.java
lblSearch=搜索 lblSearch=搜索
#InputBase.java #InputBase.java
@@ -1344,6 +1346,8 @@ lblThereNoCardInPlayerZone={0}的{1}中没有牌
lblPutCardsOnTheTopLibraryOrGraveyard=将{0}放到牌库顶还是坟场? lblPutCardsOnTheTopLibraryOrGraveyard=将{0}放到牌库顶还是坟场?
lblLibrary=牌库 lblLibrary=牌库
lblGraveyard=坟场 lblGraveyard=坟场
lblAssignSectorCreature=Assign {0} to a sector
lblChooseSectorEffect=Choose a sector
lblTop= lblTop=
lblBottom= lblBottom=
lblNColorManaFromCard={2}产{0}个{1}法术力 lblNColorManaFromCard={2}产{0}个{1}法术力

View File

@@ -527,6 +527,14 @@ public class CardDetailUtil {
area.append("(Class Level:").append(card.getClassLevel()).append(")"); area.append("(Class Level:").append(card.getClassLevel()).append(")");
} }
// sector
if (!card.getSector().isEmpty()) {
if (area.length() != 0) {
area.append("\n");
}
area.append("Sector: ").append(card.getSector());
}
// a card has something attached to it // a card has something attached to it
if (card.hasCardAttachments()) { if (card.hasCardAttachments()) {
if (area.length() != 0) { if (area.length() != 0) {

View File

@@ -1364,6 +1364,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
} }
} }
@Override
public String chooseSector(Card assignee, String ai, List<String> sectors) {
String prompt;
if (assignee != null) {
String creature = CardTranslation.getTranslatedName(assignee.getName()) + " (" + assignee.getId() + ")";
prompt = Localizer.getInstance().getMessage("lblAssignSectorCreature", creature);
} else {
prompt = Localizer.getInstance().getMessage("lblChooseSectorEffect");
}
return getGui().one(prompt, sectors);
}
@Override @Override
public Object vote(final SpellAbility sa, final String prompt, final List<Object> options, public Object vote(final SpellAbility sa, final String prompt, final List<Object> options,
final ListMultimap<Object, Player> votes, Player forPlayer) { final ListMultimap<Object, Player> votes, Player forPlayer) {