mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Text for CantBeBlockedBy is composed in runtime
This commit is contained in:
@@ -34,11 +34,15 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Constant.CardTypes;
|
||||
import forge.card.CardCharacteristics;
|
||||
import forge.card.CardDb;
|
||||
import forge.card.CardRarity;
|
||||
@@ -2123,30 +2127,107 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
// keyword parsing takes care of adding a proper description
|
||||
continue;
|
||||
} else if (keyword.startsWith("CantBeBlockedBy")) {
|
||||
String expression = keyword.split(" ", 2)[1];
|
||||
boolean hasNon = expression.contains("non") || expression.contains("without");
|
||||
sbLong.append(this.getName()).append(" cannot be blocked ");
|
||||
if( hasNon ) sbLong.append("except ");
|
||||
sbLong.append("by ");
|
||||
String[] parts = TextUtil.split(expression, '.');
|
||||
List<String> partsAfterCreatures = new ArrayList<String>();
|
||||
for(String part : parts) {
|
||||
if( part.equalsIgnoreCase("creature"))
|
||||
continue;
|
||||
if(part.startsWith("with"))
|
||||
{
|
||||
int cutIdx = part.startsWith("without") ? 7 : 4;
|
||||
partsAfterCreatures.add(StringUtils.capitalize(part.substring(cutIdx)));
|
||||
sbLong.append(this.getName()).append(" can't be blocked ");
|
||||
|
||||
boolean negative = true;
|
||||
List<String> subs = Lists.newArrayList(TextUtil.split(keyword.split(" ", 2)[1], ','));
|
||||
List<List<String>> subsAnd = Lists.newArrayList();
|
||||
List<String> orClauses = new ArrayList<String>();
|
||||
for( int iOr = 0; iOr < subs.size(); iOr++ ) {
|
||||
String expession = subs.get(iOr);
|
||||
List<String> parts = Lists.newArrayList(expession.split("[.+]"));
|
||||
for(int p = 0; p < parts.size(); p++) {
|
||||
String part = parts.get(p);
|
||||
if( part.equalsIgnoreCase("creature")) {
|
||||
parts.remove(p--);
|
||||
continue;
|
||||
}
|
||||
// based on suppossition that each expression has at least 1 predicate except 'creature'
|
||||
negative &= part.contains("non") || part.contains("without");
|
||||
}
|
||||
else
|
||||
sbLong.append(part.toLowerCase()).append(" ");
|
||||
subsAnd.add(parts);
|
||||
}
|
||||
|
||||
final boolean allNegative = negative;
|
||||
if( allNegative ) sbLong.append("except ");
|
||||
sbLong.append("by ");
|
||||
|
||||
final Function<Pair<Boolean, String>, String> withToString = new Function<Pair<Boolean, String>, String>() {
|
||||
@Override
|
||||
public String apply(Pair<Boolean, String> inp) {
|
||||
boolean useNon = inp.getKey().booleanValue() == allNegative;
|
||||
return (useNon ? "*NO* " : "" ) + inp.getRight();
|
||||
}
|
||||
};
|
||||
|
||||
for( int iOr = 0; iOr < subsAnd.size(); iOr++ ) {
|
||||
List<String> andOperands = subsAnd.get(iOr);
|
||||
List<Pair<Boolean, String>> prependedAdjectives = Lists.newArrayList();
|
||||
List<Pair<Boolean, String>> postponedAdjectives = Lists.newArrayList();
|
||||
String creatures = null;
|
||||
|
||||
for(String part : andOperands) {
|
||||
boolean positive = true;
|
||||
if (part.startsWith("non")) {
|
||||
part = part.substring(3);
|
||||
positive = false;
|
||||
}
|
||||
if(part.startsWith("with")) {
|
||||
positive = !part.startsWith("without");
|
||||
postponedAdjectives.add(Pair.of(positive, part.substring(positive ? 4 : 7)));
|
||||
} else if ( part.startsWith("power") ) {
|
||||
int kwLength = 5;
|
||||
String opName = Expressions.operatorName(part.substring(kwLength, kwLength + 2));
|
||||
String operand = part.substring(kwLength + 2);
|
||||
postponedAdjectives.add(Pair.of(true, "power" + opName + operand));
|
||||
} else if ( forge.card.CardType.isACreatureType(part)) {
|
||||
creatures = StringUtils.capitalize(Lang.getPlural(part)) + ( creatures == null ? "" : " or " + creatures );
|
||||
} else {
|
||||
prependedAdjectives.add(Pair.of(positive, part.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sbShort = new StringBuilder();
|
||||
if ( allNegative ) {
|
||||
boolean isFirst = true;
|
||||
for(Pair<Boolean, String> pre : prependedAdjectives) {
|
||||
if ( isFirst ) isFirst = false;
|
||||
else sbShort.append(" and/or ");
|
||||
|
||||
boolean useNon = pre.getKey().booleanValue() == allNegative;
|
||||
if( useNon ) sbShort.append("non-");
|
||||
sbShort.append(pre.getValue()).append(" ").append(creatures == null ? "creatures" : creatures);
|
||||
}
|
||||
if (prependedAdjectives.isEmpty())
|
||||
sbShort.append(creatures == null ? "creatures" : creatures);
|
||||
|
||||
if(!postponedAdjectives.isEmpty()) {
|
||||
if( !prependedAdjectives.isEmpty() ) {
|
||||
sbShort.append(" and/or creatures");
|
||||
}
|
||||
|
||||
sbShort.append(" with ");
|
||||
sbShort.append(Lang.joinHomogenous(postponedAdjectives, withToString, allNegative ? "or" : "and"));
|
||||
}
|
||||
|
||||
} else {
|
||||
for(Pair<Boolean, String> pre : prependedAdjectives) {
|
||||
boolean useNon = pre.getKey().booleanValue() == allNegative;
|
||||
if( useNon ) sbShort.append("non-");
|
||||
sbShort.append(pre.getValue()).append(" ");
|
||||
}
|
||||
sbShort.append(creatures == null ? "creatures" : creatures);
|
||||
|
||||
if(!postponedAdjectives.isEmpty()) {
|
||||
sbShort.append(" with ");
|
||||
sbShort.append(Lang.joinHomogenous(postponedAdjectives, withToString, allNegative ? "or" : "and"));
|
||||
}
|
||||
|
||||
}
|
||||
orClauses.add(sbShort.toString());
|
||||
}
|
||||
sbLong.append("creatures");
|
||||
if( !partsAfterCreatures.isEmpty() ) {
|
||||
sbLong.append(" with ");
|
||||
sbLong.append(Lang.joinHomogenous(partsAfterCreatures, null, hasNon ? "or" : "and"));
|
||||
}
|
||||
|
||||
sbLong.append(StringUtils.join(orClauses, " or "));
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
@@ -64,4 +64,26 @@ public abstract class Expressions {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String operatorName(final String comp) {
|
||||
// should this function be somewhere else?
|
||||
// leftSide COMPARED to rightSide:
|
||||
if (comp.contains("LT")) {
|
||||
return " less than ";
|
||||
} else if (comp.contains("LE")) {
|
||||
return " less or equal to ";
|
||||
} else if (comp.contains("EQ")) {
|
||||
return " equal to ";
|
||||
} else if (comp.contains("GT")) {
|
||||
return " greater than ";
|
||||
} else if (comp.contains("GE")) {
|
||||
return " greater or equal to ";
|
||||
} else if (comp.contains("NE")) {
|
||||
return " not equal to ";
|
||||
} else if (comp.contains("M2")) {
|
||||
return " is modulo 2 equal to"; // should not show this to players
|
||||
}
|
||||
return " ? ";
|
||||
}
|
||||
|
||||
|
||||
} // end class AllZoneUtil
|
||||
|
||||
@@ -61,14 +61,18 @@ public class Lang {
|
||||
return subjects.size() > 1 ? verb : verb + "s";
|
||||
}
|
||||
|
||||
public static String getPlural(String noun) {
|
||||
return noun + ( noun.endsWith("s") || noun.endsWith("x") ? "es" : "s");
|
||||
}
|
||||
|
||||
public static <T> String nounWithAmount(int cnt, String noun) {
|
||||
String suffix = cnt <= 1 ? "" : ( noun.endsWith("s") || noun.endsWith("x") ? "es" : "s");
|
||||
String countedForm = cnt <= 1 ? noun : getPlural(noun);
|
||||
final String strCount;
|
||||
if( cnt == 1 )
|
||||
strCount = startsWithVowel(noun) ? "an " : "a ";
|
||||
else
|
||||
strCount = String.valueOf(cnt) + " ";
|
||||
return strCount + noun + suffix;
|
||||
return strCount + countedForm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user