mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 02:08:00 +00:00
Merge branch 'master' of https://git.cardforge.org/core-developers/forge
This commit is contained in:
@@ -643,7 +643,7 @@ public class ComputerUtilCard {
|
|||||||
return getMostProminentType(list, CardType.getAllCreatureTypes());
|
return getMostProminentType(list, CardType.getAllCreatureTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getMostProminentType(final CardCollectionView list, final List<String> valid) {
|
public static String getMostProminentType(final CardCollectionView list, final Collection<String> valid) {
|
||||||
if (list.size() == 0) {
|
if (list.size() == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public abstract class GameState {
|
|||||||
if (card instanceof DetachedCardEffect) {
|
if (card instanceof DetachedCardEffect) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card);
|
addCard(zone, card.getController() == ai ? aiCardTexts : humanCardTexts, card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,6 +269,10 @@ public abstract class GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zoneType == ZoneType.Battlefield) {
|
if (zoneType == ZoneType.Battlefield) {
|
||||||
|
if (c.getOwner() != c.getController()) {
|
||||||
|
// TODO: Handle more than 2-player games.
|
||||||
|
newText.append("|Owner:" + (c.getOwner().isAI() ? "AI" : "Human"));
|
||||||
|
}
|
||||||
if (c.isTapped()) {
|
if (c.isTapped()) {
|
||||||
newText.append("|Tapped");
|
newText.append("|Tapped");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -502,12 +502,11 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional) {
|
public String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes, boolean isOptional) {
|
||||||
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
|
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
|
||||||
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
|
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty()) {
|
||||||
{
|
chosen = validTypes.iterator().next();
|
||||||
chosen = validTypes.get(0);
|
System.err.println("AI has no idea how to choose " + kindOfType +", defaulting to arbitrary element: chosen");
|
||||||
System.err.println("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
|
|
||||||
}
|
}
|
||||||
game.getAction().nofityOfValue(sa, player, chosen, player);
|
game.getAction().nofityOfValue(sa, player, chosen, player);
|
||||||
return chosen;
|
return chosen;
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ public class GameStateEvaluator {
|
|||||||
if (phase.isAfter(PhaseType.COMBAT_DAMAGE) || evalGame.isGameOver()) {
|
if (phase.isAfter(PhaseType.COMBAT_DAMAGE) || evalGame.isGameOver()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// If the current player has no creatures in play, there won't be any combat. This avoids
|
||||||
|
// an expensive game copy operation.
|
||||||
|
// Note: This is is safe to do because the simulation is based on the current game state,
|
||||||
|
// so there isn't a chance to play creatures in between.
|
||||||
|
if (evalGame.getPhaseHandler().getPlayerTurn().getCreaturesInPlay().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
GameCopier copier = new GameCopier(evalGame);
|
GameCopier copier = new GameCopier(evalGame);
|
||||||
Game gameCopy = copier.makeCopy();
|
Game gameCopy = copier.makeCopy();
|
||||||
gameCopy.getPhaseHandler().devAdvanceToPhase(PhaseType.COMBAT_DAMAGE);
|
gameCopy.getPhaseHandler().devAdvanceToPhase(PhaseType.COMBAT_DAMAGE);
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
tokenNormalized
|
tokenNormalized
|
||||||
);
|
);
|
||||||
|
|
||||||
FileSection section = FileSection.parse(contents.get("metadata"), "=");
|
FileSection section = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
res.name = section.get("name");
|
res.name = section.get("name");
|
||||||
res.date = parseDate(section.get("date"));
|
res.date = parseDate(section.get("date"));
|
||||||
res.code = section.get("code");
|
res.code = section.get("code");
|
||||||
|
|||||||
@@ -606,13 +606,13 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
|
|
||||||
public static class Constant {
|
public static class Constant {
|
||||||
public static final Settable LOADED = new Settable();
|
public static final Settable LOADED = new Settable();
|
||||||
public static final List<String> BASIC_TYPES = Lists.newArrayList();
|
public static final Set<String> BASIC_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> LAND_TYPES = Lists.newArrayList();
|
public static final Set<String> LAND_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> CREATURE_TYPES = Lists.newArrayList();
|
public static final Set<String> CREATURE_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> SPELL_TYPES = Lists.newArrayList();
|
public static final Set<String> SPELL_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> ENCHANTMENT_TYPES = Lists.newArrayList();
|
public static final Set<String> ENCHANTMENT_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> ARTIFACT_TYPES = Lists.newArrayList();
|
public static final Set<String> ARTIFACT_TYPES = Sets.newHashSet();
|
||||||
public static final List<String> WALKER_TYPES = Lists.newArrayList();
|
public static final Set<String> WALKER_TYPES = Sets.newHashSet();
|
||||||
|
|
||||||
// singular -> plural
|
// singular -> plural
|
||||||
public static final BiMap<String,String> pluralTypes = HashBiMap.create();
|
public static final BiMap<String,String> pluralTypes = HashBiMap.create();
|
||||||
@@ -699,12 +699,12 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
return sortedSubTypes;
|
return sortedSubTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getBasicTypes() {
|
public static Collection<String> getBasicTypes() {
|
||||||
return Collections.unmodifiableList(Constant.BASIC_TYPES);
|
return Collections.unmodifiableCollection(Constant.BASIC_TYPES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getAllCreatureTypes() {
|
public static Collection<String> getAllCreatureTypes() {
|
||||||
return Collections.unmodifiableList(Constant.CREATURE_TYPES);
|
return Collections.unmodifiableCollection(Constant.CREATURE_TYPES);
|
||||||
}
|
}
|
||||||
public static List<String> getAllLandTypes() {
|
public static List<String> getAllLandTypes() {
|
||||||
return ImmutableList.<String>builder()
|
return ImmutableList.<String>builder()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class DeckSerializer {
|
|||||||
}
|
}
|
||||||
final List<String> metadata = map.get("metadata");
|
final List<String> metadata = map.get("metadata");
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
return new DeckFileHeader(FileSection.parse(metadata, "="));
|
return new DeckFileHeader(FileSection.parse(metadata, FileSection.EQUALS_KV_SEPARATOR));
|
||||||
}
|
}
|
||||||
final List<String> general = map.get("general");
|
final List<String> general = map.get("general");
|
||||||
if (general != null) {
|
if (general != null) {
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public class PreconDeck implements InventoryItemFromSet {
|
|||||||
|
|
||||||
// To be able to read "shops" section in overloads
|
// To be able to read "shops" section in overloads
|
||||||
protected PreconDeck getPreconDeckFromSections(final Map<String, List<String>> sections) {
|
protected PreconDeck getPreconDeckFromSections(final Map<String, List<String>> sections) {
|
||||||
FileSection kv = FileSection.parse(sections.get("metadata"), "=");
|
FileSection kv = FileSection.parse(sections.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
String imageFilename = kv.get("Image");
|
String imageFilename = kv.get("Image");
|
||||||
String description = kv.get("Description");
|
String description = kv.get("Description");
|
||||||
String deckEdition = kv.get("set");
|
String deckEdition = kv.get("set");
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package forge.util;
|
package forge.util;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBasedTable;
|
||||||
|
import com.google.common.collect.Table;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -57,31 +60,37 @@ public class FileSection {
|
|||||||
lines = lines0;
|
lines = lines0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static final Pattern DOLLAR_SIGN_KV_SEPARATOR = Pattern.compile(Pattern.quote("$"));
|
||||||
* Parses the.
|
public static final Pattern ARROW_KV_SEPARATOR = Pattern.compile(Pattern.quote("->"));
|
||||||
*
|
public static final Pattern EQUALS_KV_SEPARATOR = Pattern.compile(Pattern.quote("="));
|
||||||
* @param line the line
|
public static final Pattern COLON_KV_SEPARATOR = Pattern.compile(Pattern.quote(":"));
|
||||||
* @param kvSeparator the kv separator
|
|
||||||
* @param pairSeparator the pair separator
|
private static final String BAR_PAIR_SPLITTER = Pattern.quote("|");
|
||||||
* @return the file section
|
|
||||||
*/
|
private static Table<String, Pattern, Map<String, String>> parseToMapCache = HashBasedTable.create();
|
||||||
public static FileSection parse(final String line, final String kvSeparator, final String pairSeparator) {
|
|
||||||
Map<String, String> map = parseToMap(line, kvSeparator, pairSeparator);
|
public static Map<String, String> parseToMap(final String line, final Pattern kvSeparator) {
|
||||||
return new FileSection(map);
|
Map<String, String> result = parseToMapCache.get(line, kvSeparator);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = parseToMapImpl(line, kvSeparator);
|
||||||
|
parseToMapCache.put(line, kvSeparator, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, String> parseToMap(final String line, final String kvSeparator, final String pairSeparator) {
|
private static Map<String, String> parseToMapImpl(final String line, final Pattern kvSeparator) {
|
||||||
Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
if (StringUtils.isEmpty(line)) {
|
||||||
if (!StringUtils.isEmpty(line)) {
|
return Collections.emptyMap();
|
||||||
final String[] pairs = line.split(Pattern.quote(pairSeparator));
|
}
|
||||||
final Pattern splitter = Pattern.compile(Pattern.quote(kvSeparator));
|
|
||||||
|
|
||||||
|
final Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
final String[] pairs = line.split(BAR_PAIR_SPLITTER);
|
||||||
for (final String dd : pairs) {
|
for (final String dd : pairs) {
|
||||||
final String[] v = splitter.split(dd, 2);
|
final String[] v = kvSeparator.split(dd, 2);
|
||||||
result.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
|
result.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
|
||||||
}
|
}
|
||||||
}
|
return Collections.unmodifiableMap(result);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,11 +100,10 @@ public class FileSection {
|
|||||||
* @param kvSeparator the kv separator
|
* @param kvSeparator the kv separator
|
||||||
* @return the file section
|
* @return the file section
|
||||||
*/
|
*/
|
||||||
public static FileSection parse(final Iterable<String> lines, final String kvSeparator) {
|
public static FileSection parse(final Iterable<String> lines, final Pattern kvSeparator) {
|
||||||
final FileSection result = new FileSection();
|
final FileSection result = new FileSection();
|
||||||
final Pattern splitter = Pattern.compile(Pattern.quote(kvSeparator));
|
|
||||||
for (final String dd : lines) {
|
for (final String dd : lines) {
|
||||||
final String[] v = splitter.split(dd, 2);
|
final String[] v = kvSeparator.split(dd, 2);
|
||||||
result.lines.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
|
result.lines.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final String getParamOrDefault(String key, String defaultValue) {
|
public final String getParamOrDefault(String key, String defaultValue) {
|
||||||
return hasParam(key) ? getParam(key) : defaultValue;
|
String param = mapParams.get(key);
|
||||||
|
return param != null ? param : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getParam(String key) {
|
public String getParam(String key) {
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
if (formatStrings == null){
|
if (formatStrings == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FileSection section = FileSection.parse(formatStrings, ":");
|
FileSection section = FileSection.parse(formatStrings, FileSection.COLON_KV_SEPARATOR);
|
||||||
String title = section.get("name");
|
String title = section.get("name");
|
||||||
FormatType formatType;
|
FormatType formatType;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ public final class AbilityFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<String, String> getMapParams(final String abString) {
|
public static final Map<String, String> getMapParams(final String abString) {
|
||||||
return FileSection.parseToMap(abString, "$", "|");
|
return FileSection.parseToMap(abString, FileSection.DOLLAR_SIGN_KV_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void adjustChangeZoneTarget(final Map<String, String> params, final SpellAbility sa) {
|
public static final void adjustChangeZoneTarget(final Map<String, String> params, final SpellAbility sa) {
|
||||||
|
|||||||
@@ -1893,11 +1893,11 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
sb.append("\r\n");
|
sb.append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sb.toString().endsWith("\r\n")) {
|
String result = sb.toString();
|
||||||
sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3);
|
while (result.endsWith("\r\n")) {
|
||||||
|
result = sb.substring(0, sb.length() - 2);
|
||||||
}
|
}
|
||||||
|
return TextUtil.fastReplace(result, "CARDNAME", state.getName());
|
||||||
return TextUtil.fastReplace(sb.toString(), "CARDNAME", state.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monstrous) {
|
if (monstrous) {
|
||||||
@@ -1983,8 +1983,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
boolean isNonAura = !type.hasSubtype("Aura");
|
boolean isNonAura = !type.hasSubtype("Aura");
|
||||||
|
|
||||||
for (final SpellAbility sa : state.getSpellAbilities()) {
|
for (final SpellAbility sa : state.getSpellAbilities()) {
|
||||||
// only add abilities not Spell portions of cards
|
// This code block is not shared by instants or sorceries. We don't need to check for permanence.
|
||||||
if (sa == null || sa.isSecondary() || !state.getType().isPermanent()) {
|
if (sa == null || sa.isSecondary()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2071,14 +2071,11 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// replace triple line feeds with double line feeds
|
// replace triple line feeds with double line feeds
|
||||||
int start;
|
|
||||||
final String s = "\r\n\r\n\r\n";
|
final String s = "\r\n\r\n\r\n";
|
||||||
while (sb.toString().contains(s)) {
|
int start = sb.lastIndexOf(s);
|
||||||
start = sb.lastIndexOf(s);
|
while (start != -1) {
|
||||||
if ((start < 0) || (start >= sb.length())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sb.replace(start, start + 4, "\r\n");
|
sb.replace(start, start + 4, "\r\n");
|
||||||
|
start = sb.lastIndexOf(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
String desc = TextUtil.fastReplace(sb.toString(), "CARDNAME", state.getName());
|
String desc = TextUtil.fastReplace(sb.toString(), "CARDNAME", state.getName());
|
||||||
@@ -2503,7 +2500,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final FCollectionView<SpellAbility> getIntrinsicSpellAbilities() {
|
public final Iterable<SpellAbility> getIntrinsicSpellAbilities() {
|
||||||
return currentState.getIntrinsicSpellAbilities();
|
return currentState.getIntrinsicSpellAbilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4321,8 +4318,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
/**
|
/**
|
||||||
* use it only for real keywords and not with hidden ones
|
* use it only for real keywords and not with hidden ones
|
||||||
*
|
*
|
||||||
* @param Keyword k
|
|
||||||
* @param CardState state
|
|
||||||
* @return Int
|
* @return Int
|
||||||
*/
|
*/
|
||||||
public final int getKeywordMagnitude(final Keyword k, CardState state) {
|
public final int getKeywordMagnitude(final Keyword k, CardState state) {
|
||||||
|
|||||||
@@ -273,8 +273,8 @@ public class CardState extends GameObject {
|
|||||||
return newCol;
|
return newCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final FCollectionView<SpellAbility> getIntrinsicSpellAbilities() {
|
public final Iterable<SpellAbility> getIntrinsicSpellAbilities() {
|
||||||
return new FCollection<>(Iterables.filter(getSpellAbilities(), SpellAbilityPredicates.isIntrinsic()));
|
return Iterables.filter(getSpellAbilities(), SpellAbilityPredicates.isIntrinsic());
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasSpellAbility(final SpellAbility sa) {
|
public final boolean hasSpellAbility(final SpellAbility sa) {
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ public abstract class PlayerController {
|
|||||||
public abstract List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand);
|
public abstract List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand);
|
||||||
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
||||||
|
|
||||||
public abstract String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional);
|
public abstract String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes, boolean isOptional);
|
||||||
public final String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes) {
|
public final String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes) {
|
||||||
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
|
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ public class ReplacementHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, String> parseParams(final String repParse) {
|
public static Map<String, String> parseParams(final String repParse) {
|
||||||
return FileSection.parseToMap(repParse, "$", "|");
|
return FileSection.parseToMap(repParse, FileSection.DOLLAR_SIGN_KV_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import forge.game.spellability.SpellAbilityStackInstance;
|
|||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
import forge.game.zone.Zone;
|
import forge.game.zone.Zone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.util.FileSection;
|
||||||
import forge.util.Visitor;
|
import forge.util.Visitor;
|
||||||
import io.sentry.Sentry;
|
import io.sentry.Sentry;
|
||||||
import io.sentry.event.BreadcrumbBuilder;
|
import io.sentry.event.BreadcrumbBuilder;
|
||||||
@@ -49,7 +50,6 @@ import com.google.common.collect.ArrayListMultimap;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Multimaps;
|
import com.google.common.collect.Multimaps;
|
||||||
|
|
||||||
public class TriggerHandler {
|
public class TriggerHandler {
|
||||||
@@ -172,35 +172,11 @@ public class TriggerHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> parseParams(final String trigParse) {
|
private static Map<String, String> parseParams(final String trigParse) {
|
||||||
final Map<String, String> mapParams = Maps.newHashMap();
|
|
||||||
|
|
||||||
if (trigParse.length() == 0) {
|
if (trigParse.length() == 0) {
|
||||||
throw new RuntimeException("TriggerFactory : registerTrigger -- trigParse too short");
|
throw new RuntimeException("TriggerFactory : registerTrigger -- trigParse too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] params = trigParse.split("\\|");
|
return FileSection.parseToMap(trigParse, FileSection.DOLLAR_SIGN_KV_SEPARATOR);
|
||||||
|
|
||||||
for (int i = 0; i < params.length; i++) {
|
|
||||||
params[i] = params[i].trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final String param : params) {
|
|
||||||
final String[] splitParam = param.split("\\$");
|
|
||||||
for (int i = 0; i < splitParam.length; i++) {
|
|
||||||
splitParam[i] = splitParam[i].trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (splitParam.length != 2) {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("TriggerFactory Parsing Error in registerTrigger() : Split length of ");
|
|
||||||
sb.append(param).append(" is not 2.");
|
|
||||||
throw new RuntimeException(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
mapParams.put(splitParam[0], splitParam[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapParams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectTriggerForWaiting() {
|
private void collectTriggerForWaiting() {
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ public class PlayerControllerForTests extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional) {
|
public String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes, boolean isOptional) {
|
||||||
return chooseItem(validTypes);
|
return chooseItem(validTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class CustomLimited extends DeckBase {
|
|||||||
* @return the custom limited
|
* @return the custom limited
|
||||||
*/
|
*/
|
||||||
public static CustomLimited parse(final List<String> dfData, final IStorage<Deck> cubes) {
|
public static CustomLimited parse(final List<String> dfData, final IStorage<Deck> cubes) {
|
||||||
final FileSection data = FileSection.parse(dfData, ":");
|
final FileSection data = FileSection.parse(dfData, FileSection.COLON_KV_SEPARATOR);
|
||||||
|
|
||||||
List<Pair<String, Integer>> slots = new ArrayList<>();
|
List<Pair<String, Integer>> slots = new ArrayList<>();
|
||||||
String boosterData = data.get("Booster");
|
String boosterData = data.get("Booster");
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import forge.util.storage.StorageBase;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default Model implementation for Forge.
|
* The default Model implementation for Forge.
|
||||||
@@ -259,31 +260,31 @@ public final class FModel {
|
|||||||
if (!CardType.Constant.LOADED.isSet()) {
|
if (!CardType.Constant.LOADED.isSet()) {
|
||||||
final List<String> typeListFile = FileUtil.readFile(ForgeConstants.TYPE_LIST_FILE);
|
final List<String> typeListFile = FileUtil.readFile(ForgeConstants.TYPE_LIST_FILE);
|
||||||
|
|
||||||
List<String> tList = null;
|
Set<String> addTo = null;
|
||||||
|
|
||||||
for (final String s : typeListFile) {
|
for (final String s : typeListFile) {
|
||||||
if (s.equals("[BasicTypes]")) {
|
if (s.equals("[BasicTypes]")) {
|
||||||
tList = CardType.Constant.BASIC_TYPES;
|
addTo = CardType.Constant.BASIC_TYPES;
|
||||||
} else if (s.equals("[LandTypes]")) {
|
} else if (s.equals("[LandTypes]")) {
|
||||||
tList = CardType.Constant.LAND_TYPES;
|
addTo = CardType.Constant.LAND_TYPES;
|
||||||
} else if (s.equals("[CreatureTypes]")) {
|
} else if (s.equals("[CreatureTypes]")) {
|
||||||
tList = CardType.Constant.CREATURE_TYPES;
|
addTo = CardType.Constant.CREATURE_TYPES;
|
||||||
} else if (s.equals("[SpellTypes]")) {
|
} else if (s.equals("[SpellTypes]")) {
|
||||||
tList = CardType.Constant.SPELL_TYPES;
|
addTo = CardType.Constant.SPELL_TYPES;
|
||||||
} else if (s.equals("[EnchantmentTypes]")) {
|
} else if (s.equals("[EnchantmentTypes]")) {
|
||||||
tList = CardType.Constant.ENCHANTMENT_TYPES;
|
addTo = CardType.Constant.ENCHANTMENT_TYPES;
|
||||||
} else if (s.equals("[ArtifactTypes]")) {
|
} else if (s.equals("[ArtifactTypes]")) {
|
||||||
tList = CardType.Constant.ARTIFACT_TYPES;
|
addTo = CardType.Constant.ARTIFACT_TYPES;
|
||||||
} else if (s.equals("[WalkerTypes]")) {
|
} else if (s.equals("[WalkerTypes]")) {
|
||||||
tList = CardType.Constant.WALKER_TYPES;
|
addTo = CardType.Constant.WALKER_TYPES;
|
||||||
} else if (s.length() > 1) {
|
} else if (s.length() > 1) {
|
||||||
if (tList != null) {
|
if (addTo != null) {
|
||||||
if (s.contains(":")) {
|
if (s.contains(":")) {
|
||||||
String[] k = s.split(":");
|
String[] k = s.split(":");
|
||||||
tList.add(k[0]);
|
addTo.add(k[0]);
|
||||||
CardType.Constant.pluralTypes.put(k[0], k[1]);
|
CardType.Constant.pluralTypes.put(k[0], k[1]);
|
||||||
} else {
|
} else {
|
||||||
tList.add(s);
|
addTo.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1034,7 +1034,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
* java.lang.String, java.util.List, java.util.List, java.lang.String)
|
* java.lang.String, java.util.List, java.util.List, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String chooseSomeType(final String kindOfType, final SpellAbility sa, final List<String> validTypes,
|
public String chooseSomeType(final String kindOfType, final SpellAbility sa, final Collection<String> validTypes,
|
||||||
final List<String> invalidTypes, final boolean isOptional) {
|
final List<String> invalidTypes, final boolean isOptional) {
|
||||||
final List<String> types = Lists.newArrayList(validTypes);
|
final List<String> types = Lists.newArrayList(validTypes);
|
||||||
if (invalidTypes != null && !invalidTypes.isEmpty()) {
|
if (invalidTypes != null && !invalidTypes.isEmpty()) {
|
||||||
@@ -1409,11 +1409,16 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
final boolean call) {
|
final boolean call) {
|
||||||
final String[] labelsSrc = call ? new String[] { "heads", "tails" }
|
final String[] labelsSrc = call ? new String[] { "heads", "tails" }
|
||||||
: new String[] { "win the flip", "lose the flip" };
|
: new String[] { "win the flip", "lose the flip" };
|
||||||
final ImmutableList.Builder<String> strResults = ImmutableList.builder();
|
final List<String> sortedResults = new ArrayList<String>();
|
||||||
for (int i = 0; i < results.length; i++) {
|
for (boolean result : results) {
|
||||||
strResults.add(labelsSrc[results[i] ? 0 : 1]);
|
sortedResults.add(labelsSrc[result ? 0 : 1]);
|
||||||
}
|
}
|
||||||
return getGui().one(sa.getHostCard().getName() + " - Choose a result", strResults.build()).equals(labelsSrc[0]);
|
|
||||||
|
Collections.sort(sortedResults);
|
||||||
|
if (!call) {
|
||||||
|
Collections.reverse(sortedResults);
|
||||||
|
}
|
||||||
|
return getGui().one(sa.getHostCard().getName() + " - Choose a result", sortedResults).equals(labelsSrc[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class ForgeProfileProperties {
|
|||||||
|
|
||||||
private static Map<String, String> getMap(final Properties props, final String propertyKey) {
|
private static Map<String, String> getMap(final Properties props, final String propertyKey) {
|
||||||
final String strMap = props.getProperty(propertyKey, "").trim();
|
final String strMap = props.getProperty(propertyKey, "").trim();
|
||||||
return FileSection.parseToMap(strMap, "->", "|");
|
return FileSection.parseToMap(strMap, FileSection.ARROW_KV_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getInt(final Properties props, final String propertyKey, final int defaultValue) {
|
private static int getInt(final Properties props, final String propertyKey, final int defaultValue) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class SellRules {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSection section = FileSection.parse(questShop, "=");
|
FileSection section = FileSection.parse(questShop, FileSection.EQUALS_KV_SEPARATOR);
|
||||||
minWins = section.getInt("WinsToUnlock");
|
minWins = section.getInt("WinsToUnlock");
|
||||||
cost = section.getInt("Credits", 250);
|
cost = section.getInt("Credits", 250);
|
||||||
maxDifficulty = section.getInt("MaxDifficulty", 5);
|
maxDifficulty = section.getInt("MaxDifficulty", 5);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class QuestChallengeReader extends StorageReaderFolder<QuestEventChalleng
|
|||||||
final QuestEventChallenge qc = new QuestEventChallenge();
|
final QuestEventChallenge qc = new QuestEventChallenge();
|
||||||
|
|
||||||
// Unique properties
|
// Unique properties
|
||||||
FileSection sectionQuest = FileSection.parse(contents.get("quest"), "=");
|
FileSection sectionQuest = FileSection.parse(contents.get("quest"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
qc.setId(sectionQuest.get("ID", "-1"));
|
qc.setId(sectionQuest.get("ID", "-1"));
|
||||||
qc.setOpponentName(sectionQuest.get("OpponentName"));
|
qc.setOpponentName(sectionQuest.get("OpponentName"));
|
||||||
qc.setRepeatable(sectionQuest.getBoolean("Repeat", false));
|
qc.setRepeatable(sectionQuest.getBoolean("Repeat", false));
|
||||||
@@ -60,7 +60,7 @@ public class QuestChallengeReader extends StorageReaderFolder<QuestEventChalleng
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Common properties
|
// Common properties
|
||||||
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), "=");
|
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
qc.setTitle(sectionMeta.get("Title"));
|
qc.setTitle(sectionMeta.get("Title"));
|
||||||
qc.setName(qc.getTitle()); // Challenges have unique titles
|
qc.setName(qc.getTitle()); // Challenges have unique titles
|
||||||
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
|
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class QuestDuelReader extends StorageReaderFolder<QuestEventDuel> {
|
|||||||
final QuestEventDuel qc = new QuestEventDuel();
|
final QuestEventDuel qc = new QuestEventDuel();
|
||||||
|
|
||||||
// Common properties
|
// Common properties
|
||||||
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), "=");
|
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
|
||||||
qc.setTitle(sectionMeta.get("Title"));
|
qc.setTitle(sectionMeta.get("Title"));
|
||||||
qc.setName(sectionMeta.get("Name")); // Challenges have unique titles
|
qc.setName(sectionMeta.get("Name")); // Challenges have unique titles
|
||||||
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
|
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
|
||||||
|
|||||||
Reference in New Issue
Block a user