mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Moved hasProperty code (it's forge script parsing in fact) out of CardState object to keep the class clean.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -304,6 +304,7 @@ forge-game/src/main/java/forge/GameCommand.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/CardTraitBase.java -text
|
||||
forge-game/src/main/java/forge/game/CardTraitPredicates.java -text svneol=unset#text/plain
|
||||
forge-game/src/main/java/forge/game/Direction.java -text
|
||||
forge-game/src/main/java/forge/game/ForgeScript.java -text
|
||||
forge-game/src/main/java/forge/game/Game.java -text
|
||||
forge-game/src/main/java/forge/game/GameAction.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/GameActionUtil.java svneol=native#text/plain
|
||||
|
||||
@@ -723,7 +723,6 @@ public abstract class GameState {
|
||||
|
||||
private void setupPlayerState(int life, Map<ZoneType, String> cardTexts, final Player p) {
|
||||
// Lock check static as we setup player state
|
||||
final Game game = p.getGame();
|
||||
|
||||
Map<ZoneType, CardCollectionView> playerCards = new EnumMap<ZoneType, CardCollectionView>(ZoneType.class);
|
||||
for (Entry<ZoneType, String> kv : cardTexts.entrySet()) {
|
||||
|
||||
@@ -303,7 +303,7 @@ public class GameCopier {
|
||||
newCard.setSemiPermanentToughnessBoost(c.getSemiPermanentToughnessBoost());
|
||||
newCard.setDamage(c.getDamage());
|
||||
|
||||
newCard.setChangedCardTypes(c.getChangedCardTypes());
|
||||
newCard.setChangedCardTypes(c.getChangedCardTypesMap());
|
||||
newCard.setChangedCardKeywords(c.getChangedCardKeywords());
|
||||
// TODO: Is this correct? Does it not duplicate keywords from enchantments and such?
|
||||
for (String kw : c.getHiddenExtrinsicKeywords())
|
||||
|
||||
@@ -411,11 +411,13 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardTypeView getTypeWithChanges(final Map<Long, CardChangedType> changedCardTypes) {
|
||||
if (changedCardTypes.isEmpty()) { return this; }
|
||||
public CardTypeView getTypeWithChanges(final Iterable<CardChangedType> changedCardTypes) {
|
||||
CardType newType = null;
|
||||
// we assume that changes are already correctly ordered (taken from TreeMap.values())
|
||||
for (final CardChangedType ct : changedCardTypes) {
|
||||
if(null == newType)
|
||||
newType = new CardType(CardType.this);
|
||||
|
||||
final CardType newType = new CardType(CardType.this);
|
||||
for (final CardChangedType ct : changedCardTypes.values()) {
|
||||
if (ct.isRemoveCardTypes()) {
|
||||
newType.coreTypes.clear();
|
||||
}
|
||||
@@ -441,7 +443,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
newType.addAll(ct.getAddType());
|
||||
}
|
||||
}
|
||||
return newType;
|
||||
return newType == null ? this : newType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package forge.card;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import forge.card.CardType.CoreType;
|
||||
@@ -39,5 +38,5 @@ public interface CardTypeView extends Iterable<String>, Serializable {
|
||||
boolean isPhenomenon();
|
||||
boolean isEmblem();
|
||||
boolean isTribal();
|
||||
CardTypeView getTypeWithChanges(Map<Long, CardChangedType> changedCardTypes);
|
||||
CardTypeView getTypeWithChanges(Iterable<CardChangedType> changedCardTypes);
|
||||
}
|
||||
|
||||
152
forge-game/src/main/java/forge/game/ForgeScript.java
Normal file
152
forge-game/src/main/java/forge/game/ForgeScript.java
Normal file
@@ -0,0 +1,152 @@
|
||||
package forge.game;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Expressions;
|
||||
|
||||
public class ForgeScript {
|
||||
|
||||
public static boolean cardStateHasProperty(CardState cardState, String property, Player sourceController,
|
||||
Card source, SpellAbility spellAbility) {
|
||||
|
||||
final boolean isColorlessSource = cardState.getCard().hasKeyword("Colorless Damage Source", cardState);
|
||||
final ColorSet colors = cardState.getCard().determineColor(cardState);
|
||||
if (property.contains("White") || property.contains("Blue") || property.contains("Black")
|
||||
|| property.contains("Red") || property.contains("Green")) {
|
||||
boolean mustHave = !property.startsWith("non");
|
||||
boolean withSource = property.endsWith("Source");
|
||||
if (withSource && isColorlessSource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String colorName = property.substring(mustHave ? 0 : 3, property.length() - (withSource ? 6 : 0));
|
||||
|
||||
int desiredColor = MagicColor.fromName(colorName);
|
||||
boolean hasColor = colors.hasAnyColor(desiredColor);
|
||||
if (mustHave != hasColor)
|
||||
return false;
|
||||
|
||||
} else if (property.contains("Colorless")) { // ... Card is colorless
|
||||
boolean non = property.startsWith("non");
|
||||
boolean withSource = property.endsWith("Source");
|
||||
if (non && withSource && isColorlessSource) {
|
||||
return false;
|
||||
}
|
||||
if (non == colors.isColorless()) return false;
|
||||
|
||||
} else if (property.contains("MultiColor")) {
|
||||
// ... Card is multicolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMulticolor())
|
||||
return false;
|
||||
|
||||
} else if (property.contains("MonoColor")) { // ... Card is monocolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMonoColor())
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("ChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor() || !colors.hasAnyColor(MagicColor.fromName(source.getChosenColor())))
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("AnyChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor()
|
||||
|| !colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()))
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("non")) {
|
||||
// ... Other Card types
|
||||
if (cardState.getTypeWithChanges().hasStringType(property.substring(3))) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("CostsPhyrexianMana")) {
|
||||
if (!cardState.getManaCost().hasPhyrexian()) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasSVar")) {
|
||||
final String svar = property.substring(8);
|
||||
if (!cardState.hasSVar(svar)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("ChosenType")) {
|
||||
if (!cardState.getTypeWithChanges().hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("IsNotChosenType")) {
|
||||
if (cardState.getTypeWithChanges().hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasSubtype")) {
|
||||
final String subType = property.substring(11);
|
||||
if (!cardState.getTypeWithChanges().hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasNoSubtype")) {
|
||||
final String subType = property.substring(13);
|
||||
if (cardState.getTypeWithChanges().hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("hasActivatedAbilityWithTapCost")) {
|
||||
for (final SpellAbility sa : cardState.getSpellAbilities()) {
|
||||
if (sa.isAbility() && (sa.getPayCosts() != null) && sa.getPayCosts().hasTapCost()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasActivatedAbility")) {
|
||||
for (final SpellAbility sa : cardState.getSpellAbilities()) {
|
||||
if (sa.isAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasManaAbility")) {
|
||||
for (final SpellAbility sa : cardState.getSpellAbilities()) {
|
||||
if (sa.isManaAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasNonManaActivatedAbility")) {
|
||||
for (final SpellAbility sa : cardState.getSpellAbilities()) {
|
||||
if (sa.isAbility() && !sa.isManaAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.startsWith("cmc")) {
|
||||
int x;
|
||||
String rhs = property.substring(5);
|
||||
int y = cardState.getManaCost().getCMC();
|
||||
try {
|
||||
x = Integer.parseInt(rhs);
|
||||
} catch (final NumberFormatException e) {
|
||||
x = AbilityUtils.calculateAmount(source, rhs, spellAbility);
|
||||
}
|
||||
|
||||
if (!Expressions.compare(y, property, x)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!cardState.getTypeWithChanges().hasStringType(property)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2709,10 +2709,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (changedCardTypes.isEmpty()) {
|
||||
return state.getType();
|
||||
}
|
||||
return state.getType().getTypeWithChanges(changedCardTypes);
|
||||
return state.getType().getTypeWithChanges(getChangedCardTypes());
|
||||
}
|
||||
|
||||
public Map<Long, CardChangedType> getChangedCardTypes() {
|
||||
public Iterable<CardChangedType> getChangedCardTypes() {
|
||||
return Iterables.unmodifiableIterable(changedCardTypes.values());
|
||||
}
|
||||
|
||||
public Map<Long, CardChangedType> getChangedCardTypesMap() {
|
||||
return Collections.unmodifiableMap(changedCardTypes);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ public class CardFactory {
|
||||
// information about the latest state of the card as it left the battlefield)
|
||||
out.setChangedCardColors(in.getChangedCardColors());
|
||||
out.setChangedCardKeywords(in.getChangedCardKeywords());
|
||||
out.setChangedCardTypes(in.getChangedCardTypes());
|
||||
out.setChangedCardTypes(in.getChangedCardTypesMap());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -29,19 +29,17 @@ import forge.card.CardEdition;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardType;
|
||||
import forge.card.CardTypeView;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostParser;
|
||||
import forge.game.ForgeScript;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.CardView.CardStateView;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.collect.FCollection;
|
||||
import forge.util.collect.FCollectionView;
|
||||
|
||||
@@ -377,6 +375,7 @@ public class CardState extends GameObject {
|
||||
view.updateKeywords(c, this);
|
||||
}
|
||||
|
||||
|
||||
public CardRarity getRarity() {
|
||||
return rarity;
|
||||
}
|
||||
@@ -388,6 +387,11 @@ public class CardState extends GameObject {
|
||||
public String getSetCode() {
|
||||
return setCode;
|
||||
}
|
||||
|
||||
public CardTypeView getTypeWithChanges() {
|
||||
return getType().getTypeWithChanges(card.getChangedCardTypes());
|
||||
}
|
||||
|
||||
public void setSetCode(String setCode0) {
|
||||
setCode = setCode0;
|
||||
view.updateSetCode(this);
|
||||
@@ -398,136 +402,7 @@ public class CardState extends GameObject {
|
||||
*/
|
||||
@Override
|
||||
public boolean hasProperty(String property, Player sourceController, Card source, SpellAbility spellAbility) {
|
||||
final boolean isColorlessSource = card.hasKeyword("Colorless Damage Source", this);
|
||||
final ColorSet colors = card.determineColor(this);
|
||||
if (property.contains("White") || property.contains("Blue") || property.contains("Black")
|
||||
|| property.contains("Red") || property.contains("Green")) {
|
||||
boolean mustHave = !property.startsWith("non");
|
||||
boolean withSource = property.endsWith("Source");
|
||||
if (withSource && isColorlessSource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String colorName = property.substring(mustHave ? 0 : 3, property.length() - (withSource ? 6 : 0));
|
||||
|
||||
int desiredColor = MagicColor.fromName(colorName);
|
||||
boolean hasColor = colors.hasAnyColor(desiredColor);
|
||||
if (mustHave != hasColor)
|
||||
return false;
|
||||
|
||||
} else if (property.contains("Colorless")) { // ... Card is colorless
|
||||
boolean non = property.startsWith("non");
|
||||
boolean withSource = property.endsWith("Source");
|
||||
if (non && withSource && isColorlessSource) {
|
||||
return false;
|
||||
}
|
||||
if (non == colors.isColorless()) return false;
|
||||
|
||||
} else if (property.contains("MultiColor")) {
|
||||
// ... Card is multicolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMulticolor())
|
||||
return false;
|
||||
|
||||
} else if (property.contains("MonoColor")) { // ... Card is monocolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMonoColor())
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("ChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor() || !colors.hasAnyColor(MagicColor.fromName(source.getChosenColor())))
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("AnyChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor()
|
||||
|| !colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()))
|
||||
return false;
|
||||
|
||||
} else if (property.startsWith("non")) {
|
||||
// ... Other Card types
|
||||
if (card.getType(this).hasStringType(property.substring(3))) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("CostsPhyrexianMana")) {
|
||||
if (!getManaCost().hasPhyrexian()) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasSVar")) {
|
||||
final String svar = property.substring(8);
|
||||
if (!hasSVar(svar)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("ChosenType")) {
|
||||
if (!card.getType(this).hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("IsNotChosenType")) {
|
||||
if (card.getType(this).hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasSubtype")) {
|
||||
final String subType = property.substring(11);
|
||||
if (!card.getType(this).hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("HasNoSubtype")) {
|
||||
final String subType = property.substring(13);
|
||||
if (card.getType(this).hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("hasActivatedAbilityWithTapCost")) {
|
||||
for (final SpellAbility sa : getSpellAbilities()) {
|
||||
if (sa.isAbility() && (sa.getPayCosts() != null) && sa.getPayCosts().hasTapCost()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasActivatedAbility")) {
|
||||
for (final SpellAbility sa : getSpellAbilities()) {
|
||||
if (sa.isAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasManaAbility")) {
|
||||
for (final SpellAbility sa : getSpellAbilities()) {
|
||||
if (sa.isManaAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.equals("hasNonManaActivatedAbility")) {
|
||||
for (final SpellAbility sa : getSpellAbilities()) {
|
||||
if (sa.isAbility() && !sa.isManaAbility()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (property.startsWith("cmc")) {
|
||||
int x;
|
||||
String rhs = property.substring(5);
|
||||
int y = getManaCost().getCMC();
|
||||
try {
|
||||
x = Integer.parseInt(rhs);
|
||||
} catch (final NumberFormatException e) {
|
||||
x = AbilityUtils.calculateAmount(source, rhs, spellAbility);
|
||||
}
|
||||
|
||||
if (!Expressions.compare(y, property, x)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!card.getType(this).hasStringType(property)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return ForgeScript.cardStateHasProperty(this, property, sourceController, source, spellAbility);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -538,7 +538,7 @@ public final class CardUtil {
|
||||
|
||||
newCopy.setChangedCardColors(in.getChangedCardColors());
|
||||
newCopy.setChangedCardKeywords(in.getChangedCardKeywords());
|
||||
newCopy.setChangedCardTypes(in.getChangedCardTypes());
|
||||
newCopy.setChangedCardTypes(in.getChangedCardTypesMap());
|
||||
|
||||
newCopy.setMeldedWith(in.getMeldedWith());
|
||||
|
||||
|
||||
@@ -1337,7 +1337,7 @@ public class GameSimulatorTest extends SimulationTestCase {
|
||||
public void testDeathsShadow() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(0);
|
||||
Player opp = game.getPlayers().get(1);
|
||||
//Player opp = game.getPlayers().get(1);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p);
|
||||
|
||||
addCardToZone("Platinum Angel", p, ZoneType.Battlefield);
|
||||
|
||||
Reference in New Issue
Block a user