mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
AbilityUtils: refactor Party types (#8967)
This commit is contained in:
@@ -547,7 +547,14 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
if (!isCreature() && !isKindred()) {
|
if (!isCreature() && !isKindred()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !Collections.disjoint(getCreatureTypes(), Constant.OUTLAW_TYPES);
|
return Constant.OUTLAW_TYPES.stream().anyMatch(s -> hasCreatureType(s));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isParty() {
|
||||||
|
if (!isCreature() && !isKindred()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Constant.PARTY_TYPES.stream().anyMatch(s -> hasCreatureType(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -916,6 +923,12 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
"Pirate",
|
"Pirate",
|
||||||
"Rogue",
|
"Rogue",
|
||||||
"Warlock");
|
"Warlock");
|
||||||
|
|
||||||
|
public static final Set<String> PARTY_TYPES = Sets.newHashSet(
|
||||||
|
"Cleric",
|
||||||
|
"Rogue",
|
||||||
|
"Warrior",
|
||||||
|
"Wizard");
|
||||||
}
|
}
|
||||||
public static class Predicates {
|
public static class Predicates {
|
||||||
public static Predicate<String> IS_LAND_TYPE = CardType::isALandType;
|
public static Predicate<String> IS_LAND_TYPE = CardType::isALandType;
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public interface CardTypeView extends Iterable<String>, Serializable {
|
|||||||
boolean isSaga();
|
boolean isSaga();
|
||||||
boolean isHistoric();
|
boolean isHistoric();
|
||||||
boolean isOutlaw();
|
boolean isOutlaw();
|
||||||
|
boolean isParty();
|
||||||
|
|
||||||
CardTypeView getTypeWithChanges(Iterable<CardChangedType> changedCardTypes);
|
CardTypeView getTypeWithChanges(Iterable<CardChangedType> changedCardTypes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ public class ForgeScript {
|
|||||||
}
|
}
|
||||||
} else if (property.equals("Outlaw")) {
|
} else if (property.equals("Outlaw")) {
|
||||||
return type.isOutlaw();
|
return type.isOutlaw();
|
||||||
|
} else if (property.equals("Party")) {
|
||||||
|
return type.isParty();
|
||||||
} else if (property.startsWith("non")) {
|
} else if (property.startsWith("non")) {
|
||||||
// ... Other Card types
|
// ... Other Card types
|
||||||
return !type.hasStringType(property.substring(3));
|
return !type.hasStringType(property.substring(3));
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.common.collect.*;
|
|||||||
import com.google.common.math.IntMath;
|
import com.google.common.math.IntMath;
|
||||||
import forge.card.CardStateName;
|
import forge.card.CardStateName;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
|
import forge.card.CardTypeView;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaAtom;
|
import forge.card.mana.ManaAtom;
|
||||||
@@ -42,6 +43,7 @@ import java.util.*;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class AbilityUtils {
|
public class AbilityUtils {
|
||||||
private final static ImmutableList<String> cmpList = ImmutableList.of("LT", "LE", "EQ", "GE", "GT", "NE");
|
private final static ImmutableList<String> cmpList = ImmutableList.of("LT", "LE", "EQ", "GE", "GT", "NE");
|
||||||
@@ -2601,61 +2603,65 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sq[0].contains("Party")) {
|
if (sq[0].contains("Party")) {
|
||||||
CardCollection adventurers = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield),
|
Set<String> chosenParty = Sets.newHashSet();
|
||||||
"Creature.Cleric,Creature.Rogue,Creature.Warrior,Creature.Wizard", player, c, ctb);
|
int wildcard = 0;
|
||||||
|
ListMultimap<String, Card> multityped = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||||
Set<String> partyTypes = Sets.newHashSet("Cleric", "Rogue", "Warrior", "Wizard");
|
List<Card> chosenMulti = Lists.newArrayList();
|
||||||
int partySize = 0;
|
|
||||||
|
|
||||||
HashMap<String, Card> chosenParty = new HashMap<>();
|
|
||||||
List<Card> wildcard = Lists.newArrayList();
|
|
||||||
HashMap<Card, Set<String>> multityped = new HashMap<>();
|
|
||||||
|
|
||||||
// Figure out how to count each class separately.
|
// Figure out how to count each class separately.
|
||||||
for (Card card : adventurers) {
|
for (Card card : player.getCardsIn(ZoneType.Battlefield)) {
|
||||||
// cards with all creature types will just return full list
|
if (!card.isCreature()) {
|
||||||
Set<String> creatureTypes = card.getType().getCreatureTypes();
|
|
||||||
creatureTypes.retainAll(partyTypes);
|
|
||||||
|
|
||||||
if (creatureTypes.size() == 4) {
|
|
||||||
wildcard.add(card);
|
|
||||||
|
|
||||||
if (wildcard.size() >= 4) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
} else if (creatureTypes.size() == 1) {
|
}
|
||||||
String type = (String)(creatureTypes.toArray()[0]);
|
CardTypeView type = card.getType();
|
||||||
|
Set<String> creatureTypes;
|
||||||
|
|
||||||
if (!chosenParty.containsKey(type)) {
|
// extra logic for "all creature types" cards
|
||||||
chosenParty.put(type, card);
|
if (type.hasAllCreatureTypes()) {
|
||||||
|
// one of the party types could be excluded, so check each of them separate
|
||||||
|
creatureTypes = CardType.Constant.PARTY_TYPES.stream().filter(p -> type.hasCreatureType(p)).collect(Collectors.toSet());
|
||||||
|
} else { // shortcut for others
|
||||||
|
creatureTypes = type.getCreatureTypes();
|
||||||
|
creatureTypes.retainAll(CardType.Constant.PARTY_TYPES);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (creatureTypes.size()) {
|
||||||
|
case 0:
|
||||||
|
continue;
|
||||||
|
case 4:
|
||||||
|
wildcard++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
chosenParty.addAll(creatureTypes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for (String t : creatureTypes) {
|
||||||
|
multityped.put(t, card);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
multityped.put(card, creatureTypes);
|
|
||||||
|
// found enough
|
||||||
|
if (chosenParty.size() + wildcard >= 4) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partySize = Math.min(chosenParty.size() + wildcard.size(), 4);
|
if (chosenParty.size() + wildcard < 4) {
|
||||||
|
multityped.keySet().removeAll(chosenParty);
|
||||||
|
|
||||||
if (partySize < 4) {
|
// sort by amount of members
|
||||||
partyTypes.removeAll(chosenParty.keySet());
|
Multimaps.asMap(multityped).entrySet().stream()
|
||||||
|
.sorted(Map.Entry.<String, List<Card>>comparingByValue(Comparator.<List<Card>>comparingInt(Collection::size)))
|
||||||
// Here I'm left with just the party types that I haven't selected.
|
.forEach(e -> {
|
||||||
for (Card multi : multityped.keySet()) {
|
e.getValue().removeAll(chosenMulti);
|
||||||
Set<String> types = multityped.get(multi);
|
if (e.getValue().size() > 0) {
|
||||||
types.retainAll(partyTypes);
|
chosenParty.add(e.getKey());
|
||||||
|
chosenMulti.add(e.getValue().get(0));
|
||||||
for (String type : types) {
|
}
|
||||||
chosenParty.put(type, multi);
|
});
|
||||||
partyTypes.remove(type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partySize = Math.min(chosenParty.size() + wildcard.size(), 4);
|
return doXMath(Math.min(chosenParty.size() + wildcard, 4), expr, c, ctb);
|
||||||
|
|
||||||
return doXMath(partySize, expr, c, ctb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make AI part to understand Sunburst better so this isn't needed
|
// TODO make AI part to understand Sunburst better so this isn't needed
|
||||||
|
|||||||
@@ -131,8 +131,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
} else if (sa.hasParam("ChooseEach")) {
|
} else if (sa.hasParam("ChooseEach")) {
|
||||||
final String s = sa.getParam("ChooseEach");
|
final String s = sa.getParam("ChooseEach");
|
||||||
final String[] types = s.equals("Party") ? new String[]{"Cleric","Rogue","Warrior","Wizard"}
|
final Collection<String> types = s.equals("Party") ? CardType.Constant.PARTY_TYPES : Arrays.asList(s.split(" & "));
|
||||||
: s.split(" & ");
|
|
||||||
for (final String type : types) {
|
for (final String type : types) {
|
||||||
CardCollection valids = CardLists.filter(pChoices, CardPredicates.isType(type));
|
CardCollection valids = CardLists.filter(pChoices, CardPredicates.isType(type));
|
||||||
if (!valids.isEmpty()) {
|
if (!valids.isEmpty()) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package forge.game.card;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.CardDb;
|
import forge.card.CardDb;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
@@ -720,17 +719,6 @@ public class CardProperty {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (property.equals("Party")) {
|
|
||||||
boolean isParty = false;
|
|
||||||
Set<String> partyTypes = Sets.newHashSet("Cleric", "Rogue", "Warrior", "Wizard");
|
|
||||||
Set<String> cTypes = card.getType().getCreatureTypes();
|
|
||||||
for (String t : partyTypes) {
|
|
||||||
if (cTypes.contains(t)) {
|
|
||||||
isParty = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isParty;
|
|
||||||
} else if (property.startsWith("sharesCreatureTypeWith")) {
|
} else if (property.startsWith("sharesCreatureTypeWith")) {
|
||||||
if (property.equals("sharesCreatureTypeWith")) {
|
if (property.equals("sharesCreatureTypeWith")) {
|
||||||
if (!card.sharesCreatureTypeWith(source)) {
|
if (!card.sharesCreatureTypeWith(source)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user