mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 21:02:08 -08:00
refactor: clean, added comments and todos to meld related code, fixed miss copy (related to #12544)
This commit is contained in:
parent
ddb7e21dc2
commit
bccf323c0f
5 changed files with 36 additions and 21 deletions
|
|
@ -84,6 +84,13 @@ public class MeldEffect extends OneShotEffect {
|
|||
if (sourcePermanent == null || meldWithPermanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// melding in exile zone, rules:
|
||||
// When two cards are exiled and melded, they each leave the battlefield, then return together as one
|
||||
// new untapped object with no relation to either of the objects that left the battlefield.
|
||||
// Counters, Auras, Equipment, and other effects that affected those two cards don't affect
|
||||
// the melded permanent.
|
||||
|
||||
Cards cards = new CardsImpl(sourcePermanent);
|
||||
cards.add(meldWithPermanent);
|
||||
controller.moveCards(cards, Zone.EXILED, source, game);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import mage.counters.Counter;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
|
@ -30,8 +31,8 @@ public abstract class MeldCard extends CardImpl {
|
|||
|
||||
protected MeldCard(final MeldCard card) {
|
||||
super(card);
|
||||
this.topHalfCard = card.topHalfCard;
|
||||
this.bottomHalfCard = card.bottomHalfCard;
|
||||
this.topHalfCard = CardUtil.deepCopyObject(card.topHalfCard);
|
||||
this.bottomHalfCard = CardUtil.deepCopyObject(card.bottomHalfCard);
|
||||
this.topLastZoneChangeCounter = card.topLastZoneChangeCounter;
|
||||
this.bottomLastZoneChangeCounter = card.bottomLastZoneChangeCounter;
|
||||
this.halves = new CardsImpl(card.halves);
|
||||
|
|
@ -135,6 +136,7 @@ public abstract class MeldCard extends CardImpl {
|
|||
boolean value = topLastZoneChangeCounter == topHalfCard.getZoneChangeCounter(game)
|
||||
&& halves.contains(topHalfCard.getId());
|
||||
if (!value) {
|
||||
// TODO: sync code with deleting halfs ref smells bad - looks like melds have problems with zcc sync (topLastZoneChangeCounter)
|
||||
halves.remove(topHalfCard);
|
||||
}
|
||||
return value;
|
||||
|
|
@ -144,6 +146,7 @@ public abstract class MeldCard extends CardImpl {
|
|||
boolean value = bottomLastZoneChangeCounter == bottomHalfCard.getZoneChangeCounter(game)
|
||||
&& halves.contains(bottomHalfCard.getId());
|
||||
if (!value) {
|
||||
// TODO: sync code with deleting halfs ref smells bad - looks like melds have problems with zcc sync (bottomLastZoneChangeCounter)
|
||||
halves.remove(bottomHalfCard);
|
||||
}
|
||||
return value;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class ZoneChangeInfo {
|
|||
|
||||
public boolean faceDown;
|
||||
public ZoneChangeEvent event;
|
||||
List<ZoneChangeInfo> additionalMoves = new ArrayList<>(); // additions objects move (example: meld parts), TODO: must research, can be un-used by real code
|
||||
|
||||
public ZoneChangeInfo(ZoneChangeEvent event) {
|
||||
this.event = event;
|
||||
|
|
@ -27,9 +28,10 @@ public class ZoneChangeInfo {
|
|||
this.faceDown = faceDown;
|
||||
}
|
||||
|
||||
public ZoneChangeInfo(ZoneChangeInfo info) {
|
||||
private ZoneChangeInfo(final ZoneChangeInfo info) {
|
||||
this.event = info.event;
|
||||
this.faceDown = info.faceDown;
|
||||
this.additionalMoves = new ArrayList<>(info.additionalMoves);
|
||||
}
|
||||
|
||||
public ZoneChangeInfo copy() {
|
||||
|
|
@ -146,8 +148,6 @@ public class ZoneChangeInfo {
|
|||
|
||||
public static class Unmelded extends ZoneChangeInfo {
|
||||
|
||||
List<ZoneChangeInfo> subInfo = new ArrayList<>();
|
||||
|
||||
public Unmelded(ZoneChangeInfo info, Game game) {
|
||||
super(info.event);
|
||||
MeldCard meld = game.getMeldCard(info.event.getTargetId());
|
||||
|
|
@ -157,14 +157,14 @@ public class ZoneChangeInfo {
|
|||
event.getPlayerId(), event.getFromZone(), event.getToZone(), event.getAppliedEffects());
|
||||
ZoneChangeInfo topInfo = info.copy();
|
||||
topInfo.event = topEvent;
|
||||
subInfo.add(topInfo);
|
||||
additionalMoves.add(topInfo);
|
||||
}
|
||||
if (meld.hasBottomHalf(game)) {
|
||||
ZoneChangeEvent bottomEvent = new ZoneChangeEvent(meld.getBottomHalfCard().getId(), event.getSource(),
|
||||
event.getPlayerId(), event.getFromZone(), event.getToZone(), event.getAppliedEffects());
|
||||
ZoneChangeInfo bottomInfo = info.copy();
|
||||
bottomInfo.event = bottomEvent;
|
||||
subInfo.add(bottomInfo);
|
||||
additionalMoves.add(bottomInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,14 +58,19 @@ public final class ZonesHandler {
|
|||
}
|
||||
|
||||
public static List<ZoneChangeInfo> moveCards(List<ZoneChangeInfo> zoneChangeInfos, Ability source, Game game) {
|
||||
// Handle Unmelded Meld Cards
|
||||
// handle unmelded meld cards (if something moved a melded card to non-battlefield then parts must be moved too)
|
||||
for (ListIterator<ZoneChangeInfo> itr = zoneChangeInfos.listIterator(); itr.hasNext(); ) {
|
||||
ZoneChangeInfo info = itr.next();
|
||||
if (info.event.getToZone().equals(Zone.BATTLEFIELD)) {
|
||||
continue;
|
||||
}
|
||||
MeldCard card = game.getMeldCard(info.event.getTargetId());
|
||||
// Copies should be handled as normal cards.
|
||||
if (card != null && !card.isMelded(game) && !card.isCopy()) {
|
||||
// TODO: WTF, never worked code here. Need research possible typo: !card.isMelded(game) -> card.isMelded(game)
|
||||
ZoneChangeInfo.Unmelded unmelded = new ZoneChangeInfo.Unmelded(info, game);
|
||||
if (unmelded.subInfo.isEmpty()) {
|
||||
if (unmelded.additionalMoves.isEmpty()) {
|
||||
// already moved halves somehow
|
||||
itr.remove();
|
||||
} else {
|
||||
itr.set(unmelded);
|
||||
|
|
@ -123,9 +128,9 @@ public final class ZonesHandler {
|
|||
if (info instanceof ZoneChangeInfo.Unmelded) {
|
||||
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
|
||||
Zone toZone = null;
|
||||
for (ZoneChangeInfo subInfo : unmelded.subInfo) {
|
||||
toZone = subInfo.event.getToZone();
|
||||
placeInDestinationZone(subInfo, createOrder, source, game);
|
||||
for (ZoneChangeInfo additionalMove : unmelded.additionalMoves) {
|
||||
toZone = additionalMove.event.getToZone();
|
||||
placeInDestinationZone(additionalMove, createOrder, source, game);
|
||||
}
|
||||
// We arbitrarily prefer the bottom half card. This should never be relevant.
|
||||
if (toZone != null) {
|
||||
|
|
@ -303,21 +308,21 @@ public final class ZonesHandler {
|
|||
if (info instanceof ZoneChangeInfo.Unmelded) {
|
||||
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
|
||||
MeldCard meld = game.getMeldCard(event.getTargetId());
|
||||
for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext(); ) {
|
||||
ZoneChangeInfo subInfo = itr.next();
|
||||
if (!maybeRemoveFromSourceZone(subInfo, game, source)) {
|
||||
for (Iterator<ZoneChangeInfo> itr = unmelded.additionalMoves.iterator(); itr.hasNext(); ) {
|
||||
ZoneChangeInfo additionalMove = itr.next();
|
||||
if (!maybeRemoveFromSourceZone(additionalMove, game, source)) {
|
||||
itr.remove();
|
||||
} else if (Objects.equals(subInfo.event.getTargetId(), meld.getTopHalfCard().getId())) {
|
||||
} else if (Objects.equals(additionalMove.event.getTargetId(), meld.getTopHalfCard().getId())) {
|
||||
meld.setTopLastZoneChangeCounter(meld.getTopHalfCard().getZoneChangeCounter(game));
|
||||
} else if (Objects.equals(subInfo.event.getTargetId(), meld.getBottomHalfCard().getId())) {
|
||||
} else if (Objects.equals(additionalMove.event.getTargetId(), meld.getBottomHalfCard().getId())) {
|
||||
meld.setBottomLastZoneChangeCounter(meld.getBottomHalfCard().getZoneChangeCounter(game));
|
||||
}
|
||||
}
|
||||
if (unmelded.subInfo.isEmpty()) {
|
||||
if (unmelded.additionalMoves.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// We arbitrarily prefer the bottom half card. This should never be relevant.
|
||||
meld.updateZoneChangeCounter(game, unmelded.subInfo.get(unmelded.subInfo.size() - 1).event);
|
||||
meld.updateZoneChangeCounter(game, unmelded.additionalMoves.get(unmelded.additionalMoves.size() - 1).event);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import mage.game.permanent.Permanent;
|
|||
public class ZoneChangeEvent extends GameEvent {
|
||||
|
||||
private Zone fromZone;
|
||||
private Zone toZone;
|
||||
private Zone originalToZone;
|
||||
private Zone toZone; // real toZone after apply some replacements effects
|
||||
private Zone originalToZone; // original toZone before any replacement effects
|
||||
private Permanent target;
|
||||
private Ability source; // link to source ability, can be null in rare situations
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue