mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-12 16:58:57 +00:00
Merge pull request #5401 from kevlahnota/newmaster2
Add Backup/Restore Data Adventure Mode
This commit is contained in:
@@ -27,7 +27,7 @@ public class RewardSprite extends CharacterSprite {
|
||||
if (data != null) {
|
||||
rewards = JSONStringLoader.parse(RewardData[].class, data, default_reward);
|
||||
} else { //Shouldn't happen, but make sure it doesn't fly by.
|
||||
System.err.printf("Reward data is null. Using a default reward.");
|
||||
System.err.print("Reward data is null. Using a default reward.");
|
||||
rewards = JSONStringLoader.parse(RewardData[].class, default_reward, default_reward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ public class AdventureEventData implements Serializable {
|
||||
} else {
|
||||
description += "\n";
|
||||
}
|
||||
description += String.format("Prizes\n3 round wins: 500 gold\n2 round wins: 200 gold\n1 round win: 100 gold\n");
|
||||
description += "Prizes\n3 round wins: 500 gold\n2 round wins: 200 gold\n1 round win: 100 gold\n";
|
||||
description += "Finishing event will award an unsellable copy of each card in your Jumpstart deck.";
|
||||
}
|
||||
return description;
|
||||
|
||||
@@ -1106,10 +1106,13 @@ public class AdventureDeckEditor extends TabPageScreen<AdventureDeckEditor> {
|
||||
if (canOnlyBePartnerCommander(card)) {
|
||||
return; //don't auto-change commander unexpectedly
|
||||
}
|
||||
DeckSectionPage main = getMainDeckPage();
|
||||
if (main == null)
|
||||
return;
|
||||
if (!cardManager.isInfinite()) {
|
||||
removeCard(card);
|
||||
}
|
||||
getMainDeckPage().addCard(card);
|
||||
main.addCard(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -238,12 +238,18 @@ public class ArenaScene extends UIScene implements IAfterMatch {
|
||||
arenaPlane.addActor(lost);
|
||||
}
|
||||
|
||||
boolean started = false;
|
||||
|
||||
private void startRound() {
|
||||
if (started)
|
||||
return;
|
||||
started = true;
|
||||
DuelScene duelScene = DuelScene.instance();
|
||||
EnemySprite enemy = enemies.get(enemies.size - 1);
|
||||
FThreads.invokeInEdtNowOrLater(() -> {
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
duelScene.initDuels(WorldStage.getInstance().getPlayerSprite(), enemy);
|
||||
started = false;
|
||||
duelScene.initDuels(WorldStage.getInstance().getPlayerSprite(), enemy, true, null);
|
||||
Forge.switchScene(duelScene);
|
||||
}, Forge.takeScreenshot(), true, false, false, false, "", Current.player().avatar(), enemy.getAtlasPath(), Current.player().getName(), enemy.getName()));
|
||||
});
|
||||
|
||||
@@ -127,7 +127,7 @@ public class NewGameScene extends MenuScene {
|
||||
modeNames[i] = modes.get(i).getName();
|
||||
mode.setTextList(modeNames);
|
||||
|
||||
gender.setTextList(new String[]{Forge.getLocalizer().getInstance().getMessage("lblMale"), Forge.getLocalizer().getInstance().getMessage("lblFemale")});
|
||||
gender.setTextList(new String[]{Forge.getLocalizer().getMessage("lblMale"), Forge.getLocalizer().getMessage("lblFemale")});
|
||||
gender.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
@@ -217,7 +217,7 @@ public class NewGameScene extends MenuScene {
|
||||
}
|
||||
Forge.switchScene(GameScene.instance());
|
||||
};
|
||||
Forge.setTransitionScreen(new TransitionScreen(runnable, null, false, true, "Generating World..."));
|
||||
Forge.setTransitionScreen(new TransitionScreen(runnable, null, false, true, Forge.getLocalizer().getMessage("lblGeneratingWorld")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ public class PlayerStatisticScene extends UIScene {
|
||||
if (g != null) //skip variants
|
||||
continue;
|
||||
}
|
||||
a.updateTrophyImage();
|
||||
TextureRegion textureRegion = new TextureRegion(((FBufferedImage) a.getImage()).getTexture());
|
||||
textureRegion.flip(false, true);
|
||||
Image image = new Image(textureRegion);
|
||||
|
||||
@@ -196,14 +196,19 @@ public class SaveLoadScene extends UIScene {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean loaded = false;
|
||||
|
||||
public void loadSave() {
|
||||
if (loaded)
|
||||
return;
|
||||
loaded = true;
|
||||
switch (mode) {
|
||||
case Save:
|
||||
if (TileMapScene.instance().currentMap().isInMap()) {
|
||||
//Access to screen should be disabled, but stop the process just in case.
|
||||
//Saving needs to be disabled inside maps until we can capture and load exact map state
|
||||
//Otherwise location based events for quests can be skipped by saving and then loading outside the map
|
||||
Dialog noSave = createGenericDialog("", "!!GAME NOT SAVED!!\nManual saving is only available on the world map","OK",null, null, null);
|
||||
Dialog noSave = createGenericDialog("", Forge.getLocalizer().getMessage("lblGameNotSaved"), Forge.getLocalizer().getMessage("lblOK"),null, null, null);
|
||||
showDialog(noSave);
|
||||
return;
|
||||
}
|
||||
@@ -226,17 +231,19 @@ public class SaveLoadScene extends UIScene {
|
||||
showDialog(saveDialog);
|
||||
stage.setKeyboardFocus(textInput);
|
||||
}
|
||||
loaded = false;
|
||||
break;
|
||||
case Load:
|
||||
try {
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
loaded = false;
|
||||
if (WorldSave.load(currentSlot)) {
|
||||
SoundSystem.instance.changeBackgroundTrack();
|
||||
Forge.switchScene(GameScene.instance());
|
||||
} else {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
}, null, false, true, "Loading World..."));
|
||||
}, null, false, true, Forge.getLocalizer().getMessage("lblLoadingWorld")));
|
||||
} catch (Exception e) {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
@@ -244,6 +251,7 @@ public class SaveLoadScene extends UIScene {
|
||||
case NewGamePlus:
|
||||
try {
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
loaded = false;
|
||||
if (WorldSave.load(currentSlot)) {
|
||||
WorldSave.getCurrentSave().clearChanges();
|
||||
WorldSave.getCurrentSave().getWorld().generateNew(0);
|
||||
@@ -261,8 +269,9 @@ public class SaveLoadScene extends UIScene {
|
||||
} else {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
}, null, false, true, "Generating World..."));
|
||||
}, null, false, true, Forge.getLocalizer().getMessage("lblGeneratingWorld")));
|
||||
} catch (Exception e) {
|
||||
loaded = false;
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
import com.github.tommyettinger.textra.TextraButton;
|
||||
import com.github.tommyettinger.textra.TypingLabel;
|
||||
import forge.Forge;
|
||||
import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.stage.GameStage;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.localinstance.properties.ForgeProfileProperties;
|
||||
import forge.screens.TransitionScreen;
|
||||
import forge.sound.SoundSystem;
|
||||
import forge.util.ZipUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* First scene after the splash screen
|
||||
*/
|
||||
public class StartScene extends UIScene {
|
||||
|
||||
private static StartScene object;
|
||||
Dialog exitDialog;
|
||||
Dialog exitDialog, backupDialog, zipDialog, unzipDialog;
|
||||
TextraButton saveButton, resumeButton, continueButton;
|
||||
TypingLabel version = Controls.newTypingLabel("{GRADIENT}[%80]" + Forge.CURRENT_VERSION + "{ENDGRADIENT}");
|
||||
|
||||
|
||||
public StartScene() {
|
||||
@@ -30,6 +39,7 @@ public class StartScene extends UIScene {
|
||||
ui.onButtonPress("Resume", StartScene.this::Resume);
|
||||
ui.onButtonPress("Continue", StartScene.this::Continue);
|
||||
ui.onButtonPress("Settings", StartScene.this::settings);
|
||||
ui.onButtonPress("Backup", StartScene.this::backup);
|
||||
ui.onButtonPress("Exit", StartScene.this::Exit);
|
||||
ui.onButtonPress("Switch", StartScene.this::switchToClassic);
|
||||
|
||||
@@ -40,6 +50,9 @@ public class StartScene extends UIScene {
|
||||
|
||||
saveButton.setVisible(false);
|
||||
resumeButton.setVisible(false);
|
||||
version.setHeight(5);
|
||||
version.skipToTheEnd();
|
||||
ui.addActor(version);
|
||||
}
|
||||
|
||||
public static StartScene instance() {
|
||||
@@ -55,7 +68,7 @@ public class StartScene extends UIScene {
|
||||
|
||||
public boolean Save() {
|
||||
if (TileMapScene.instance().currentMap().isInMap()) {
|
||||
Dialog noSave = createGenericDialog("", "!!GAME NOT SAVED!!\nManual saving is only available on the world map","OK",null, null, null);
|
||||
Dialog noSave = createGenericDialog("", Forge.getLocalizer().getMessage("lblGameNotSaved"), Forge.getLocalizer().getMessage("lblOK"),null, null, null);
|
||||
showDialog(noSave);
|
||||
} else {
|
||||
SaveLoadScene.instance().setMode(SaveLoadScene.Modes.Save);
|
||||
@@ -79,20 +92,27 @@ public class StartScene extends UIScene {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean loaded = false;
|
||||
|
||||
public boolean Continue() {
|
||||
final String lastActiveSave = Config.instance().getSettingData().lastActiveSave;
|
||||
|
||||
if (WorldSave.isSafeFile(lastActiveSave)) {
|
||||
if (loaded)
|
||||
return true;
|
||||
loaded = true;
|
||||
try {
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
loaded = false;
|
||||
if (WorldSave.load(WorldSave.filenameToSlot(lastActiveSave))) {
|
||||
SoundSystem.instance.changeBackgroundTrack();
|
||||
Forge.switchScene(GameScene.instance());
|
||||
} else {
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
}, null, false, true, "Loading World..."));
|
||||
}, null, false, true, Forge.getLocalizer().getMessage("lblLoadingWorld")));
|
||||
} catch (Exception e) {
|
||||
loaded = false;
|
||||
Forge.clearTransitionScreen();
|
||||
}
|
||||
}
|
||||
@@ -105,6 +125,86 @@ public class StartScene extends UIScene {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean backup() {
|
||||
if (backupDialog == null) {
|
||||
backupDialog = createGenericDialog(Forge.getLocalizer().getMessage("lblData"),
|
||||
null, Forge.getLocalizer().getMessage("lblBackup"),
|
||||
Forge.getLocalizer().getMessage("lblRestore"),
|
||||
() -> {
|
||||
removeDialog();
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
generateBackup();
|
||||
}
|
||||
}, 0.2f);
|
||||
},
|
||||
() -> {
|
||||
removeDialog();
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
restoreBackup();
|
||||
}
|
||||
}, 0.2f);
|
||||
}, true, Forge.getLocalizer().getMessage("lblCancel"));
|
||||
}
|
||||
showDialog(backupDialog);
|
||||
return true;
|
||||
}
|
||||
public boolean generateBackup() {
|
||||
try {
|
||||
File source = new FileHandle(ForgeProfileProperties.getUserDir() + "/adventure/Shandalar").file();
|
||||
File target = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir()).file();
|
||||
ZipUtil.zip(source, target, ZipUtil.backupAdvFile);
|
||||
zipDialog = createGenericDialog("",
|
||||
Forge.getLocalizer().getMessage("lblSaveLocation") + "\n" + target.getAbsolutePath() + File.separator + ZipUtil.backupAdvFile,
|
||||
Forge.getLocalizer().getMessage("lblOK"), null, this::removeDialog, null);
|
||||
} catch (IOException e) {
|
||||
zipDialog = createGenericDialog("",
|
||||
Forge.getLocalizer().getMessage("lblErrorSavingFile") + "\n\n" + e.getMessage(),
|
||||
Forge.getLocalizer().getMessage("lblOK"), null, this::removeDialog, null);
|
||||
} finally {
|
||||
showDialog(zipDialog);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean restoreBackup() {
|
||||
File source = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir() + ZipUtil.backupAdvFile).file();
|
||||
File target = new FileHandle(ForgeProfileProperties.getUserDir() + "/adventure/Shandalar").file().getParentFile();
|
||||
if (unzipDialog == null) {
|
||||
unzipDialog = createGenericDialog("",
|
||||
Forge.getLocalizer().getMessage("lblDoYouWantToRestoreBackup"),
|
||||
Forge.getLocalizer().getMessage("lblYes"), Forge.getLocalizer().getMessage("lblNo"),
|
||||
() -> {
|
||||
removeDialog();
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
extract(source, target);
|
||||
}
|
||||
}, 0.2f);
|
||||
}, this::removeDialog);
|
||||
}
|
||||
showDialog(unzipDialog);
|
||||
return true;
|
||||
}
|
||||
public boolean extract(File source, File target) {
|
||||
String title = "", val = "";
|
||||
try {
|
||||
val = Forge.getLocalizer().getMessage("lblFiles") + ":\n" + ZipUtil.unzip(source, target);
|
||||
} catch (IOException e) {
|
||||
title = Forge.getLocalizer().getMessage("lblError");
|
||||
val = e.getMessage();
|
||||
} finally {
|
||||
Config.instance().getSettingData().lastActiveSave = null;
|
||||
Config.instance().saveSettings();
|
||||
showDialog(createGenericDialog(title, val,
|
||||
Forge.getLocalizer().getMessage("lblOK"), null, this::removeDialog, null));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean Exit() {
|
||||
if (exitDialog == null) {
|
||||
exitDialog = createGenericDialog(Forge.getLocalizer().getMessage("lblExitForge"),
|
||||
@@ -123,16 +223,7 @@ public class StartScene extends UIScene {
|
||||
Forge.switchToClassic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
boolean hasSaveButton = WorldSave.getCurrentSave().getWorld().getData() != null;
|
||||
if (hasSaveButton) {
|
||||
TileMapScene scene = TileMapScene.instance();
|
||||
hasSaveButton = !scene.currentMap().isInMap() || scene.isAutoHealLocation();
|
||||
}
|
||||
saveButton.setVisible(hasSaveButton);
|
||||
saveButton.setDisabled(TileMapScene.instance().currentMap().isInMap());
|
||||
|
||||
public void updateResumeContinue() {
|
||||
boolean hasResumeButton = WorldSave.getCurrentSave().getWorld().getData() != null;
|
||||
resumeButton.setVisible(hasResumeButton);
|
||||
|
||||
@@ -146,7 +237,18 @@ public class StartScene extends UIScene {
|
||||
} else {
|
||||
continueButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
boolean hasSaveButton = WorldSave.getCurrentSave().getWorld().getData() != null;
|
||||
if (hasSaveButton) {
|
||||
TileMapScene scene = TileMapScene.instance();
|
||||
hasSaveButton = !scene.currentMap().isInMap() || scene.isAutoHealLocation();
|
||||
}
|
||||
saveButton.setVisible(hasSaveButton);
|
||||
saveButton.setDisabled(TileMapScene.instance().currentMap().isInMap());
|
||||
updateResumeContinue();
|
||||
|
||||
if (Forge.createNewAdventureMap) {
|
||||
this.NewGame();
|
||||
|
||||
@@ -239,6 +239,9 @@ public class UIScene extends Scene {
|
||||
}
|
||||
|
||||
public Dialog createGenericDialog(String title, String label, String stringYes, String stringNo, Runnable runnableYes, Runnable runnableNo) {
|
||||
return createGenericDialog(title, label, stringYes, stringNo, runnableYes, runnableNo, false, "");
|
||||
}
|
||||
public Dialog createGenericDialog(String title, String label, String stringYes, String stringNo, Runnable runnableYes, Runnable runnableNo, boolean cancelButton, String stringCancel) {
|
||||
Dialog dialog = new Dialog(title == null ? "" : title, Controls.getSkin());
|
||||
if (label != null)
|
||||
dialog.text(label);
|
||||
@@ -248,6 +251,10 @@ public class UIScene extends Scene {
|
||||
TextraButton no = Controls.newTextButton(stringNo, runnableNo);
|
||||
dialog.button(no);
|
||||
}
|
||||
if (cancelButton) {
|
||||
TextraButton cancel = Controls.newTextButton(stringCancel, this::removeDialog);
|
||||
dialog.button(cancel);
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ConsoleCommandInterpreter {
|
||||
public String complete(String text) {
|
||||
String[] words = splitOnSpace(text);
|
||||
Command currentCommand = root;
|
||||
String completionString = "";
|
||||
StringBuilder completionString = new StringBuilder();
|
||||
for (String name : words) {
|
||||
if (!currentCommand.children.containsKey(name)) {
|
||||
for (String key : currentCommand.children.keySet()) {
|
||||
@@ -49,7 +49,7 @@ public class ConsoleCommandInterpreter {
|
||||
}
|
||||
break;
|
||||
}
|
||||
completionString += name + " ";
|
||||
completionString.append(name).append(" ");
|
||||
currentCommand = currentCommand.children.get(name);
|
||||
}
|
||||
return text;
|
||||
|
||||
@@ -1039,6 +1039,7 @@ public class MapStage extends GameStage {
|
||||
}
|
||||
}
|
||||
|
||||
boolean started = false;
|
||||
public void beginDuel(EnemySprite mob) {
|
||||
if (mob == null) return;
|
||||
mob.clearCollisionHeight();
|
||||
@@ -1054,6 +1055,9 @@ public class MapStage extends GameStage {
|
||||
Forge.restrictAdvMenus = true;
|
||||
player.clearCollisionHeight();
|
||||
startPause(0.8f, () -> {
|
||||
if (started)
|
||||
return;
|
||||
started = true;
|
||||
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
|
||||
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
|
||||
DuelScene duelScene = DuelScene.instance();
|
||||
@@ -1061,6 +1065,7 @@ public class MapStage extends GameStage {
|
||||
if (!isLoadingMatch) {
|
||||
isLoadingMatch = true;
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
started = false;
|
||||
duelScene.initDuels(player, mob);
|
||||
if (isInMap && effect != null && !mob.ignoreDungeonEffect)
|
||||
duelScene.setDungeonEffect(effect);
|
||||
|
||||
@@ -64,6 +64,7 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
final Rectangle tempBoundingRect = new Rectangle();
|
||||
final Vector2 enemyMoveVector = new Vector2();
|
||||
|
||||
boolean collided = false;
|
||||
@Override
|
||||
protected void onActing(float delta) {
|
||||
if (isPaused() || MapStage.getInstance().isDialogOnlyInput())
|
||||
@@ -110,6 +111,9 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
}
|
||||
|
||||
if (player.collideWith(mob)) {
|
||||
if (collided)
|
||||
return;
|
||||
collided = true;
|
||||
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
player.playEffect(Paths.EFFECT_SPARKS, 0.5f);
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
@@ -126,6 +130,7 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
DuelScene duelScene = DuelScene.instance();
|
||||
FThreads.invokeInEdtNowOrLater(() -> {
|
||||
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||
collided = false;
|
||||
duelScene.initDuels(player, mob);
|
||||
Forge.switchScene(duelScene);
|
||||
}, Forge.takeScreenshot(), true, false, false, false, "", Current.player().avatar(), mob.getAtlasPath(), Current.player().getName(), mob.getName()));
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.badlogic.gdx.utils.Timer;
|
||||
import com.github.tommyettinger.textra.Font;
|
||||
import com.github.tommyettinger.textra.TextraButton;
|
||||
import com.github.tommyettinger.textra.TextraLabel;
|
||||
import com.github.tommyettinger.textra.TypingButton;
|
||||
import com.github.tommyettinger.textra.TypingLabel;
|
||||
import forge.Forge;
|
||||
import forge.adventure.player.AdventurePlayer;
|
||||
@@ -84,12 +85,53 @@ public class Controls {
|
||||
|
||||
}
|
||||
|
||||
static class TypingButtonFix extends TypingButton {
|
||||
public TypingButtonFix(@Null String text) {
|
||||
super(text == null ? "NULL" : text, Controls.getSkin(), Controls.getTextraFont());
|
||||
addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
super.clicked(event, x, y);
|
||||
SoundSystem.instance.play(SoundEffectType.ButtonPress, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(Button.ButtonStyle style, boolean makeGridGlyphs) {
|
||||
super.setStyle(style, makeGridGlyphs);
|
||||
this.getTextraLabel().setFont(Controls.getTextraFont());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return this.getTextraLabel().storedText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(@Null String text) {
|
||||
getTextraLabel().storedText = text;
|
||||
getTextraLabel().layout.setTargetWidth(getTextraLabel().getMaxWidth());
|
||||
getTextraLabel().getFont().markup(text, getTextraLabel().layout.clear());
|
||||
getTextraLabel().setWidth(getTextraLabel().layout.getWidth() + (getTextraLabel().style != null && getTextraLabel().style.background != null ? getTextraLabel().style.background.getLeftWidth() + getTextraLabel().style.background.getRightWidth() : 0.0F));
|
||||
layout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static public TextraButton newTextButton(String text) {
|
||||
TextraButton button = new TextButtonFix(text);
|
||||
button.getTextraLabel().setWrap(false);
|
||||
return button;
|
||||
}
|
||||
|
||||
static public TypingButton newTypingButton(String text) {
|
||||
TypingButton button = new TypingButtonFix(text);
|
||||
button.getTextraLabel().setWrap(false);
|
||||
return button;
|
||||
}
|
||||
|
||||
static public Rectangle getBoundingRect(Actor actor) {
|
||||
return new Rectangle(actor.getX(), actor.getY(), actor.getWidth(), actor.getHeight());
|
||||
}
|
||||
|
||||
@@ -354,11 +354,10 @@ public class SaveFileData extends HashMap<String,byte[]>
|
||||
final long localSUID = localClassDescriptor.getSerialVersionUID();
|
||||
final long streamSUID = resultClassDescriptor.getSerialVersionUID();
|
||||
if (streamSUID != localSUID) { // check for serialVersionUID mismatch.
|
||||
final StringBuffer s = new StringBuffer("Overriding serialized class version mismatch: ");
|
||||
s.append("local serialVersionUID = ").append(localSUID);
|
||||
s.append(" stream serialVersionUID = ").append(streamSUID);
|
||||
String s = "Overriding serialized class version mismatch: " + "local serialVersionUID = " + localSUID +
|
||||
" stream serialVersionUID = " + streamSUID;
|
||||
|
||||
System.err.println("[Invalid Class Exception]\n"+s);
|
||||
System.err.println("[Invalid Class Exception]\n"+ s);
|
||||
resultClassDescriptor = localClassDescriptor; // Use local class descriptor for deserialization
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ public class TemplateTmxMapLoader extends TmxMapLoader {
|
||||
|
||||
this.root = xml.parse(tmxFile);
|
||||
parameter.generateMipMaps=true;
|
||||
parameter.textureMinFilter = Texture.TextureFilter.Nearest;
|
||||
parameter.textureMagFilter = Texture.TextureFilter.Nearest;
|
||||
final Array<FileHandle> textureFiles = getDependencyFileHandles(tmxFile);
|
||||
for (FileHandle textureFile : textureFiles) {
|
||||
Texture texture = new Texture(textureFile, parameter.generateMipMaps);
|
||||
|
||||
@@ -23,13 +23,10 @@ public class NavigationMap {
|
||||
this.half = spriteSize / 2;
|
||||
}
|
||||
|
||||
RayCastCallback callback = new RayCastCallback() {
|
||||
@Override
|
||||
public float reportRayFixture(Fixture fixture, Vector2 vector2, Vector2 vector21, float v) {
|
||||
RayCastCallback callback = (fixture, vector2, vector21, v) -> {
|
||||
if (v < 1.0)
|
||||
rayCollided = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// public void initializeOverworldGeometryGraph() {
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.ArrayList;
|
||||
public class BiomeTexture implements Serializable {
|
||||
private final BiomeData data;
|
||||
private final int tileSize;
|
||||
public static Pixmap emptyPixmap = null;
|
||||
public Pixmap emptyPixmap = null;
|
||||
ArrayList<ArrayList<Pixmap>> images = new ArrayList<>();
|
||||
ArrayList<ArrayList<Pixmap>> smallImages = new ArrayList<>();
|
||||
ArrayList<IntMap<Pixmap>> edgeImages = new ArrayList<>();
|
||||
|
||||
@@ -25,6 +25,7 @@ public enum AbilityEffect {
|
||||
if (soundClip == null) {
|
||||
soundClip = AudioClip.createClip(ForgeConstants.EFFECTS_DIR + wav);
|
||||
}
|
||||
if (soundClip != null)
|
||||
soundClip.play(FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_SOUNDS)/100f);
|
||||
animation.start();
|
||||
}
|
||||
|
||||
@@ -75,11 +75,21 @@
|
||||
"name": "Settings",
|
||||
"text": "tr(lblSettings)",
|
||||
"selectable": true,
|
||||
"width": 160,
|
||||
"width": 80,
|
||||
"height": 30,
|
||||
"x": 160,
|
||||
"y": 180
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "Backup",
|
||||
"text": "tr(lblData)",
|
||||
"selectable": true,
|
||||
"width": 80,
|
||||
"height": 30,
|
||||
"x": 240,
|
||||
"y": 180
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "Exit",
|
||||
|
||||
@@ -64,11 +64,21 @@
|
||||
"name": "Settings",
|
||||
"text": "tr(lblSettings)",
|
||||
"selectable": true,
|
||||
"width": 238,
|
||||
"width": 118,
|
||||
"height": 48,
|
||||
"x": 16,
|
||||
"yOffset": 8
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "Backup",
|
||||
"text": "tr(lblData)",
|
||||
"selectable": true,
|
||||
"width": 118,
|
||||
"height": 48,
|
||||
"x": 134,
|
||||
"yOffset": -48
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"name": "Switch",
|
||||
|
||||
@@ -361,6 +361,14 @@ lblAutoYields=Automatische Bestätigung
|
||||
lblDeckList=Deckliste
|
||||
lblClose=Schließen
|
||||
lblExitForge=Forge verlassen
|
||||
lblLoadingWorld=Welt wird geladen...
|
||||
lblGeneratingWorld=Welt erzeugen...
|
||||
lblGameNotSaved=!!SPIEL NICHT GESPEICHERT!!\nManuelles Speichern ist nur auf der Weltkarte verfügbar
|
||||
lblBackup=Sicherung
|
||||
lblRestore=Wiederherstellen
|
||||
lblData=Daten
|
||||
lblSaveLocation=Sicherer Ort:
|
||||
lblDoYouWantToRestoreBackup=Durch das Wiederherstellen des Backups werden alle Ihre Speicherungen überschrieben. Möchtest du fortfahren?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Wähle Avatar für %s
|
||||
lblRemoveSmallCreatures=Entferne 1/1- und 0/X-Kreaturen aus erzeugten Decks
|
||||
|
||||
@@ -363,6 +363,14 @@ lblAutoYields=Auto-Yields
|
||||
lblDeckList=Deck List
|
||||
lblClose=Close
|
||||
lblExitForge=Exit Forge
|
||||
lblLoadingWorld=Loading World...
|
||||
lblGeneratingWorld=Generating World...
|
||||
lblGameNotSaved=!!GAME NOT SAVED!!\nManual saving is only available on the world map
|
||||
lblBackup=Backup
|
||||
lblRestore=Restore
|
||||
lblData=Data
|
||||
lblSaveLocation=Save Location:
|
||||
lblDoYouWantToRestoreBackup=Restoring backup will overwrite all of your save. Do you want to continue?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Select avatar for %s
|
||||
lblRemoveSmallCreatures=Remove 1/1 and 0/X creatures in generated decks.
|
||||
|
||||
@@ -361,6 +361,14 @@ lblAutoYields=Auto-ceder
|
||||
lblDeckList=Lista del mazo
|
||||
lblClose=Cerrar
|
||||
lblExitForge=Salir de Forge
|
||||
lblLoadingWorld=Cargando mundo...
|
||||
lblGeneratingWorld=Generando mundo...
|
||||
lblGameNotSaved=!!JUEGO NO GUARDADO!!\nEl guardado manual solo está disponible en el mapa mundial
|
||||
lblBackup=Respaldo
|
||||
lblRestore=Restaurar
|
||||
lblData=Datos
|
||||
lblSaveLocation=Guardar dirección:
|
||||
lblDoYouWantToRestoreBackup=Restaurar la copia de seguridad sobrescribirá todo lo que guardó. ¿Quieres continuar?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Seleccionar avatar para %s
|
||||
lblRemoveSmallCreatures=Elimina 1/1 y 0 /X criaturas en los mazos generados.
|
||||
|
||||
@@ -361,6 +361,14 @@ lblAutoYields=Rendements automatiques
|
||||
lblDeckList=Liste des decks
|
||||
lblClose=Fermer
|
||||
lblExitForge=Quitter Forge
|
||||
lblLoadingWorld=Chargement du monde...
|
||||
lblGeneratingWorld=Générer le monde...
|
||||
lblGameNotSaved=!!JEU NON ENREGISTRÉ !!\nLa sauvegarde manuelle n'est disponible que sur la carte du monde
|
||||
lblBackup=Sauvegarde
|
||||
lblRestore=Restaurer
|
||||
lblData=Données
|
||||
lblSaveLocation=Enregistrer l'emplacement:
|
||||
lblDoYouWantToRestoreBackup=La restauration de la sauvegarde écrasera toute votre sauvegarde. Voulez-vous continuer?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Sélectionner un avatar pour %s
|
||||
lblRemoveSmallCreatures=Retire les créatures 1/1 et 0/X dans les decks générés.
|
||||
|
||||
@@ -360,6 +360,14 @@ lblAutoYields=Consensi automatici
|
||||
lblDeckList=Lista del mazzo
|
||||
lblClose=Chiudi
|
||||
lblExitForge=Esci da Forge
|
||||
lblLoadingWorld=Caricamento del mondo...
|
||||
lblGeneratingWorld=Generazione del mondo...
|
||||
lblGameNotSaved=!!GIOCO NON SALVATO!!\nIl salvataggio manuale è disponibile solo sulla mappa del mondo
|
||||
lblBackup=Backup
|
||||
lblRestore=Ristabilire
|
||||
lblData=Dati
|
||||
lblSaveLocation=Salva l'indirizzo:
|
||||
lblDoYouWantToRestoreBackup=Il ripristino del backup sovrascriverà tutti i tuoi salvataggi. Vuoi continuare?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Seleziona avatar per %s
|
||||
lblRemoveSmallCreatures=Rimuovi le creature 1/1 e 0 / X nei mazzi generati.
|
||||
|
||||
@@ -361,6 +361,14 @@ lblAutoYields=優先権の自動放棄
|
||||
lblDeckList=デッキリスト
|
||||
lblClose=閉じる
|
||||
lblExitForge=Forge を終了します
|
||||
lblLoadingWorld=世界を読み込んでいます...
|
||||
lblGeneratingWorld=ワールドを生成中...
|
||||
lblGameNotSaved=!!ゲームは保存されていません!!\n手動保存はワールドマップでのみ使用できます
|
||||
lblBackup=バックアップ
|
||||
lblRestore=復元する
|
||||
lblData=データ
|
||||
lblSaveLocation=位置を保存:
|
||||
lblDoYouWantToRestoreBackup=バックアップを復元すると、保存内容がすべて上書きされます。続けたいですか?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=%sアバターのデッキを選択
|
||||
lblRemoveSmallCreatures=生成されたデッキに 1/1 および 0/X クリーチャーを含まない。
|
||||
|
||||
@@ -373,6 +373,14 @@ lblAutoYields=Resolver automático
|
||||
lblDeckList=Lista de Deck
|
||||
lblClose=Fechar
|
||||
lblExitForge=Sair da Forge
|
||||
lblLoadingWorld=Carregando mundo...
|
||||
lblGeneratingWorld=Gerando mundo...
|
||||
lblGameNotSaved=!!JOGO NÃO SALVO!!\nO salvamento manual só está disponível no mapa mundial
|
||||
lblBackup=Cópia de segurança
|
||||
lblRestore=Restaurar
|
||||
lblData=Dados
|
||||
lblSaveLocation=Salvar localização:
|
||||
lblDoYouWantToRestoreBackup=A restauração do backup substituirá todos os seus dados salvos. Você quer continuar?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=Escolha o avatar para %s
|
||||
lblRemoveSmallCreatures=Remover criaturas 1/1 e 0/X dos decks gerados.
|
||||
|
||||
@@ -361,6 +361,14 @@ lblAutoYields=自动让过
|
||||
lblDeckList=套牌列表
|
||||
lblClose=关闭
|
||||
lblExitForge=退出Forge
|
||||
lblLoadingWorld=正在加载世界...
|
||||
lblGeneratingWorld=生成世界...
|
||||
lblGameNotSaved=!!游戏未保存!!\n手动保存仅在世界地图上可用
|
||||
lblBackup=备份
|
||||
lblRestore=恢复
|
||||
lblData=数据
|
||||
lblSaveLocation=保存位置:
|
||||
lblDoYouWantToRestoreBackup=恢复备份将覆盖您的所有保存。你想继续吗?
|
||||
#ConstructedGameMenu.java
|
||||
lblSelectAvatarFor=为%s选择头像
|
||||
lblRemoveSmallCreatures=将1/1和0/X生物从生成套牌中移除。
|
||||
|
||||
@@ -128,7 +128,7 @@ public abstract class Achievement {
|
||||
return earnedSpecial() || earnedMythic() || earnedRare() || earnedUncommon() || earnedCommon();
|
||||
}
|
||||
|
||||
private void updateTrophyImage() {
|
||||
public void updateTrophyImage() {
|
||||
FSkinProp background;
|
||||
float opacity = 1;
|
||||
if (earnedSpecial()) {
|
||||
|
||||
99
forge-gui/src/main/java/forge/util/ZipUtil.java
Normal file
99
forge-gui/src/main/java/forge/util/ZipUtil.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package forge.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/*
|
||||
* https://www.baeldung.com/java-compress-and-uncompress
|
||||
*/
|
||||
public class ZipUtil {
|
||||
public static String backupAdvFile = "forge.adv";
|
||||
public static void zip(File source, File dest, String name) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(dest.getAbsolutePath() + File.separator + name);
|
||||
ZipOutputStream zipOut = new ZipOutputStream(fos);
|
||||
zipFile(source, source.getName(), zipOut);
|
||||
zipOut.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
|
||||
if (fileToZip.isHidden()) {
|
||||
return;
|
||||
}
|
||||
if (fileToZip.isDirectory()) {
|
||||
if (fileName.endsWith("/")) {
|
||||
zipOut.putNextEntry(new ZipEntry(fileName));
|
||||
zipOut.closeEntry();
|
||||
} else {
|
||||
zipOut.putNextEntry(new ZipEntry(fileName + "/"));
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
File[] children = fileToZip.listFiles();
|
||||
if (children != null) {
|
||||
for (File childFile : children) {
|
||||
zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
FileInputStream fis = new FileInputStream(fileToZip);
|
||||
ZipEntry zipEntry = new ZipEntry(fileName);
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
byte[] bytes = new byte[1024];
|
||||
int length;
|
||||
while ((length = fis.read(bytes)) >= 0) {
|
||||
zipOut.write(bytes, 0, length);
|
||||
}
|
||||
fis.close();
|
||||
}
|
||||
|
||||
public static String unzip(File fileZip, File destDir) throws IOException {
|
||||
StringBuilder val = new StringBuilder();
|
||||
byte[] buffer = new byte[1024];
|
||||
ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip));
|
||||
ZipEntry zipEntry = zis.getNextEntry();
|
||||
while (zipEntry != null) {
|
||||
File newFile = newFile(destDir, zipEntry);
|
||||
if (zipEntry.isDirectory()) {
|
||||
if (!newFile.isDirectory() && !newFile.mkdirs()) {
|
||||
throw new IOException("Failed to create directory " + newFile);
|
||||
}
|
||||
} else {
|
||||
// fix for Windows-created archives
|
||||
File parent = newFile.getParentFile();
|
||||
if (!parent.isDirectory() && !parent.mkdirs()) {
|
||||
throw new IOException("Failed to create directory " + parent);
|
||||
}
|
||||
|
||||
// write file content
|
||||
val.append(" * "). append(newFile.getName()).append("\n");
|
||||
FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
}
|
||||
zipEntry = zis.getNextEntry();
|
||||
}
|
||||
|
||||
zis.closeEntry();
|
||||
zis.close();
|
||||
return val.toString();
|
||||
}
|
||||
|
||||
private static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
|
||||
File destFile = new File(destinationDir, zipEntry.getName());
|
||||
|
||||
String destDirPath = destinationDir.getCanonicalPath();
|
||||
String destFilePath = destFile.getCanonicalPath();
|
||||
|
||||
if (!destFilePath.startsWith(destDirPath + File.separator)) {
|
||||
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
|
||||
}
|
||||
|
||||
return destFile;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user