Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions forge-core/src/main/java/forge/card/CardType.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ public boolean remove(final Supertype st) {
return supertypes.remove(st);
}

@Deprecated
public boolean remove(final String str) {
boolean changed = false;

Expand Down Expand Up @@ -681,6 +682,14 @@ public int compareTo(final CardType o) {
return toString().compareTo(o.toString());
}

@Override
public boolean equals(final Object o) {
if (!(o instanceof CardType)) {
return false;
}
return toString().equals(o.toString());
}

public boolean sharesCreaturetypeWith(final CardTypeView ctOther) {
if (ctOther == null) {
return false;
Expand Down
23 changes: 23 additions & 0 deletions forge-core/src/main/java/forge/card/ChangedColorWord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package forge.card;

import java.util.Map;

public record ChangedColorWord(MagicColor.Color oldColor, MagicColor.Color newColor) implements IChangedText {

@Override
public void applyColorChanges(Map<MagicColor.Color, MagicColor.Color> result) {
if (oldColor == null) {
for (MagicColor.Color old : ColorSet.WUBRG) {
result.put(old, newColor);
}
} else {
for (Map.Entry<MagicColor.Color, MagicColor.Color> e : result.entrySet()) {
if (e.getValue().equals(oldColor)) {
e.setValue(newColor);
}
}
result.put(oldColor, newColor);
}

}
}
8 changes: 8 additions & 0 deletions forge-core/src/main/java/forge/card/IChangedText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package forge.card;

import java.util.Map;

public interface IChangedText {
default void applyColorChanges(Map<MagicColor.Color, MagicColor.Color> result) { }
default void applyTypeChanges(Map<String, String> result) { }
}
13 changes: 13 additions & 0 deletions forge-core/src/main/java/forge/card/ITextChanges.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package forge.card;

import java.util.Map;

public interface ITextChanges {
Map<MagicColor.Color, MagicColor.Color> colorChanges();
Map<String, String> typeChanges();

boolean isEmpty();

ITextChanges combine(ITextChanges output);
default ITextChanges getView() { return this; }
}
16 changes: 16 additions & 0 deletions forge-core/src/main/java/forge/card/ResetChangedText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package forge.card;

import java.util.Map;

public record ResetChangedText() implements IChangedText {

@Override
public void applyColorChanges(Map<MagicColor.Color, MagicColor.Color> result) {
result.clear();
}
@Override
public void applyTypeChanges(Map<String, String> result) {
result.clear();
}

}
79 changes: 79 additions & 0 deletions forge-core/src/main/java/forge/card/TextChanges.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package forge.card;

import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.google.common.collect.TreeBasedTable;

import java.util.Map;

public class TextChanges implements ITextChanges {

public static ITextChanges EMPTY = TextChangesView.EMPTY;

private final Table<Long, Long, IChangedText> map = TreeBasedTable.create();
private final Map<MagicColor.Color, MagicColor.Color> colorChanges = Maps.newHashMap();
private final Map<String, String> typeChanges = Maps.newHashMap();
private boolean isDirty = false;

public long add(final long timestamp, final long staticId, final IChangedText changes) {
map.put(timestamp, staticId, changes);
isDirty = true;
return timestamp;
}

public boolean remove(final long timestamp, final long staticId) {
isDirty = true;
return map.remove(timestamp, staticId) != null;
}

public void clear() {
map.clear();
colorChanges.clear();
typeChanges.clear();
isDirty = false;
}
public void copyFrom(final TextChanges other) {
map.clear();
map.putAll(other.map);
isDirty = true;
}

@Override
public boolean isEmpty() {
return map.isEmpty();
}

@Override
public Map<MagicColor.Color, MagicColor.Color> colorChanges() {
refreshCache();
return this.colorChanges;
}

@Override
public Map<String, String> typeChanges() {
refreshCache();
return this.typeChanges;
}

private void refreshCache() {
if (isDirty) {
colorChanges.clear();
typeChanges.clear();
for (final IChangedText changes : this.map.values()) {
changes.applyColorChanges(colorChanges);
changes.applyTypeChanges(typeChanges);
}
isDirty = false;
}
}

@Override
public TextChangesView getView() {
return new TextChangesView(colorChanges(), typeChanges());
}

@Override
public ITextChanges combine(ITextChanges output) {
return getView().combine(output);
}
}
47 changes: 47 additions & 0 deletions forge-core/src/main/java/forge/card/TextChangesView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package forge.card;

import com.google.common.collect.Maps;

import java.util.Map;

public record TextChangesView(Map<MagicColor.Color, MagicColor.Color> colorChanges, Map<String, String> typeChanges) implements ITextChanges {

public static TextChangesView EMPTY = new TextChangesView(Map.of(), Map.of());

@Override
public boolean isEmpty() {
return colorChanges.isEmpty() && typeChanges.isEmpty();
}

@Override
public ITextChanges combine(ITextChanges output) {
if (output.isEmpty()) {
return this;
}
if (this.isEmpty()) {
return output;
};

return new TextChangesView(
_combineChangedMap(colorChanges(), output.colorChanges()),
_combineChangedMap(typeChanges(), output.typeChanges())
);
}

private <T> Map<T, T> _combineChangedMap(Map<T, T> input, Map<T, T> output) {
// no need to do something, just return hash
if (input.isEmpty()) {
return output;
}
if (output.isEmpty()) {
return input;
}
// magic combine them
Map<T, T> result = Maps.newHashMap(input);
for (Map.Entry<T, T> e : result.entrySet()) {
e.setValue(output.getOrDefault(e.getValue(), e.getValue()));
}
result.putAll(output);
return result;
}
}
14 changes: 13 additions & 1 deletion forge-core/src/main/java/forge/card/WordChangedType.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package forge.card;

public record WordChangedType(String oldWord, String newWord) implements ICardChangedType {
import java.util.Map;

public record WordChangedType(String oldWord, String newWord) implements ICardChangedType, IChangedText {

@Override
public CardType applyChanges(CardType newType) {
Expand All @@ -10,4 +12,14 @@ public CardType applyChanges(CardType newType) {
}
return newType;
}

@Override
public void applyTypeChanges(Map<String, String> result) {
for (Map.Entry<String, String> e : result.entrySet()) {
if (e.getValue().equals(oldWord)) {
e.setValue(newWord);
}
}
result.put(oldWord, newWord);
}
}
44 changes: 11 additions & 33 deletions forge-game/src/main/java/forge/game/CardTraitBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import com.google.common.collect.Lists;

import forge.card.CardStateName;
import forge.card.ITextChanges;
import forge.card.MagicColor;
import forge.card.TextChanges;
import forge.card.mana.ManaAtom;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
Expand Down Expand Up @@ -55,10 +57,8 @@ public abstract class CardTraitBase implements GameObject, IHasCardView, IHasSVa

protected Map<String, String> sVars = Maps.newTreeMap();

protected Map<String, String> intrinsicChangedTextColors = Maps.newHashMap();
protected Map<String, String> intrinsicChangedTextTypes = Maps.newHashMap();
protected Map<String, String> changedTextColors = Maps.newHashMap();
protected Map<String, String> changedTextTypes = Maps.newHashMap();
protected ITextChanges intrinsicTextChanges = TextChanges.EMPTY;
protected ITextChanges textChanges = TextChanges.EMPTY;

/** Keys of descriptive (text) parameters. */
private static final ImmutableList<String> descriptiveKeys = ImmutableList.<String>builder()
Expand Down Expand Up @@ -658,45 +658,24 @@ public boolean isCopiedTrait() {
return !getHostCard().equals(getCardState().getCard());
}

public Map<String, String> getChangedTextColors() {
return _combineChangedMap(intrinsicChangedTextColors, changedTextColors);
}
public Map<String, String> getChangedTextTypes() {
return _combineChangedMap(intrinsicChangedTextTypes, changedTextTypes);
}

private Map<String, String> _combineChangedMap(Map<String, String> input, Map<String, String> output) {
// no need to do something, just return hash
if (input.isEmpty()) {
return output;
}
if (output.isEmpty()) {
return input;
}
// magic combine them
Map<String, String> result = Maps.newHashMap(output);
for (Map.Entry<String, String> e : input.entrySet()) {
String value = e.getValue();
result.put(e.getKey(), output.getOrDefault(value, value));
}
return result;
public ITextChanges getTextChanges() {
return intrinsicTextChanges.combine(textChanges);
}

public void changeTextIntrinsic(Map<String,String> colorMap, Map<String,String> typeMap) {
intrinsicChangedTextColors = colorMap;
intrinsicChangedTextTypes = typeMap;
public void changeTextIntrinsic(ITextChanges textChanges) {
this.intrinsicTextChanges = textChanges.getView();
for (final String key : this.mapParams.keySet()) {
final String value = this.originalMapParams.get(key), newValue;
if (noChangeKeys.contains(key)) {
continue;
} else if (descriptiveKeys.contains(key)) {
// change descriptions differently
newValue = AbilityUtils.applyTextChangeEffects(value, true, colorMap, typeMap);
newValue = AbilityUtils.applyTextChangeEffects(value, true, textChanges);
} else if (this.getHostCard().hasSVar(value)) {
// don't change literal SVar names!
continue;
} else {
newValue = AbilityUtils.applyTextChangeEffects(value, false, colorMap, typeMap);
newValue = AbilityUtils.applyTextChangeEffects(value, false, textChanges);
}

if (newValue != null) {
Expand All @@ -709,8 +688,7 @@ public void changeTextIntrinsic(Map<String,String> colorMap, Map<String,String>

public void changeText() {
// copy changed text words into card trait there
this.changedTextColors = getHostCard().getChangedTextColorWords();
this.changedTextTypes = getHostCard().getChangedTextTypeWords();
this.textChanges = getHostCard().getTextChanges().getView();

for (final String key : this.mapParams.keySet()) {
final String value = this.originalMapParams.get(key), newValue;
Expand Down
11 changes: 4 additions & 7 deletions forge-game/src/main/java/forge/game/TriggerReplacementBase.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package forge.game;

import java.util.EnumSet;
import java.util.Map;
import java.util.Set;

import forge.card.ITextChanges;
import forge.game.card.Card;
import forge.game.card.CardState;
import forge.game.keyword.KeywordInterface;
Expand Down Expand Up @@ -104,17 +104,14 @@ public void changeText() {
}
}

/* (non-Javadoc)
* @see forge.game.CardTraitBase#changeTextIntrinsic(java.util.Map, java.util.Map)
*/
@Override
public void changeTextIntrinsic(Map<String, String> colorMap, Map<String, String> typeMap) {
super.changeTextIntrinsic(colorMap, typeMap);
public void changeTextIntrinsic(ITextChanges textChanges) {
super.changeTextIntrinsic(textChanges);

SpellAbility sa = ensureAbility();

if (sa != null) {
sa.changeTextIntrinsic(colorMap, typeMap);
sa.changeTextIntrinsic(textChanges);
}
}
}
Loading
Loading