use of mage.cards.MagePermanent in project mage by magefree.
the class BattlefieldPanel method update.
public void update(Map<UUID, PermanentView> battlefield) {
gameUpdateTimer.stop();
boolean changed = false;
List<PermanentView> permanentsToAdd = new ArrayList<>();
for (PermanentView permanent : battlefield.values()) {
if (!permanent.isPhasedIn()) {
continue;
}
MageCard oldFound = permanents.get(permanent.getId());
MagePermanent oldMagePermanent = oldFound == null ? null : (MagePermanent) oldFound.getMainPanel();
if (oldMagePermanent == null) {
permanentsToAdd.add(permanent);
changed = true;
} else {
if (!changed) {
changed = oldMagePermanent.getOriginalPermanent().isCreature() != permanent.isCreature();
// Check if there was a change in the permanets that are the permanent attached to
if (!changed) {
int attachments = permanent.getAttachments() == null ? 0 : permanent.getAttachments().size();
int attachmentsBefore = oldMagePermanent.getLinks().size();
if (attachments != attachmentsBefore) {
changed = true;
} else if (attachments > 0) {
Set<UUID> attachmentIds = new HashSet<>(permanent.getAttachments());
for (MageCard mageCard : oldMagePermanent.getLinks()) {
MagePermanent magePermanent = (MagePermanent) mageCard.getMainPanel();
if (!attachmentIds.contains(magePermanent.getOriginalPermanent().getId())) {
// that means that the amount of attachments is the same
// but they are different:
// we've just found an attachment on previous view
// that doesn't exist anymore on current view
changed = true;
break;
}
}
}
}
// Check if permanents it now attached to another or no permanent
if (!changed) {
UUID attachedToIdBefore = oldMagePermanent.getOriginalPermanent().getAttachedTo();
UUID attachedToId = permanent.getAttachedTo();
if (attachedToIdBefore == null && attachedToId != null || attachedToId == null && attachedToIdBefore != null || (attachedToIdBefore != null && !attachedToIdBefore.equals(attachedToId))) {
changed = true;
}
}
// Check for changes in the counters of the permanent
if (!changed) {
List<CounterView> counters1 = oldMagePermanent.getOriginalPermanent().getCounters();
List<CounterView> counters2 = permanent.getCounters();
if (counters1 == null && counters2 != null || counters1 != null && counters2 == null) {
changed = true;
} else if (counters1 != null && counters2 != null && counters1.size() != counters2.size()) {
changed = true;
}
}
}
oldMagePermanent.update(permanent);
}
}
addedArtifact = addedCreature = addedPermanent = false;
int count = permanentsToAdd.size();
for (PermanentView permanent : permanentsToAdd) {
addPermanent(permanent, count);
}
if (addedArtifact) {
AudioManager.playAddArtifact();
} else if (addedCreature) {
AudioManager.playSummon();
} else if (addedPermanent) {
AudioManager.playAddPermanent();
}
removedCreature = false;
for (Iterator<Entry<UUID, MageCard>> iterator = permanents.entrySet().iterator(); iterator.hasNext(); ) {
Entry<UUID, MageCard> entry = iterator.next();
if (!battlefield.containsKey(entry.getKey()) || !battlefield.get(entry.getKey()).isPhasedIn()) {
removePermanent(entry.getKey(), 1);
iterator.remove();
changed = true;
}
}
if (removedCreature) {
AudioManager.playDiedCreature();
}
if (changed) {
this.battlefield = battlefield;
sortLayout();
}
}
use of mage.cards.MagePermanent in project mage by magefree.
the class BattlefieldPanel method removePermanent.
private void removePermanent(UUID permanentId, final int count) {
for (Component comp : this.jPanel.getComponents()) {
if (comp instanceof MageCard) {
MageCard mageCard = (MageCard) comp;
if (mageCard.getMainPanel() instanceof MagePermanent) {
MagePermanent magePermanent = (MagePermanent) mageCard.getMainPanel();
if (magePermanent.getOriginal().getId().equals(permanentId)) {
Thread t = new Thread(() -> {
Plugins.instance.onRemoveCard(mageCard, count);
mageCard.setVisible(false);
this.jPanel.remove(mageCard);
});
t.start();
}
if (magePermanent.getOriginal().isCreature()) {
removedCreature = true;
}
}
}
}
}
use of mage.cards.MagePermanent in project mage by magefree.
the class CardPluginImpl method calculateNeededNumberOfVerticalColumns.
private AttachmentLayoutInfos calculateNeededNumberOfVerticalColumns(int currentCol, Map<UUID, MageCard> cards, MageCard cardWithAttachments) {
int maxCol = ++currentCol;
int attachments = 0;
MagePermanent permWithAttachments = (MagePermanent) cardWithAttachments.getMainPanel();
for (UUID attachmentId : permWithAttachments.getOriginalPermanent().getAttachments()) {
MageCard attachedCard = cards.get(attachmentId);
if (attachedCard != null) {
attachments++;
MagePermanent attachedPerm = (MagePermanent) attachedCard.getMainPanel();
if (attachedPerm.getOriginalPermanent().getAttachments() != null && !attachedPerm.getOriginalPermanent().getAttachments().isEmpty()) {
AttachmentLayoutInfos attachmentLayoutInfos = calculateNeededNumberOfVerticalColumns(currentCol, cards, attachedCard);
if (attachmentLayoutInfos.getColumns() > maxCol) {
maxCol = attachmentLayoutInfos.getColumns();
attachments += attachmentLayoutInfos.getAttachments();
}
}
}
}
return new AttachmentLayoutInfos(maxCol, attachments);
}
use of mage.cards.MagePermanent in project mage by magefree.
the class CardPluginImpl method sortPermanents.
@Override
public int sortPermanents(Map<String, JComponent> ui, Map<UUID, MageCard> cards, boolean nonPermanentsOwnRow, boolean topPanel) {
if (ui == null) {
throw new RuntimeException("No battlefield ui for layout");
}
JLayeredPane battlefieldPanel = (JLayeredPane) ui.get("battlefieldPanel");
JComponent cardsPanel = ui.get("jPanel");
JScrollPane scrollPane = (JScrollPane) ui.get("scrollPane");
if (battlefieldPanel == null || cardsPanel == null || scrollPane == null) {
throw new RuntimeException("No battlefield components for layout");
}
Row rowAllLands = new Row();
outerLoop: //
for (MageCard card : cards.values()) {
// all cards must be MagePermanent on battlefield
MagePermanent perm = (MagePermanent) card.getMainPanel();
if (!perm.isLand() || perm.isCreature()) {
continue;
}
int insertIndex = -1;
// Find already added lands with the same name.
for (int i = 0, n = rowAllLands.size(); i < n; i++) {
// stack contains main card panel, but for any size/order manipulation you must use top layer panel
Stack stack = rowAllLands.get(i);
MagePermanent firstPanelPerm = stack.get(0);
if (firstPanelPerm.getOriginal().getName().equals(perm.getOriginal().getName())) {
if (!empty(firstPanelPerm.getOriginalPermanent().getAttachments())) {
// Put this land to the left of lands with the same name and attachments.
insertIndex = i;
break;
}
List<CounterView> counters = firstPanelPerm.getOriginalPermanent().getCounters();
if (counters != null && !counters.isEmpty()) {
// don't put to first panel if it has counters
insertIndex = i;
break;
}
if (!empty(perm.getOriginalPermanent().getAttachments()) || stack.size() == landStackMax) {
// If this land has attachments or the stack is full, put it to the right.
insertIndex = i + 1;
continue;
}
counters = perm.getOriginalPermanent().getCounters();
if (counters != null && !counters.isEmpty()) {
// if a land has counter, put it to the right
insertIndex = i + 1;
continue;
}
// Add to stack.
stack.add(0, perm);
continue outerLoop;
}
if (insertIndex != -1) {
break;
}
}
Stack stack = new Stack();
if (perm.getOriginalPermanent().getAttachments() != null && !perm.getOriginalPermanent().getAttachments().isEmpty() && !perm.getOriginalPermanent().isAttachedTo()) {
// get the number of all attachements and sub attachments
AttachmentLayoutInfos ali = calculateNeededNumberOfVerticalColumns(0, cards, card);
stack.setMaxAttachedCount(ali.getAttachments());
stack.setAttachmentColumns(ali.getColumns());
}
stack.add(perm);
rowAllLands.add(insertIndex == -1 ? rowAllLands.size() : insertIndex, stack);
}
Row rowAllCreatures = new Row(cards, RowType.creature);
Row rowAllOthers = new Row(cards, RowType.other);
Row rowAllAttached = new Row(cards, RowType.attached);
boolean othersOnTheRight = true;
if (nonPermanentsOwnRow) {
othersOnTheRight = false;
rowAllCreatures.addAll(rowAllOthers);
rowAllOthers.clear();
}
// try to auto-fit cards
cardWidth = cardWidthMax;
Rectangle rect = battlefieldPanel.getVisibleRect();
playAreaWidth = rect.width;
playAreaHeight = rect.height;
while (true) {
rows.clear();
// calculate values based on the card size that is changing with every iteration
cardHeight = Math.round(cardWidth * CardPanel.ASPECT_RATIO);
extraCardSpacingX = Math.round(cardWidth * EXTRA_CARD_SPACING_X);
// need space for tap animation (horizontal position)
cardSpacingX = cardHeight - cardWidth + extraCardSpacingX;
cardSpacingY = Math.round(cardHeight * CARD_SPACING_Y);
stackSpacingX = stackVertical ? 0 : Math.round(cardWidth * STACK_SPACING_X);
stackSpacingY = Math.round(cardHeight * STACK_SPACING_Y);
attachmentSpacingY = Math.round(cardHeight * ATTACHMENT_SPACING_Y);
// clone data
Row creatures = (Row) rowAllCreatures.clone();
Row lands = (Row) rowAllLands.clone();
Row others = (Row) rowAllOthers.clone();
// Wrap all creatures and lands.
int addOthersIndex;
if (topPanel) {
wrap(lands, rows, -1);
wrap(others, rows, rows.size());
addOthersIndex = rows.size();
wrap(creatures, rows, addOthersIndex);
} else {
wrap(creatures, rows, -1);
addOthersIndex = rows.size();
wrap(lands, rows, rows.size());
wrap(others, rows, rows.size());
}
// Store the current rows and others.
List<Row> storedRows = new ArrayList<>(rows.size());
for (Row row : rows) {
storedRows.add((Row) row.clone());
}
Row storedOthers = (Row) others.clone();
// Fill in all rows with others.
for (Row row : rows) {
fillRow(others, rows, row);
}
// Stop if everything fits, otherwise revert back to the stored values.
if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty()) {
break;
}
rows = storedRows;
others = storedOthers;
// Try to put others on their own row(s) and fill in the rest.
wrap(others, rows, addOthersIndex);
for (Row row : rows) {
fillRow(others, rows, row);
}
// If that still doesn't fit, scale down.
if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty()) {
break;
}
cardWidth -= CARD_WIDTH_AUTO_FIT_INCREMENT;
}
// Get size of all the rows.
int x, y = GUTTER_Y;
int maxRowWidth = 0;
for (Row row : rows) {
int rowBottom = 0;
x = GUTTER_X;
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
Stack stack = row.get(stackIndex);
rowBottom = Math.max(rowBottom, y + stack.getHeight());
x += stack.getWidth();
}
y = rowBottom;
maxRowWidth = Math.max(maxRowWidth, x);
}
// Position all card panels
y = GUTTER_Y;
for (Row row : rows) {
int rowBottom = 0;
x = GUTTER_X;
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
Stack stack = row.get(stackIndex);
// Align others to the right.
if (othersOnTheRight && RowType.other.isType(stack.get(0))) {
x = playAreaWidth - GUTTER_X + extraCardSpacingX;
for (int i = stackIndex, n = row.size(); i < n; i++) {
x -= row.get(i).getWidth();
}
}
for (int panelIndex = 0, panelCount = stack.size(); panelIndex < panelCount; panelIndex++) {
// it's original card panel, but you must change top layer
MagePermanent panelPerm = stack.get(panelIndex);
int stackPosition = panelCount - panelIndex - 1;
if (cardsPanel != null) {
cardsPanel.setComponentZOrder(panelPerm.getTopPanelRef(), panelIndex);
}
int panelX = x + (stackPosition * stackSpacingX);
int panelY = y + (stackPosition * stackSpacingY);
try {
// may cause:
// java.lang.IllegalArgumentException: illegal component position 26 should be less then 26
battlefieldPanel.moveToFront(panelPerm.getTopPanelRef());
} catch (Exception e) {
e.printStackTrace();
}
panelPerm.getTopPanelRef().setCardBounds(panelX, panelY, cardWidth, cardHeight);
}
rowBottom = Math.max(rowBottom, y + stack.getHeight());
x += stack.getWidth();
}
y = rowBottom;
}
// attached permanents will be handled separately
for (Stack stack : rowAllAttached) {
for (MagePermanent panelPerm : stack) {
panelPerm.getTopPanelRef().setCardBounds(0, 0, cardWidth, cardHeight);
}
}
// scrollbars speed
scrollPane.getVerticalScrollBar().setUnitIncrement(GUISizeHelper.getCardsScrollbarUnitInc(cardHeight));
return y;
}
Aggregations