amidstest/src/main/java/amidst/gui/main/Actions.java

368 lines
11 KiB
Java

package amidst.gui.main;
import java.awt.Component;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.function.Supplier;
import javax.imageio.ImageIO;
import amidst.Application;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gameengineabstraction.GameEngineType;
import amidst.gui.crash.CrashWindow;
import amidst.gui.main.menu.MovePlayerPopupMenu;
import amidst.gui.main.viewer.ViewerFacade;
import amidst.gui.seedsearcher.SeedSearcherWindow;
import amidst.logging.AmidstLogger;
import amidst.mojangapi.world.WorldSeed;
import amidst.mojangapi.world.WorldType;
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
import amidst.mojangapi.world.icon.WorldIcon;
import amidst.mojangapi.world.player.Player;
import amidst.mojangapi.world.player.PlayerCoordinates;
import amidst.settings.biomeprofile.BiomeProfile;
import amidst.settings.biomeprofile.BiomeProfileSelection;
import amidst.util.FileExtensionChecker;
@NotThreadSafe
public class Actions {
private final Application application;
private final MainWindowDialogs dialogs;
private final WorldSwitcher worldSwitcher;
private final SeedSearcherWindow seedSearcherWindow;
private final Supplier<ViewerFacade> viewerFacadeSupplier;
private final BiomeProfileSelection biomeProfileSelection;
private final GameEngineType gameEngineType;
@CalledOnlyBy(AmidstThread.EDT)
public Actions(
Application application,
MainWindowDialogs dialogs,
WorldSwitcher worldSwitcher,
SeedSearcherWindow seedSearcherWindow,
Supplier<ViewerFacade> viewerFacadeSupplier,
BiomeProfileSelection biomeProfileSelection,
GameEngineType gameEngineType) {
this.application = application;
this.dialogs = dialogs;
this.worldSwitcher = worldSwitcher;
this.seedSearcherWindow = seedSearcherWindow;
this.viewerFacadeSupplier = viewerFacadeSupplier;
this.biomeProfileSelection = biomeProfileSelection;
this.gameEngineType = gameEngineType;
}
@CalledOnlyBy(AmidstThread.EDT)
public void newFromSeed() {
WorldSeed seed = dialogs.askForSeed(gameEngineType);
if (seed != null) {
newFromSeed(seed);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void newFromRandom() {
newFromSeed(WorldSeed.random(gameEngineType));
}
@CalledOnlyBy(AmidstThread.EDT)
private void newFromSeed(WorldSeed worldSeed) {
WorldType worldType = dialogs.askForWorldType();
if (worldType != null) {
worldSwitcher.displayWorld(worldSeed, worldType);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void searchForRandom() {
seedSearcherWindow.show();
}
@CalledOnlyBy(AmidstThread.EDT)
public void openSaveGame() {
File file = dialogs.askForSaveGame();
if (file != null) {
worldSwitcher.displayWorld(file);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void export() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.export(dialogs.askForExportConfiguration());
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void switchProfile() {
application.displayProfileSelectWindow();
}
@CalledOnlyBy(AmidstThread.EDT)
public void exit() {
application.exitGracefully();
}
@CalledOnlyBy(AmidstThread.EDT)
public void goToCoordinate() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
String input = dialogs.askForCoordinates();
if (input != null) {
CoordinatesInWorld coordinates = CoordinatesInWorld.tryParse(input);
if (coordinates != null) {
viewerFacade.centerOn(coordinates);
} else {
AmidstLogger.warn("Invalid location entered, ignoring.");
dialogs.displayError("You entered an invalid location.");
}
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void goToSpawn() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.centerOn(viewerFacade.getSpawnWorldIcon());
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void goToStronghold() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
WorldIcon stronghold = dialogs
.askForOptions("Go to", "Select Stronghold:", viewerFacade.getStrongholdWorldIcons());
if (stronghold != null) {
viewerFacade.centerOn(stronghold);
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void goToPlayer() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
List<WorldIcon> playerWorldIcons = viewerFacade.getPlayerWorldIcons();
if (!playerWorldIcons.isEmpty()) {
WorldIcon player = dialogs.askForOptions("Go to", "Select player:", playerWorldIcons);
if (player != null) {
viewerFacade.centerOn(player);
}
} else {
AmidstLogger.warn("There are no players in this world.");
dialogs.displayError("There are no players in this world.");
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void zoomIn() {
adjustZoom(-1);
}
@CalledOnlyBy(AmidstThread.EDT)
public void zoomOut() {
adjustZoom(1);
}
@CalledOnlyBy(AmidstThread.EDT)
public void savePlayerLocations() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
if (dialogs.askToConfirmSaveGameManipulation()) {
viewerFacade.savePlayerLocations();
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void reloadPlayerLocations() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.loadPlayers();
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void howCanIMoveAPlayer() {
dialogs.displayInfo(
"How can I move a player?",
"If you load the world from a save game, you can change the player locations.\n"
+ "1. Scroll the map to and right-click on the new player location, this opens a popup menu.\n"
+ "2. Select the player you want to move to the new location.\n"
+ "3. Enter the new player height (y-coordinate).\n" + "4. Save player locations.");
}
@CalledOnlyBy(AmidstThread.EDT)
public void copySeedToClipboard() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
String seed = "" + viewerFacade.getWorldSeed().getLong();
StringSelection selection = new StringSelection(seed);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void takeScreenshot() {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
BufferedImage image = viewerFacade.createScreenshot();
String suggestedFilename = "screenshot_" + viewerFacade.getWorldType().getFilenameText() + "_"
+ viewerFacade.getWorldSeed().getLong() + ".png";
File file = dialogs.askForScreenshotSaveFile(suggestedFilename);
if (file != null) {
file = appendPNGFileExtensionIfNecessary(file);
if (file.exists() && !file.isFile()) {
String message = "Unable to write screenshot, because the target exists but is not a file: "
+ file.getAbsolutePath();
AmidstLogger.warn(message);
dialogs.displayError(message);
} else if (!canWriteToFile(file)) {
String message = "Unable to write screenshot, because you have no writing permissions: "
+ file.getAbsolutePath();
AmidstLogger.warn(message);
dialogs.displayError(message);
} else if (!file.exists() || dialogs.askToConfirmYesNo(
"Replace file?",
"File already exists. Do you want to replace it?\n" + file.getAbsolutePath() + "")) {
saveImageToFile(image, file);
}
}
image.flush();
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void selectBiomeProfile(BiomeProfile profile) {
biomeProfileSelection.set(profile);
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.reloadBackgroundLayer();
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayLogMessages() {
CrashWindow.showForInterest();
}
@CalledOnlyBy(AmidstThread.EDT)
public void checkForUpdates() {
application.checkForUpdates(dialogs);
}
@CalledOnlyBy(AmidstThread.EDT)
public void viewLicense() {
application.displayLicenseWindow();
}
@CalledOnlyBy(AmidstThread.EDT)
public void about() {
dialogs.displayInfo(
"About",
"Amidst - Advanced Minecraft Interfacing and Data/Structure Tracking\n\n"
+ "Author: Skidoodle aka skiphs\n" + "Mail: toolbox4minecraft+amidst@gmail.com\n"
+ "Project Page: https://github.com/toolbox4minecraft/amidst");
}
@CalledOnlyBy(AmidstThread.EDT)
private void adjustZoom(int notches) {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.adjustZoom(notches);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void adjustZoom(Point mousePosition, int notches) {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.adjustZoom(mousePosition, notches);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void selectWorldIcon(WorldIcon worldIcon) {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.selectWorldIcon(worldIcon);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void showPlayerPopupMenu(CoordinatesInWorld targetCoordinates, Component component, int x, int y) {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
if (viewerFacade.canSavePlayerLocations()) {
new MovePlayerPopupMenu(this, viewerFacade.getMovablePlayerList(), targetCoordinates)
.show(component, x, y);
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void movePlayer(Player player, CoordinatesInWorld targetCoordinates) {
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
PlayerCoordinates currentCoordinates = player.getPlayerCoordinates();
long currentHeight = currentCoordinates.getY();
String input = dialogs.askForPlayerHeight(currentHeight);
if (input != null) {
player.moveTo(targetCoordinates, tryParseLong(input, currentHeight), currentCoordinates.getDimension());
viewerFacade.reloadPlayerLayer();
if (dialogs.askToConfirmYesNo("Save Player Locations", "Do you want to save the player locations?")) {
if (dialogs.askToConfirmSaveGameManipulation()) {
viewerFacade.savePlayerLocations();
}
}
}
}
}
@CalledOnlyBy(AmidstThread.EDT)
private long tryParseLong(String text, long defaultValue) {
try {
return Long.parseLong(text);
} catch (NumberFormatException e) {
return defaultValue;
}
}
@CalledOnlyBy(AmidstThread.EDT)
private boolean canWriteToFile(File file) {
File parentFile = file.getParentFile();
return file.canWrite() || (!file.exists() && parentFile != null && parentFile.canWrite());
}
@CalledOnlyBy(AmidstThread.EDT)
private void saveImageToFile(BufferedImage image, File file) {
try {
ImageIO.write(image, "png", file);
} catch (IOException e) {
AmidstLogger.warn(e);
dialogs.displayError(e);
}
}
@CalledOnlyBy(AmidstThread.EDT)
private File appendPNGFileExtensionIfNecessary(File file) {
String filename = file.getAbsolutePath();
if (!FileExtensionChecker.hasFileExtension(filename, "png")) {
filename += ".png";
}
return new File(filename);
}
}