mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Keyword: link StaticAbility into it (#6079)
* Keyword: link StaticAbility into it * fix getKeywordMagnitude to check for StaticAbility
This commit is contained in:
@@ -1759,7 +1759,7 @@ public class ComputerUtilCard {
|
|||||||
pumped.addPTBoost(power + berserkPower, toughness, timestamp, 0);
|
pumped.addPTBoost(power + berserkPower, toughness, timestamp, 0);
|
||||||
|
|
||||||
if (!kws.isEmpty()) {
|
if (!kws.isEmpty()) {
|
||||||
pumped.addChangedCardKeywords(kws, null, false, timestamp, 0, false);
|
pumped.addChangedCardKeywords(kws, null, false, timestamp, null, false);
|
||||||
}
|
}
|
||||||
if (!hiddenKws.isEmpty()) {
|
if (!hiddenKws.isEmpty()) {
|
||||||
pumped.addHiddenExtrinsicKeywords(timestamp, 0, hiddenKws);
|
pumped.addHiddenExtrinsicKeywords(timestamp, 0, hiddenKws);
|
||||||
@@ -1780,7 +1780,7 @@ public class ComputerUtilCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final long timestamp2 = c.getGame().getNextTimestamp(); //is this necessary or can the timestamp be re-used?
|
final long timestamp2 = c.getGame().getNextTimestamp(); //is this necessary or can the timestamp be re-used?
|
||||||
pumped.addChangedCardKeywordsInternal(toCopy, null, false, timestamp2, 0, false);
|
pumped.addChangedCardKeywordsInternal(toCopy, null, false, timestamp2, null, false);
|
||||||
pumped.updateKeywordsCache(pumped.getCurrentState());
|
pumped.updateKeywordsCache(pumped.getCurrentState());
|
||||||
applyStaticContPT(ai.getGame(), pumped, new CardCollection(c));
|
applyStaticContPT(ai.getGame(), pumped, new CardCollection(c));
|
||||||
return pumped;
|
return pumped;
|
||||||
|
|||||||
@@ -567,6 +567,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected IHasSVars getSVarFallback() {
|
protected IHasSVars getSVarFallback() {
|
||||||
|
if (this.getKeyword() != null && this.getKeyword().getStatic() != null) {
|
||||||
|
return this.getKeyword().getStatic();
|
||||||
|
}
|
||||||
if (getCardState() != null)
|
if (getCardState() != null)
|
||||||
return getCardState();
|
return getCardState();
|
||||||
return getHostCard();
|
return getHostCard();
|
||||||
|
|||||||
@@ -485,17 +485,17 @@ public class GameAction {
|
|||||||
if (c.getCastSA() != null && !c.getCastSA().isIntrinsic() && c.getCastSA().getKeyword() != null) {
|
if (c.getCastSA() != null && !c.getCastSA().isIntrinsic() && c.getCastSA().getKeyword() != null) {
|
||||||
KeywordInterface ki = c.getCastSA().getKeyword();
|
KeywordInterface ki = c.getCastSA().getKeyword();
|
||||||
ki.setHostCard(copied);
|
ki.setHostCard(copied);
|
||||||
copied.addChangedCardKeywordsInternal(ImmutableList.of(ki), null, false, copied.getGameTimestamp(), 0, true);
|
copied.addChangedCardKeywordsInternal(ImmutableList.of(ki), null, false, copied.getGameTimestamp(), null, true);
|
||||||
}
|
}
|
||||||
// TODO hot fix for non-intrinsic offspring
|
// TODO hot fix for non-intrinsic offspring
|
||||||
Multimap<Long, KeywordInterface> addKw = MultimapBuilder.hashKeys().arrayListValues().build();
|
Multimap<StaticAbility, KeywordInterface> addKw = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||||
for (KeywordInterface kw : c.getKeywords(Keyword.OFFSPRING)) {
|
for (KeywordInterface kw : c.getKeywords(Keyword.OFFSPRING)) {
|
||||||
if (!kw.isIntrinsic()) {
|
if (!kw.isIntrinsic()) {
|
||||||
addKw.put(kw.getStaticId(), kw);
|
addKw.put(kw.getStatic(), kw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!addKw.isEmpty()) {
|
if (!addKw.isEmpty()) {
|
||||||
for (Map.Entry<Long, Collection<KeywordInterface>> e : addKw.asMap().entrySet()) {
|
for (Map.Entry<StaticAbility, Collection<KeywordInterface>> e : addKw.asMap().entrySet()) {
|
||||||
copied.addChangedCardKeywordsInternal(e.getValue(), null, false, copied.getGameTimestamp(), e.getKey(), true);
|
copied.addChangedCardKeywordsInternal(e.getValue(), null, false, copied.getGameTimestamp(), e.getKey(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,7 +601,7 @@ public class GameAction {
|
|||||||
// 400.7g try adding keyword back into card if it doesn't already have it
|
// 400.7g try adding keyword back into card if it doesn't already have it
|
||||||
if (zoneTo.is(ZoneType.Stack) && cause != null && cause.isSpell() && !cause.isIntrinsic() && c.equals(cause.getHostCard())) {
|
if (zoneTo.is(ZoneType.Stack) && cause != null && cause.isSpell() && !cause.isIntrinsic() && c.equals(cause.getHostCard())) {
|
||||||
if (cause.getKeyword() != null && !copied.getKeywords().contains(cause.getKeyword())) {
|
if (cause.getKeyword() != null && !copied.getKeywords().contains(cause.getKeyword())) {
|
||||||
copied.addChangedCardKeywordsInternal(ImmutableList.of(cause.getKeyword()), null, false, game.getNextTimestamp(), 0, true);
|
copied.addChangedCardKeywordsInternal(ImmutableList.of(cause.getKeyword()), null, false, game.getNextTimestamp(), null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
|||||||
params.put("Category", "Keywords");
|
params.put("Category", "Keywords");
|
||||||
c.addPerpetual(params);
|
c.addPerpetual(params);
|
||||||
}
|
}
|
||||||
c.addChangedCardKeywords(keywords, removeKeywords, removeAll, timestamp, 0);
|
c.addChangedCardKeywords(keywords, removeKeywords, removeAll, timestamp, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do this after changing types in case it wasn't a creature before
|
// do this after changing types in case it wasn't a creature before
|
||||||
|
|||||||
@@ -672,7 +672,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("Unearth") && movedCard.isInPlay()) {
|
if (sa.hasParam("Unearth") && movedCard.isInPlay()) {
|
||||||
movedCard.setUnearthed(true);
|
movedCard.setUnearthed(true);
|
||||||
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false,
|
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false,
|
||||||
game.getNextTimestamp(), 0, true);
|
game.getNextTimestamp(), null, true);
|
||||||
registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard));
|
registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard));
|
||||||
addLeaveBattlefieldReplacement(movedCard, sa, "Exile");
|
addLeaveBattlefieldReplacement(movedCard, sa, "Exile");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pumpKeywords.isEmpty()) {
|
if (!pumpKeywords.isEmpty()) {
|
||||||
tgtCard.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, ts, 0);
|
tgtCard.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, ts, null);
|
||||||
TokenEffectBase.addPumpUntil(sa, tgtCard, ts);
|
TokenEffectBase.addPumpUntil(sa, tgtCard, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (keywords != null) {
|
if (keywords != null) {
|
||||||
tgtC.addChangedCardKeywords(keywords, Lists.newArrayList(), false, tStamp, 0);
|
tgtC.addChangedCardKeywords(keywords, Lists.newArrayList(), false, tStamp, null);
|
||||||
game.fireEvent(new GameEventCardStatsChanged(tgtC));
|
game.fireEvent(new GameEventCardStatsChanged(tgtC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ public class DebuffEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removedKW.addAll(kws);
|
removedKW.addAll(kws);
|
||||||
tgtC.addChangedCardKeywords(addedKW, removedKW, false, timestamp, 0);
|
tgtC.addChangedCardKeywords(addedKW, removedKW, false, timestamp, null);
|
||||||
|
|
||||||
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
||||||
final GameCommand until = new GameCommand() {
|
final GameCommand until = new GameCommand() {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
|
|||||||
CardCollectionView list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), valid, sa.getActivatingPlayer(), host, sa);
|
CardCollectionView list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), valid, sa.getActivatingPlayer(), host, sa);
|
||||||
|
|
||||||
for (final Card tgtC : list) {
|
for (final Card tgtC : list) {
|
||||||
tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, 0, true);
|
tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, null, true);
|
||||||
|
|
||||||
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
||||||
// If not Permanent, remove protection at EOT
|
// If not Permanent, remove protection at EOT
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, 0, true);
|
tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, null, true);
|
||||||
|
|
||||||
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
if (!"Permanent".equals(sa.getParam("Duration"))) {
|
||||||
// If not Permanent, remove protection at EOT
|
// If not Permanent, remove protection at EOT
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
|||||||
params.put("Category", "Keywords");
|
params.put("Category", "Keywords");
|
||||||
tgtC.addPerpetual(params);
|
tgtC.addPerpetual(params);
|
||||||
}
|
}
|
||||||
tgtC.addChangedCardKeywords(kws, null, false, timestamp, 0);
|
tgtC.addChangedCardKeywords(kws, null, false, timestamp, null);
|
||||||
}
|
}
|
||||||
if (redrawPT) {
|
if (redrawPT) {
|
||||||
tgtC.updatePowerToughnessForView();
|
tgtC.updatePowerToughnessForView();
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
|||||||
params.put("Category", "Keywords");
|
params.put("Category", "Keywords");
|
||||||
gameCard.addPerpetual(params);
|
gameCard.addPerpetual(params);
|
||||||
}
|
}
|
||||||
gameCard.addChangedCardKeywords(kws, Lists.newArrayList(), false, timestamp, 0);
|
gameCard.addChangedCardKeywords(kws, Lists.newArrayList(), false, timestamp, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!hiddenKws.isEmpty()) {
|
if (!hiddenKws.isEmpty()) {
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pumpKeywords.isEmpty()) {
|
if (!pumpKeywords.isEmpty()) {
|
||||||
moved.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, timestamp, 0);
|
moved.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, timestamp, null);
|
||||||
addPumpUntil(sa, moved, timestamp);
|
addPumpUntil(sa, moved, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1696,7 +1696,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
if (!Keyword.smartValueOf(counterType.toString().split(":")[0]).isMultipleRedundant()) {
|
if (!Keyword.smartValueOf(counterType.toString().split(":")[0]).isMultipleRedundant()) {
|
||||||
num = getCounters(counterType);
|
num = getCounters(counterType);
|
||||||
}
|
}
|
||||||
addChangedCardKeywords(Collections.nCopies(num, counterType.toString()), null, false, timestamp, 0, updateView);
|
addChangedCardKeywords(Collections.nCopies(num, counterType.toString()), null, false, timestamp, null, updateView);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4657,7 +4657,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
} else if (category.equals("Keywords")) {
|
} else if (category.equals("Keywords")) {
|
||||||
boolean removeAll = p.containsKey("RemoveAll") && (boolean) p.get("RemoveAll") == true;
|
boolean removeAll = p.containsKey("RemoveAll") && (boolean) p.get("RemoveAll") == true;
|
||||||
addChangedCardKeywords((List<String>) p.get("AddKeywords"), Lists.newArrayList(), removeAll,
|
addChangedCardKeywords((List<String>) p.get("AddKeywords"), Lists.newArrayList(), removeAll,
|
||||||
(long) p.get("Timestamp"), (long) 0);
|
(long) p.get("Timestamp"), null);
|
||||||
} else if (category.equals("Types")) {
|
} else if (category.equals("Types")) {
|
||||||
addChangedCardTypes((CardType) p.get("AddTypes"), (CardType) p.get("RemoveTypes"),
|
addChangedCardTypes((CardType) p.get("AddTypes"), (CardType) p.get("RemoveTypes"),
|
||||||
false, (Set<RemoveType>) p.get("RemoveXTypes"),
|
false, (Set<RemoveType>) p.get("RemoveXTypes"),
|
||||||
@@ -4963,7 +4963,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
KeywordInterface result = storedKeywordByText.get(triple);
|
KeywordInterface result = storedKeywordByText.get(triple);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = ki.copy(this, false);
|
result = ki.copy(this, false);
|
||||||
result.setStaticId(stAb.getId());
|
result.setStatic(stAb);
|
||||||
result.setIdx(idx);
|
result.setIdx(idx);
|
||||||
result.setIntrinsic(true);
|
result.setIntrinsic(true);
|
||||||
storedKeywordByText.put(triple, result);
|
storedKeywordByText.put(triple, result);
|
||||||
@@ -5086,11 +5086,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
||||||
final boolean removeAllKeywords, final long timestamp, final long staticId) {
|
final boolean removeAllKeywords, final long timestamp, final StaticAbility st) {
|
||||||
addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, timestamp, staticId, true);
|
addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, timestamp, st, true);
|
||||||
}
|
}
|
||||||
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
||||||
final boolean removeAllKeywords, final long timestamp, final long staticId, final boolean updateView) {
|
final boolean removeAllKeywords, final long timestamp, final StaticAbility st, final boolean updateView) {
|
||||||
List<KeywordInterface> kws = Lists.newArrayList();
|
List<KeywordInterface> kws = Lists.newArrayList();
|
||||||
if (keywords != null) {
|
if (keywords != null) {
|
||||||
long idx = 1;
|
long idx = 1;
|
||||||
@@ -5104,14 +5104,14 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (canHave) {
|
if (canHave) {
|
||||||
kws.add(getKeywordForStaticAbility(kw, staticId, idx));
|
kws.add(getKeywordForStaticAbility(kw, st, idx));
|
||||||
}
|
}
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final KeywordsChange newCks = new KeywordsChange(kws, removeKeywords, removeAllKeywords);
|
final KeywordsChange newCks = new KeywordsChange(kws, removeKeywords, removeAllKeywords);
|
||||||
changedCardKeywords.put(timestamp, staticId, newCks);
|
changedCardKeywords.put(timestamp, st == null ? 0l : st.getId(), newCks);
|
||||||
|
|
||||||
if (updateView) {
|
if (updateView) {
|
||||||
updateKeywords();
|
updateKeywords();
|
||||||
@@ -5120,12 +5120,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final KeywordInterface getKeywordForStaticAbility(String kw, final long staticId, final long idx) {
|
public final KeywordInterface getKeywordForStaticAbility(String kw, final StaticAbility st, final long idx) {
|
||||||
KeywordInterface result;
|
KeywordInterface result;
|
||||||
|
long staticId = st == null ? 0 : st.getId();
|
||||||
Triple<String, Long, Long> triple = Triple.of(kw, staticId, idx);
|
Triple<String, Long, Long> triple = Triple.of(kw, staticId, idx);
|
||||||
if (staticId < 1 || !storedKeywords.containsKey(triple)) {
|
if (staticId < 1 || !storedKeywords.containsKey(triple)) {
|
||||||
result = Keyword.getInstance(kw);
|
result = Keyword.getInstance(kw);
|
||||||
result.setStaticId(staticId);
|
result.setStatic(st);
|
||||||
result.setIdx(idx);
|
result.setIdx(idx);
|
||||||
result.createTraits(this, false);
|
result.createTraits(this, false);
|
||||||
if (staticId > 0) {
|
if (staticId > 0) {
|
||||||
@@ -5138,8 +5139,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void addKeywordForStaticAbility(KeywordInterface kw) {
|
public final void addKeywordForStaticAbility(KeywordInterface kw) {
|
||||||
if (kw.getStaticId() > 0) {
|
if (kw.getStatic() != null) {
|
||||||
storedKeywords.put(Triple.of(kw.getOriginal(), kw.getStaticId(), kw.getIdx()), kw);
|
storedKeywords.put(Triple.of(kw.getOriginal(), (long)kw.getStatic().getId(), kw.getIdx()), kw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5184,8 +5185,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
public final void addChangedCardKeywordsInternal(
|
public final void addChangedCardKeywordsInternal(
|
||||||
final Collection<KeywordInterface> keywords, final Collection<KeywordInterface> removeKeywords,
|
final Collection<KeywordInterface> keywords, final Collection<KeywordInterface> removeKeywords,
|
||||||
final boolean removeAllKeywords,
|
final boolean removeAllKeywords,
|
||||||
final long timestamp, final long staticId, final boolean updateView) {
|
final long timestamp, final StaticAbility st, final boolean updateView) {
|
||||||
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords, removeAllKeywords);
|
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords, removeAllKeywords);
|
||||||
|
long staticId = st == null ? 0 : st.getId();
|
||||||
changedCardKeywords.put(timestamp, staticId, newCks);
|
changedCardKeywords.put(timestamp, staticId, newCks);
|
||||||
|
|
||||||
if (updateView) {
|
if (updateView) {
|
||||||
@@ -5821,9 +5823,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
if (StringUtils.isNumeric(s)) {
|
if (StringUtils.isNumeric(s)) {
|
||||||
count += Integer.parseInt(s);
|
count += Integer.parseInt(s);
|
||||||
} else {
|
} else {
|
||||||
String svar = StringUtils.join(parse);
|
StaticAbility st = inst.getStatic();
|
||||||
if (state.hasSVar(svar)) {
|
// TODO make keywordinterface inherit from CardTrait somehow, or invent new interface
|
||||||
count += AbilityUtils.calculateAmount(this, state.getSVar(svar), null);
|
if (st != null && st.hasSVar(s)) {
|
||||||
|
count += AbilityUtils.calculateAmount(this, st.getSVar(s), null);
|
||||||
|
} else {
|
||||||
|
String svar = StringUtils.join(parse);
|
||||||
|
if (state.hasSVar(svar)) {
|
||||||
|
count += AbilityUtils.calculateAmount(this, state.getSVar(svar), null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6568,7 +6576,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
suspectedTimestamp = getGame().getNextTimestamp();
|
suspectedTimestamp = getGame().getNextTimestamp();
|
||||||
|
|
||||||
// use this for CantHaveKeyword
|
// use this for CantHaveKeyword
|
||||||
addChangedCardKeywords(ImmutableList.of("Menace"), ImmutableList.<String>of(), false, suspectedTimestamp, 0, true);
|
addChangedCardKeywords(ImmutableList.of("Menace"), ImmutableList.<String>of(), false, suspectedTimestamp, null, true);
|
||||||
|
|
||||||
if (suspectedStatic == null) {
|
if (suspectedStatic == null) {
|
||||||
String effect = "Mode$ CantBlockBy | ValidBlocker$ Creature.Self | Description$ CARDNAME can't block.";
|
String effect = "Mode$ CantBlockBy | ValidBlocker$ Creature.Self | Description$ CARDNAME can't block.";
|
||||||
@@ -6719,7 +6727,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
new CardType(Collections.singletonList("Creature"), true),
|
new CardType(Collections.singletonList("Creature"), true),
|
||||||
false, EnumSet.of(RemoveType.EnchantmentTypes), bestowTimestamp, 0, updateView, false);
|
false, EnumSet.of(RemoveType.EnchantmentTypes), bestowTimestamp, 0, updateView, false);
|
||||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(),
|
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(),
|
||||||
false, bestowTimestamp, 0, updateView);
|
false, bestowTimestamp, null, updateView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void unanimateBestow() {
|
public final void unanimateBestow() {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
|||||||
|
|
||||||
private Keyword keyword;
|
private Keyword keyword;
|
||||||
private String original;
|
private String original;
|
||||||
private long staticId = 0;
|
private StaticAbility st = null;
|
||||||
private long idx = -1;
|
private long idx = -1;
|
||||||
|
|
||||||
private List<Trigger> triggers = Lists.newArrayList();
|
private List<Trigger> triggers = Lists.newArrayList();
|
||||||
@@ -367,11 +367,11 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStaticId() {
|
public StaticAbility getStatic() {
|
||||||
return this.staticId;
|
return this.st;
|
||||||
}
|
}
|
||||||
public void setStaticId(long v) {
|
public void setStatic(StaticAbility st) {
|
||||||
this.staticId = v;
|
this.st = st;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIdx() {
|
public long getIdx() {
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ public interface KeywordInterface extends Cloneable {
|
|||||||
String getReminderText();
|
String getReminderText();
|
||||||
|
|
||||||
int getAmount();
|
int getAmount();
|
||||||
long getStaticId();
|
|
||||||
void setStaticId(long v);
|
StaticAbility getStatic();
|
||||||
|
void setStatic(StaticAbility st);
|
||||||
|
|
||||||
long getIdx();
|
long getIdx();
|
||||||
void setIdx(long i);
|
void setIdx(long i);
|
||||||
|
|
||||||
|
|||||||
@@ -705,7 +705,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
mana.getSourceCard().getController(), mana.getSourceCard(), null)) {
|
mana.getSourceCard().getController(), mana.getSourceCard(), null)) {
|
||||||
final long timestamp = host.getGame().getNextTimestamp();
|
final long timestamp = host.getGame().getNextTimestamp();
|
||||||
final List<String> kws = Arrays.asList(mana.getAddedKeywords().split(" & "));
|
final List<String> kws = Arrays.asList(mana.getAddedKeywords().split(" & "));
|
||||||
host.addChangedCardKeywords(kws, null, false, timestamp, 0);
|
host.addChangedCardKeywords(kws, null, false, timestamp, null);
|
||||||
if (mana.addsKeywordsUntil()) {
|
if (mana.addsKeywordsUntil()) {
|
||||||
final GameCommand untilEOT = new GameCommand() {
|
final GameCommand untilEOT = new GameCommand() {
|
||||||
private static final long serialVersionUID = -8285169579025607693L;
|
private static final long serialVersionUID = -8285169579025607693L;
|
||||||
@@ -2590,7 +2590,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasOptionalKeywordAmount(KeywordInterface kw) {
|
public boolean hasOptionalKeywordAmount(KeywordInterface kw) {
|
||||||
return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId()));
|
long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId();
|
||||||
|
return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), staticId));
|
||||||
}
|
}
|
||||||
public boolean hasOptionalKeywordAmount(Keyword kw) {
|
public boolean hasOptionalKeywordAmount(Keyword kw) {
|
||||||
return this.optionalKeywordAmount.containsRow(kw);
|
return this.optionalKeywordAmount.containsRow(kw);
|
||||||
@@ -2600,13 +2601,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getOptionalKeywordAmount(KeywordInterface kw) {
|
public int getOptionalKeywordAmount(KeywordInterface kw) {
|
||||||
return ObjectUtils.firstNonNull(this.optionalKeywordAmount.get(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId())), 0);
|
long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId();
|
||||||
|
return ObjectUtils.firstNonNull(this.optionalKeywordAmount.get(kw.getKeyword(), Pair.of(kw.getIdx(), staticId)), 0);
|
||||||
}
|
}
|
||||||
public int getOptionalKeywordAmount(Keyword kw) {
|
public int getOptionalKeywordAmount(Keyword kw) {
|
||||||
return this.optionalKeywordAmount.row(kw).values().stream().mapToInt(i->i).sum();
|
return this.optionalKeywordAmount.row(kw).values().stream().mapToInt(i->i).sum();
|
||||||
}
|
}
|
||||||
public void setOptionalKeywordAmount(KeywordInterface kw, int amount) {
|
public void setOptionalKeywordAmount(KeywordInterface kw, int amount) {
|
||||||
this.optionalKeywordAmount.put(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId()), amount);
|
long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId();
|
||||||
|
this.optionalKeywordAmount.put(kw.getKeyword(), Pair.of(kw.getIdx(), staticId), amount);
|
||||||
}
|
}
|
||||||
public void clearOptionalKeywordAmount() {
|
public void clearOptionalKeywordAmount() {
|
||||||
optionalKeywordAmount.clear();
|
optionalKeywordAmount.clear();
|
||||||
|
|||||||
@@ -770,7 +770,7 @@ public final class StaticAbilityContinuous {
|
|||||||
}
|
}
|
||||||
|
|
||||||
affectedCard.addChangedCardKeywords(newKeywords, removeKeywords,
|
affectedCard.addChangedCardKeywords(newKeywords, removeKeywords,
|
||||||
removeAllAbilities, se.getTimestamp(), stAb.getId(), true);
|
removeAllAbilities, se.getTimestamp(), stAb, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add HIDDEN keywords
|
// add HIDDEN keywords
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Fumiko the Lowblood
|
|||||||
ManaCost:2 R R
|
ManaCost:2 R R
|
||||||
Types:Legendary Creature Human Samurai
|
Types:Legendary Creature Human Samurai
|
||||||
PT:3/2
|
PT:3/2
|
||||||
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Bushido:N | CalcKeywordN$ N | Description$ CARDNAME has bushido X, where X is the number of attacking creatures.
|
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Bushido:X | Description$ CARDNAME has bushido X, where X is the number of attacking creatures.
|
||||||
SVar:N:Count$Valid Creature.attacking
|
SVar:X:Count$Valid Creature.attacking
|
||||||
S:Mode$ MustAttack | ValidCreature$ Creature.OppCtrl | Description$ Creatures your opponents control attack each combat if able.
|
S:Mode$ MustAttack | ValidCreature$ Creature.OppCtrl | Description$ Creatures your opponents control attack each combat if able.
|
||||||
Oracle:Fumiko the Lowblood has bushido X, where X is the number of attacking creatures. (Whenever this creature blocks or becomes blocked, it gets +X/+X until end of turn.)\nCreatures your opponents control attack each combat if able.
|
Oracle:Fumiko the Lowblood has bushido X, where X is the number of attacking creatures. (Whenever this creature blocks or becomes blocked, it gets +X/+X until end of turn.)\nCreatures your opponents control attack each combat if able.
|
||||||
|
|||||||
Reference in New Issue
Block a user