mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Support flipping cards on reward dialog
Prevent concurrent modification exception from opening overlay from background thread
This commit is contained in:
@@ -223,6 +223,10 @@ public class ConquestRewardDialog extends FScrollPane {
|
||||
for (int i = currentIndex; i < index; i++) {
|
||||
cardRevealers.get(i).progress = 1;
|
||||
}
|
||||
//ensure current card in view
|
||||
if (getScrollHeight() > getHeight() && index < cardCount) {
|
||||
scrollIntoView(cardRevealers.get(index), PADDING);
|
||||
}
|
||||
}
|
||||
|
||||
currentIndex = index;
|
||||
@@ -237,10 +241,11 @@ public class ConquestRewardDialog extends FScrollPane {
|
||||
|
||||
//skip remainder of animation
|
||||
private void skip() {
|
||||
currentIndex = cardRevealers.size();
|
||||
for (int i = currentIndex; i < currentIndex; i++) {
|
||||
int cardCount = cardRevealers.size();
|
||||
for (int i = currentIndex; i < cardCount; i++) {
|
||||
cardRevealers.get(i).progress = 1;
|
||||
}
|
||||
currentIndex = cardCount;
|
||||
animation.stop();
|
||||
}
|
||||
|
||||
@@ -256,18 +261,21 @@ public class ConquestRewardDialog extends FScrollPane {
|
||||
|
||||
private class CardRevealer extends FLabel {
|
||||
private static final float DUPLICATE_ALPHA_COMPOSITE = 0.35f;
|
||||
private static final float FLIP_DURATION = 0.85f;
|
||||
private static final float FADE_DUPLICATE_DURATION = 0.1f; //give a brief interlude before the next flip
|
||||
|
||||
private final ConquestReward reward;
|
||||
private float progress;
|
||||
|
||||
private CardRevealer(ConquestReward reward0) {
|
||||
super(new FLabel.Builder().iconScaleFactor(1f));
|
||||
super(new FLabel.Builder().iconScaleWithFont(true).iconScaleFactor(1));
|
||||
|
||||
reward = reward0;
|
||||
if (reward.isDuplicate()) {
|
||||
setFont(FSkinFont.get(20));
|
||||
setIcon(FSkinImage.QUEST_COIN);
|
||||
setAlignment(HAlignment.CENTER);
|
||||
setText(String.valueOf(reward.getReplacementShards()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,23 +299,35 @@ public class ConquestRewardDialog extends FScrollPane {
|
||||
float w = getWidth();
|
||||
float h = getHeight();
|
||||
|
||||
if (progress > 0.9999f) { //account for floating point error
|
||||
if (progress >= FLIP_DURATION) {
|
||||
float fadeProgress = (progress - FLIP_DURATION) / FADE_DUPLICATE_DURATION;
|
||||
if (reward.isDuplicate()) {
|
||||
g.setAlphaComposite(DUPLICATE_ALPHA_COMPOSITE);
|
||||
float alphaComposite = DUPLICATE_ALPHA_COMPOSITE;
|
||||
if (fadeProgress < 1) {
|
||||
alphaComposite += (1 - fadeProgress) * (1 - DUPLICATE_ALPHA_COMPOSITE);
|
||||
}
|
||||
g.setAlphaComposite(alphaComposite);
|
||||
}
|
||||
CardRenderer.drawCard(g, reward.getCard(), 0, 0, w, h, CardStackPosition.Top);
|
||||
if (reward.isDuplicate()) {
|
||||
g.resetAlphaComposite();
|
||||
if (fadeProgress >= 1) {
|
||||
drawContent(g, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
else if (progress >= 0.5f) {
|
||||
CardRenderer.drawCard(g, reward.getCard(), 0, 0, w, h, CardStackPosition.Top);
|
||||
}
|
||||
else {
|
||||
float halfDuration = FLIP_DURATION / 2;
|
||||
if (progress >= halfDuration) {
|
||||
float flipWidth = w * (progress - halfDuration) / halfDuration;
|
||||
CardRenderer.drawCard(g, reward.getCard(), (w - flipWidth) / 2, 0, flipWidth, h, CardStackPosition.Top);
|
||||
}
|
||||
else {
|
||||
Texture cardBack = ImageCache.getImage(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD), true);
|
||||
if (cardBack != null) {
|
||||
g.drawImage(cardBack, 0, 0, w, h);
|
||||
float flipWidth = w * (halfDuration - progress) / halfDuration;
|
||||
g.drawImage(cardBack, (w - flipWidth) / 2, 0, flipWidth, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
private boolean bldSelected = false;
|
||||
private boolean bldOpaque = false;
|
||||
private boolean bldIconInBackground = false;
|
||||
private boolean bldIconScaleWithFont = false;
|
||||
private boolean bldIconScaleAuto = true;
|
||||
private boolean bldEnabled = true;
|
||||
private boolean bldParseSymbols = true;
|
||||
@@ -60,6 +61,7 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
public Builder alphaComposite(final float a0) { this.bldAlphaComposite = a0; return this; }
|
||||
public Builder enabled(final boolean b0) { this.bldEnabled = b0; return this; }
|
||||
public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; }
|
||||
public Builder iconScaleWithFont(final boolean b0) { this.bldIconScaleWithFont = b0; return this; }
|
||||
public Builder iconScaleFactor(final float f0) { this.bldIconScaleFactor = f0; return this; }
|
||||
public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; }
|
||||
public Builder iconInBackground() { iconInBackground(true); return this; }
|
||||
@@ -103,7 +105,7 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
private float alphaComposite;
|
||||
private HAlignment alignment;
|
||||
private Vector2 insets;
|
||||
private boolean selectable, selected, opaque, iconInBackground, iconScaleAuto, pressed;
|
||||
private boolean selectable, selected, opaque, iconInBackground, iconScaleAuto, iconScaleWithFont, pressed;
|
||||
|
||||
private String text;
|
||||
private FImage icon;
|
||||
@@ -123,6 +125,7 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
opaque = b0.bldOpaque;
|
||||
iconInBackground = b0.bldIconInBackground;
|
||||
iconScaleAuto = b0.bldIconScaleAuto;
|
||||
iconScaleWithFont = b0.bldIconScaleWithFont;
|
||||
text = b0.bldText != null ? b0.bldText : "";
|
||||
icon = b0.bldIcon;
|
||||
textColor = b0.bldTextColor;
|
||||
@@ -323,7 +326,11 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
float iconHeight = icon.getHeight();
|
||||
float aspectRatio = iconWidth / iconHeight;
|
||||
|
||||
if (iconInBackground || iconScaleAuto) {
|
||||
if (iconScaleWithFont) {
|
||||
iconHeight = font.getLineHeight() * iconScaleFactor;
|
||||
iconWidth = iconHeight * aspectRatio;
|
||||
}
|
||||
else if (iconInBackground || iconScaleAuto) {
|
||||
iconHeight = h * iconScaleFactor;
|
||||
iconWidth = iconHeight * aspectRatio;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
import com.badlogic.gdx.utils.Timer.Task;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.assets.FSkinColor;
|
||||
@@ -90,6 +91,8 @@ public abstract class FOverlay extends FContainer {
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible0) {
|
||||
FThreads.assertExecutedByEdt(true); //prevent showing or hiding overlays from background thread
|
||||
|
||||
if (this.isVisible() == visible0) { return; }
|
||||
|
||||
//ensure task to hide temporary overlay cancelled and run if another overlay becomes shown or hidden
|
||||
|
||||
@@ -275,7 +275,7 @@ public class ConquestController {
|
||||
//also build list of all rewards including replacement shards for each duplicate card
|
||||
//build this list in reverse order so commons appear first
|
||||
int shards = 0;
|
||||
List<ConquestReward> allRewards = new ArrayList<ConquestReward>();
|
||||
final List<ConquestReward> allRewards = new ArrayList<ConquestReward>();
|
||||
for (int i = rewards.size() - 1; i >= 0; i--) {
|
||||
int replacementShards = 0;
|
||||
PaperCard card = rewards.get(i);
|
||||
@@ -287,7 +287,12 @@ public class ConquestController {
|
||||
allRewards.add(new ConquestReward(card, replacementShards));
|
||||
}
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.showConquestRewards("Booster Awarded", allRewards);
|
||||
}
|
||||
});
|
||||
model.unlockCards(rewards);
|
||||
model.rewardAEtherShards(shards);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user