mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
Try to keep original card and not migrate to new card
This commit is contained in:
@@ -338,13 +338,10 @@ public class GameAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update state for view
|
// update state for view
|
||||||
copied.updateStateForView();
|
|
||||||
if (copied.isMerged()) {
|
if (copied.isMerged()) {
|
||||||
if (copied.getMergedToCard() != null) {
|
|
||||||
copied.getMergedToCard().updateStateForView();
|
copied.getMergedToCard().updateStateForView();
|
||||||
} else {
|
} else {
|
||||||
copied.getMergedCards().get(0).updateStateForView();
|
copied.updateStateForView();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromBattlefield) {
|
if (fromBattlefield) {
|
||||||
|
|||||||
@@ -47,17 +47,17 @@ public class MutateEffect extends SpellAbilityEffect {
|
|||||||
);
|
);
|
||||||
final boolean putOnTop = (topCard == host);
|
final boolean putOnTop = (topCard == host);
|
||||||
|
|
||||||
|
host.setMergedToCard(target);
|
||||||
|
// If first time mutate, add target first.
|
||||||
|
if (target.getMergedCards().isEmpty()) {
|
||||||
|
target.addMergedCard(target);
|
||||||
|
}
|
||||||
if (putOnTop) {
|
if (putOnTop) {
|
||||||
host.addMergedCard(target);
|
target.addMergedCardToTop(host);
|
||||||
host.addMergedCards(target.getMergedCards());
|
|
||||||
target.clearMergedCards();
|
|
||||||
target.setMergedToCard(host);
|
|
||||||
} else {
|
} else {
|
||||||
target.addMergedCard(host);
|
target.addMergedCard(host);
|
||||||
host.setMergedToCard(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// First remove current mutated states
|
// First remove current mutated states
|
||||||
if (target.getMutatedTimestamp() != -1) {
|
if (target.getMutatedTimestamp() != -1) {
|
||||||
target.removeCloneState(target.getMutatedTimestamp());
|
target.removeCloneState(target.getMutatedTimestamp());
|
||||||
@@ -66,27 +66,21 @@ public class MutateEffect extends SpellAbilityEffect {
|
|||||||
// Now add all abilities from bottom cards
|
// Now add all abilities from bottom cards
|
||||||
final Long ts = game.getNextTimestamp();
|
final Long ts = game.getNextTimestamp();
|
||||||
if (topCard.getCurrentStateName() != CardStateName.FaceDown) {
|
if (topCard.getCurrentStateName() != CardStateName.FaceDown) {
|
||||||
final CardCloneStates mutatedStates = CardFactory.getMutatedCloneStates(topCard, sa);
|
final CardCloneStates mutatedStates = CardFactory.getMutatedCloneStates(target, sa);
|
||||||
topCard.addCloneState(mutatedStates, ts);
|
target.addCloneState(mutatedStates, ts);
|
||||||
topCard.setMutatedTimestamp(ts);
|
target.setMutatedTimestamp(ts);
|
||||||
}
|
}
|
||||||
if (topCard == target) {
|
|
||||||
// Re-register triggers for target card
|
// Re-register triggers for target card
|
||||||
game.getTriggerHandler().clearActiveTriggers(target, null);
|
game.getTriggerHandler().clearActiveTriggers(target, null);
|
||||||
game.getTriggerHandler().registerActiveTrigger(target, false);
|
game.getTriggerHandler().registerActiveTrigger(target, false);
|
||||||
}
|
|
||||||
|
|
||||||
game.getAction().moveToPlay(host, p, sa);
|
game.getAction().moveToPlay(host, p, sa);
|
||||||
|
|
||||||
if (topCard == host) {
|
|
||||||
CardFactory.migrateTopCard(host, target);
|
|
||||||
} else {
|
|
||||||
host.setTapped(target.isTapped());
|
host.setTapped(target.isTapped());
|
||||||
host.setFlipped(target.isFlipped());
|
host.setFlipped(target.isFlipped());
|
||||||
}
|
target.setTimesMutated(target.getTimesMutated() + 1);
|
||||||
topCard.setTimesMutated(topCard.getTimesMutated() + 1);
|
|
||||||
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Mutates, AbilityKey.mapFromCard(topCard), false);
|
game.getTriggerHandler().runTrigger(TriggerType.Mutates, AbilityKey.mapFromCard(target), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1010,8 +1010,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
public final void addMergedCard(final Card c) {
|
public final void addMergedCard(final Card c) {
|
||||||
mergedCards = view.addCard(mergedCards, c, TrackableProperty.MergedCards);
|
mergedCards = view.addCard(mergedCards, c, TrackableProperty.MergedCards);
|
||||||
}
|
}
|
||||||
public final void addMergedCards(final Iterable<Card> cards) {
|
public final void addMergedCardToTop(final Card c) {
|
||||||
mergedCards = view.addCards(mergedCards, cards, TrackableProperty.MergedCards);
|
mergedCards.add(0, c);
|
||||||
|
view.setCards(mergedCards, mergedCards, TrackableProperty.MergedCards);
|
||||||
}
|
}
|
||||||
public final void removeMergedCard(final Card c) {
|
public final void removeMergedCard(final Card c) {
|
||||||
mergedCards = view.removeCard(mergedCards, c, TrackableProperty.MergedCards);
|
mergedCards = view.removeCard(mergedCards, c, TrackableProperty.MergedCards);
|
||||||
@@ -1028,7 +1029,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isMerged() {
|
public final boolean isMerged() {
|
||||||
return !getMergedCards().isEmpty() || getMergedToCard() != null;
|
return getMergedToCard() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isMutated() {
|
public final boolean isMutated() {
|
||||||
@@ -3740,9 +3741,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
if (tapped == tapped0) { return; }
|
if (tapped == tapped0) { return; }
|
||||||
tapped = tapped0;
|
tapped = tapped0;
|
||||||
view.updateTapped(this);
|
view.updateTapped(this);
|
||||||
for (final Card c : getMergedCards()) {
|
|
||||||
c.setTapped(tapped0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void tap() {
|
public final void tap() {
|
||||||
|
|||||||
@@ -823,49 +823,23 @@ public class CardFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static CardCloneStates getMutatedCloneStates(final Card card, final CardTraitBase sa) {
|
public static CardCloneStates getMutatedCloneStates(final Card card, final CardTraitBase sa) {
|
||||||
final CardStateName state = card.getCurrentStateName();
|
final Card top = card.getMergedCards().get(0);
|
||||||
|
final CardStateName state = top.getCurrentStateName();
|
||||||
final CardState ret = new CardState(card, state);
|
final CardState ret = new CardState(card, state);
|
||||||
ret.copyFrom(card.getState(state, true), false);
|
ret.copyFrom(top.getState(state, true), false);
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
for (final Card c : card.getMergedCards()) {
|
for (final Card c : card.getMergedCards()) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ret.addAbilitiesFrom(c.getCurrentState(), false);
|
ret.addAbilitiesFrom(c.getCurrentState(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardCloneStates result = new CardCloneStates(card, sa);
|
final CardCloneStates result = new CardCloneStates(top, sa);
|
||||||
result.put(state, ret);
|
result.put(state, ret);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void migrateTopCard(final Card host, final Card target) {
|
|
||||||
// Copy all status from target card and migrate all counters
|
|
||||||
// Also update all reference of target card to new top card
|
|
||||||
|
|
||||||
// TODO: find out all necessary status that should be copied
|
|
||||||
host.setTapped(target.isTapped());
|
|
||||||
host.setSickness(target.isFirstTurnControlled());
|
|
||||||
host.setFlipped(target.isFlipped());
|
|
||||||
host.setDamage(target.getDamage());
|
|
||||||
host.setTimesMutated(target.getTimesMutated());
|
|
||||||
host.setMonstrous(target.isMonstrous());
|
|
||||||
host.setRenowned(target.isRenowned());
|
|
||||||
|
|
||||||
// Migrate counters
|
|
||||||
Map<CounterType, Integer> counters = target.getCounters();
|
|
||||||
if (!counters.isEmpty()) {
|
|
||||||
host.setCounters(Maps.newHashMap(counters));
|
|
||||||
}
|
|
||||||
target.clearCounters();
|
|
||||||
|
|
||||||
// Migrate attached cards
|
|
||||||
CardCollectionView attached = target.getAttachedCards();
|
|
||||||
for (final Card c : attached) {
|
|
||||||
c.setEntityAttachedTo(host);
|
|
||||||
}
|
|
||||||
target.setAttachedCards(null);
|
|
||||||
host.setAttachedCards(attached);
|
|
||||||
|
|
||||||
// TODO: move all remembered, imprinted objects to new top card
|
|
||||||
// and possibly many other needs to be migrated.
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end class AbstractCardFactory
|
} // end class AbstractCardFactory
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ public class PlayerView extends GameEntityView {
|
|||||||
void updateZone(PlayerZone zone) {
|
void updateZone(PlayerZone zone) {
|
||||||
TrackableProperty prop = getZoneProp(zone.getZoneType());
|
TrackableProperty prop = getZoneProp(zone.getZoneType());
|
||||||
if (prop == null) { return; }
|
if (prop == null) { return; }
|
||||||
set(prop, CardView.getCollection(zone.getCards(false, false)));
|
set(prop, CardView.getCollection(zone.getCards(false, true)));
|
||||||
|
|
||||||
//update delirium
|
//update delirium
|
||||||
if (ZoneType.Graveyard == zone.getZoneType())
|
if (ZoneType.Graveyard == zone.getZoneType())
|
||||||
|
|||||||
@@ -685,21 +685,6 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
|||||||
}
|
}
|
||||||
toPanel.getAttachedPanels().clear();
|
toPanel.getAttachedPanels().clear();
|
||||||
|
|
||||||
// Treat merged cards like attached cards
|
|
||||||
if (card.hasMergedCards()) {
|
|
||||||
final Iterable<CardView> merged = card.getMergedCards();
|
|
||||||
for (final CardView c : merged) {
|
|
||||||
final CardPanel cardC = getCardPanel(c.getId());
|
|
||||||
if (cardC != null) {
|
|
||||||
if (cardC.getAttachedToPanel() != toPanel) {
|
|
||||||
cardC.setAttachedToPanel(toPanel);
|
|
||||||
needLayoutRefresh = true; //ensure layout refreshed if any attachments change
|
|
||||||
}
|
|
||||||
toPanel.getAttachedPanels().add(cardC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (card.hasCardAttachments()) {
|
if (card.hasCardAttachments()) {
|
||||||
final Iterable<CardView> enchants = card.getAttachedCards();
|
final Iterable<CardView> enchants = card.getAttachedCards();
|
||||||
for (final CardView e : enchants) {
|
for (final CardView e : enchants) {
|
||||||
@@ -714,13 +699,11 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat merged cards like attached cards
|
|
||||||
CardPanel attachedToPanel;
|
CardPanel attachedToPanel;
|
||||||
if (card.getMergedTo() != null) {
|
if (card.getAttachedTo() != null) {
|
||||||
attachedToPanel = getCardPanel(card.getMergedTo().getId());
|
|
||||||
} else if (card.getAttachedTo() != null) {
|
|
||||||
attachedToPanel = getCardPanel(card.getAttachedTo().getId());
|
attachedToPanel = getCardPanel(card.getAttachedTo().getId());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
attachedToPanel = null;
|
attachedToPanel = null;
|
||||||
}
|
}
|
||||||
if (toPanel.getAttachedToPanel() != attachedToPanel) {
|
if (toPanel.getAttachedToPanel() != attachedToPanel) {
|
||||||
|
|||||||
@@ -286,17 +286,6 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
|
|||||||
|
|
||||||
attachedPanels.clear();
|
attachedPanels.clear();
|
||||||
|
|
||||||
// Treat merged cards like attached cards
|
|
||||||
if (card.hasMergedCards()) {
|
|
||||||
final Iterable<CardView> merged = card.getMergedCards();
|
|
||||||
for (final CardView c : merged) {
|
|
||||||
final CardAreaPanel cardC = CardAreaPanel.get(c);
|
|
||||||
if (cardC != null) {
|
|
||||||
attachedPanels.add(cardC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (card.hasCardAttachments()) {
|
if (card.hasCardAttachments()) {
|
||||||
final Iterable<CardView> enchants = card.getAttachedCards();
|
final Iterable<CardView> enchants = card.getAttachedCards();
|
||||||
for (final CardView e : enchants) {
|
for (final CardView e : enchants) {
|
||||||
@@ -307,10 +296,7 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.getMergedTo() != null ) {
|
if (card.getAttachedTo() != null) {
|
||||||
setAttachedToPanel(CardAreaPanel.get(card.getMergedTo()));
|
|
||||||
}
|
|
||||||
else if (card.getAttachedTo() != null) {
|
|
||||||
setAttachedToPanel(CardAreaPanel.get(card.getAttachedTo()));
|
setAttachedToPanel(CardAreaPanel.get(card.getAttachedTo()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
10
forge-gui/res/cardsfolder/p/pollywog_symbiote.txt
Normal file
10
forge-gui/res/cardsfolder/p/pollywog_symbiote.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Pollywog Symbiote
|
||||||
|
ManaCost:1 U
|
||||||
|
Types:Creature Frog
|
||||||
|
PT:1/3
|
||||||
|
S:Mode$ ReduceCost | ValidCard$ Creature.withMutate | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Each creature spell you cast costs {1} less to cast if it has mutate.
|
||||||
|
T:Mode$ SpellCast | ValidCard$ Creature.withMutate | ValidActivatingPlayer$ You | Execute$ TrigLoot | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, if it has mutate, draw a card, then discard a card.
|
||||||
|
SVar:TrigLoot:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBDiscard
|
||||||
|
SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose
|
||||||
|
SVar:BuffedBy:Card.withMutate
|
||||||
|
Oracle:Each creature spell you cast costs {1} less to cast if it has mutate.\nWhenever you cast a creature spell, if it has mutate, draw a card, then discard a card.
|
||||||
Reference in New Issue
Block a user