Created ReplayAsset interface and AssetRepository class which can contain such ReplayAssets. ReplayAssets allow users to add custom Files (so far only images, might be extended by .obj files) to the Replay which will later be used for CustomImageObjects.
Created GuiReplayManager to allow users to manage their assets. Created BoundingUtils class to provide a simple method to fit an image into given bounds. This implementation fixes https://trello.com/c/WTnicWkJ/
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
package eu.crushedpixel.replaymod.assets;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
|
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AssetRepository {
|
||||||
|
|
||||||
|
private List<ReplayAsset> replayAssets;
|
||||||
|
|
||||||
|
public AssetRepository() {
|
||||||
|
replayAssets = new ArrayList<ReplayAsset>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplayAsset addAsset(String assetFileName, InputStream inputStream) throws IOException {
|
||||||
|
ReplayAsset asset = assetFromFileName(assetFileName);
|
||||||
|
|
||||||
|
asset.loadFromStream(inputStream);
|
||||||
|
|
||||||
|
replayAssets.add(asset);
|
||||||
|
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAsset(ReplayAsset asset) {
|
||||||
|
replayAssets.remove(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveAssets() {
|
||||||
|
for(ReplayAsset asset : replayAssets) {
|
||||||
|
try {
|
||||||
|
String filepath = ReplayFile.ENTRY_ASSET_FOLDER + asset.getDisplayString() + "." + asset.getSavedFileExtension();
|
||||||
|
|
||||||
|
File toAdd = File.createTempFile(asset.getDisplayString(), asset.getSavedFileExtension());
|
||||||
|
FileOutputStream fos = new FileOutputStream(toAdd);
|
||||||
|
asset.writeToStream(fos);
|
||||||
|
|
||||||
|
ReplayMod.replayFileAppender.registerModifiedFile(toAdd, filepath, ReplayHandler.getReplayFile());
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReplayAsset assetFromFileName(String filename) {
|
||||||
|
String baseName = FilenameUtils.getBaseName(filename);
|
||||||
|
String extension = FilenameUtils.getExtension(filename);
|
||||||
|
|
||||||
|
if(ArrayUtils.contains(AssetFileUtils.fileExtensionsForAssetClass(ReplayImageAsset.class), extension)) {
|
||||||
|
return new ReplayImageAsset(baseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Can't create ReplayAsset from File "+filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package eu.crushedpixel.replaymod.assets;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.holders.GuiEntryListEntry;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public interface ReplayAsset<T> extends GuiEntryListEntry {
|
||||||
|
|
||||||
|
String getSavedFileExtension();
|
||||||
|
|
||||||
|
void loadFromStream(InputStream inputStream) throws IOException;
|
||||||
|
void writeToStream(OutputStream outputStream) throws IOException;
|
||||||
|
|
||||||
|
void drawToScreen(int x, int y, int maxWidth, int maxHeight);
|
||||||
|
|
||||||
|
void setAssetName(String name);
|
||||||
|
|
||||||
|
T getObject();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package eu.crushedpixel.replaymod.assets;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.registry.ResourceHelper;
|
||||||
|
import eu.crushedpixel.replaymod.utils.BoundingUtils;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.Gui;
|
||||||
|
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import org.lwjgl.util.Dimension;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ReplayImageAsset implements ReplayAsset<BufferedImage> {
|
||||||
|
|
||||||
|
private final Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
|
private BufferedImage object;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public ReplayImageAsset(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAssetName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSavedFileExtension() {
|
||||||
|
return "png";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadFromStream(InputStream inputStream) throws IOException {
|
||||||
|
this.object = ImageIO.read(inputStream);
|
||||||
|
ResourceHelper.freeResource(previewResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToStream(OutputStream outputStream) throws IOException {
|
||||||
|
ImageIO.write(object, "png", outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation previewResource = new ResourceLocation("/asset/"+ UUID.randomUUID().toString());
|
||||||
|
private DynamicTexture dynamicTexture;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawToScreen(int x, int y, int maxWidth, int maxHeight) {
|
||||||
|
if(object == null) return;
|
||||||
|
if(!ResourceHelper.isRegistered(previewResource) || dynamicTexture == null) {
|
||||||
|
dynamicTexture = new DynamicTexture(object);
|
||||||
|
mc.getTextureManager().loadTexture(previewResource, dynamicTexture);
|
||||||
|
ResourceHelper.registerResource(previewResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.renderEngine.bindTexture(previewResource);
|
||||||
|
|
||||||
|
Dimension dimension = BoundingUtils.fitIntoBounds(new Dimension(object.getWidth(), object.getHeight()), new Dimension(maxWidth, maxHeight));
|
||||||
|
|
||||||
|
Gui.drawScaledCustomSizeModalRect(x, y, 0, 0, object.getWidth(), object.getHeight(), dimension.getWidth(), dimension.getHeight(), object.getWidth(), object.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
ResourceHelper.freeResource(previewResource);
|
||||||
|
super.finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package eu.crushedpixel.replaymod.events.handlers;
|
package eu.crushedpixel.replaymod.events.handlers;
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
|
import eu.crushedpixel.replaymod.assets.AssetRepository;
|
||||||
import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection;
|
import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection;
|
||||||
import eu.crushedpixel.replaymod.gui.GuiAssetAdder;
|
import eu.crushedpixel.replaymod.gui.GuiAssetManager;
|
||||||
import eu.crushedpixel.replaymod.gui.GuiKeyframeRepository;
|
import eu.crushedpixel.replaymod.gui.GuiKeyframeRepository;
|
||||||
import eu.crushedpixel.replaymod.gui.GuiMouseInput;
|
import eu.crushedpixel.replaymod.gui.GuiMouseInput;
|
||||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||||
@@ -202,8 +203,8 @@ public class KeyInputHandler {
|
|||||||
ReplayMod.replaySettings.setShowPathPreview(!ReplayMod.replaySettings.showPathPreview());
|
ReplayMod.replaySettings.setShowPathPreview(!ReplayMod.replaySettings.showPathPreview());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_ADD_ASSETS) && (kb.isPressed() || kb.getKeyCode() == keyCode)) {
|
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_ASSET_MANAGER) && (kb.isPressed() || kb.getKeyCode() == keyCode)) {
|
||||||
mc.displayGuiScreen(new GuiAssetAdder());
|
mc.displayGuiScreen(new GuiAssetManager(new AssetRepository()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
175
src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetManager.java
Normal file
175
src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetManager.java
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
package eu.crushedpixel.replaymod.gui;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.assets.AssetFileUtils;
|
||||||
|
import eu.crushedpixel.replaymod.assets.AssetRepository;
|
||||||
|
import eu.crushedpixel.replaymod.assets.ReplayAsset;
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.*;
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener;
|
||||||
|
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
|
||||||
|
import eu.crushedpixel.replaymod.utils.MouseUtils;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.util.Point;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class GuiAssetManager extends GuiScreen {
|
||||||
|
|
||||||
|
private String screenTitle;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
private GuiEntryList<ReplayAsset> assetGuiEntryList;
|
||||||
|
private GuiAdvancedButton removeButton;
|
||||||
|
private GuiAdvancedTextField assetNameInput;
|
||||||
|
private GuiFileChooser fileChooser, addButton;
|
||||||
|
|
||||||
|
private ComposedElement inputElements;
|
||||||
|
|
||||||
|
private ComposedElement composedElement;
|
||||||
|
|
||||||
|
private AssetRepository assetRepository;
|
||||||
|
|
||||||
|
private ReplayAsset currentAsset;
|
||||||
|
|
||||||
|
public GuiAssetManager(AssetRepository assetRepository) {
|
||||||
|
this.assetRepository = assetRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initGui() {
|
||||||
|
if(!initialized) {
|
||||||
|
screenTitle = I18n.format("replaymod.gui.assets.title");
|
||||||
|
|
||||||
|
assetGuiEntryList = new GuiEntryList<ReplayAsset>(fontRendererObj, 0, 0, 0, 0);
|
||||||
|
addButton = new GuiFileChooser(0, 0, 0, I18n.format("replaymod.gui.add"), null, AssetFileUtils.getAllAvailableExtensions()) {
|
||||||
|
@Override
|
||||||
|
protected void updateDisplayString() {
|
||||||
|
this.displayString = baseString;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addButton.addFileChooseListener(new FileChooseListener() {
|
||||||
|
@Override
|
||||||
|
public void onFileChosen(File file) {
|
||||||
|
try {
|
||||||
|
ReplayAsset newAsset = assetRepository.addAsset(file.getName(), new FileInputStream(file));
|
||||||
|
assetGuiEntryList.addElement(newAsset);
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
removeButton = new GuiAdvancedButton(0, 0, 0, I18n.format("replaymod.gui.remove")) {
|
||||||
|
@Override
|
||||||
|
public void performAction() {
|
||||||
|
assetRepository.removeAsset(currentAsset);
|
||||||
|
assetGuiEntryList.removeElement(assetGuiEntryList.getSelectionIndex());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assetNameInput = new GuiAdvancedTextField(fontRendererObj, 0, 0, 150, 20);
|
||||||
|
assetNameInput.hint = I18n.format("replaymod.gui.assets.namehint");
|
||||||
|
|
||||||
|
fileChooser = new GuiFileChooser(0, 0, 0, I18n.format("replaymod.gui.assets.changefile"), null, new String[0]) {
|
||||||
|
@Override
|
||||||
|
protected void updateDisplayString() {
|
||||||
|
this.displayString = baseString;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fileChooser.addFileChooseListener(new FileChooseListener() {
|
||||||
|
@Override
|
||||||
|
public void onFileChosen(File file) {
|
||||||
|
if(currentAsset == null) return;
|
||||||
|
try {
|
||||||
|
currentAsset.loadFromStream(new FileInputStream(file));
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fileChooser.width = 150;
|
||||||
|
|
||||||
|
inputElements = new ComposedElement(assetNameInput, fileChooser);
|
||||||
|
composedElement = new ComposedElement(assetGuiEntryList, addButton, removeButton, inputElements);
|
||||||
|
|
||||||
|
inputElements.setEnabled(false);
|
||||||
|
|
||||||
|
assetGuiEntryList.addSelectionListener(new SelectionListener() {
|
||||||
|
@Override
|
||||||
|
public void onSelectionChanged(int selectionIndex) {
|
||||||
|
currentAsset = assetGuiEntryList.getElement(selectionIndex);
|
||||||
|
inputElements.setEnabled(currentAsset != null);
|
||||||
|
|
||||||
|
assetNameInput.setText(currentAsset != null ? currentAsset.getDisplayString() : "");
|
||||||
|
fileChooser.setAllowedExtensions(currentAsset != null ? AssetFileUtils.fileExtensionsForAssetClass(currentAsset.getClass()) : new String[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int visibleEntries = (int)Math.floor(((double)this.height-(45+20+15+20))/14);
|
||||||
|
|
||||||
|
assetGuiEntryList.width = 150;
|
||||||
|
assetGuiEntryList.xPosition = width/2 - assetGuiEntryList.width - 5;
|
||||||
|
assetGuiEntryList.setVisibleElements(visibleEntries);
|
||||||
|
|
||||||
|
assetGuiEntryList.yPosition = assetNameInput.yPosition = 45;
|
||||||
|
|
||||||
|
addButton.xPosition = assetGuiEntryList.xPosition-1;
|
||||||
|
addButton.width = 77;
|
||||||
|
removeButton.width = 76;
|
||||||
|
removeButton.xPosition = addButton.xPosition+addButton.width;
|
||||||
|
|
||||||
|
addButton.yPosition = removeButton.yPosition = assetGuiEntryList.yPosition+assetGuiEntryList.height+2;
|
||||||
|
|
||||||
|
assetNameInput.xPosition = fileChooser.xPosition = this.width / 2 + 5;
|
||||||
|
fileChooser.yPosition = assetNameInput.yPosition + 20 + 5;
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
this.drawCenteredString(fontRendererObj, screenTitle, this.width / 2, 5, Color.WHITE.getRGB());
|
||||||
|
|
||||||
|
int leftBorder = 10;
|
||||||
|
int topBorder = 20;
|
||||||
|
|
||||||
|
drawGradientRect(leftBorder, topBorder, width - leftBorder, this.height - 10, -1072689136, -804253680);
|
||||||
|
|
||||||
|
composedElement.draw(mc, mouseX, mouseY);
|
||||||
|
|
||||||
|
if(currentAsset != null) {
|
||||||
|
int y = fileChooser.yPosition + 20 + 5;
|
||||||
|
int height = (addButton.yPosition+addButton.height)-y;
|
||||||
|
|
||||||
|
GL11.glColor4f(1, 1, 1, 1);
|
||||||
|
currentAsset.drawToScreen(fileChooser.xPosition, y, 150, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||||
|
composedElement.mouseClick(mc, mouseX, mouseY, mouseButton);
|
||||||
|
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||||
|
Point mousePos = MouseUtils.getMousePos();
|
||||||
|
composedElement.buttonPressed(mc, mousePos.getX(), mousePos.getY(), typedChar, keyCode);
|
||||||
|
super.keyTyped(typedChar, keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateScreen() {
|
||||||
|
composedElement.tick(mc);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package eu.crushedpixel.replaymod.gui.elements;
|
|||||||
|
|
||||||
import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener;
|
import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.client.Minecraft;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -20,8 +20,9 @@ public class GuiFileChooser extends GuiAdvancedButton {
|
|||||||
updateDisplayString();
|
updateDisplayString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String baseString;
|
protected String baseString;
|
||||||
|
|
||||||
|
@Setter
|
||||||
private String[] allowedExtensions = null;
|
private String[] allowedExtensions = null;
|
||||||
|
|
||||||
private List<FileChooseListener> listeners = new ArrayList<FileChooseListener>();
|
private List<FileChooseListener> listeners = new ArrayList<FileChooseListener>();
|
||||||
@@ -45,49 +46,44 @@ public class GuiFileChooser extends GuiAdvancedButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
|
public void performAction() {
|
||||||
boolean success = super.mousePressed(mc, mouseX, mouseY);
|
new Thread(new Runnable() {
|
||||||
if (success) {
|
@Override
|
||||||
new Thread(new Runnable() {
|
public void run() {
|
||||||
@Override
|
Frame frame = new Frame();
|
||||||
public void run() {
|
FileDialog fileDialog = new FileDialog(frame);
|
||||||
Frame frame = new Frame();
|
|
||||||
FileDialog fileDialog = new FileDialog(frame);
|
|
||||||
|
|
||||||
fileDialog.setFilenameFilter(new FilenameFilter() {
|
fileDialog.setFilenameFilter(new FilenameFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File dir, String name) {
|
public boolean accept(File dir, String name) {
|
||||||
if(allowedExtensions == null) return true;
|
if(allowedExtensions == null) return true;
|
||||||
for(String extension : allowedExtensions) {
|
for(String extension : allowedExtensions) {
|
||||||
String[] split = name.split("\\.");
|
String[] split = name.split("\\.");
|
||||||
String ext = split[split.length-1];
|
String ext = split[split.length-1];
|
||||||
if(extension.equalsIgnoreCase(ext)) return true;
|
if(extension.equalsIgnoreCase(ext)) return true;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
//frame.setVisible(true);
|
return false;
|
||||||
fileDialog.setVisible(true);
|
|
||||||
|
|
||||||
String filename = fileDialog.getFile();
|
|
||||||
String directory = fileDialog.getDirectory();
|
|
||||||
if(filename != null) {
|
|
||||||
selectedFile = new File(directory, filename);
|
|
||||||
|
|
||||||
updateDisplayString();
|
|
||||||
|
|
||||||
for(FileChooseListener listener : listeners) {
|
|
||||||
listener.onFileChosen(selectedFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frame.dispose();
|
//frame.setVisible(true);
|
||||||
|
fileDialog.setVisible(true);
|
||||||
|
|
||||||
|
String filename = fileDialog.getFile();
|
||||||
|
String directory = fileDialog.getDirectory();
|
||||||
|
if(filename != null) {
|
||||||
|
selectedFile = new File(directory, filename);
|
||||||
|
|
||||||
|
updateDisplayString();
|
||||||
|
|
||||||
|
for(FileChooseListener listener : listeners) {
|
||||||
|
listener.onFileChosen(selectedFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, "replaymod-file-chooser").start();
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
frame.dispose();
|
||||||
|
}
|
||||||
|
}, "replaymod-file-chooser").start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class KeybindRegistry {
|
|||||||
public static final String KEY_PLAY_PAUSE = "replaymod.input.playpause";
|
public static final String KEY_PLAY_PAUSE = "replaymod.input.playpause";
|
||||||
public static final String KEY_ADD_MARKER = "replaymod.input.marker";
|
public static final String KEY_ADD_MARKER = "replaymod.input.marker";
|
||||||
public static final String KEY_PATH_PREVIEW = "replaymod.input.pathpreview";
|
public static final String KEY_PATH_PREVIEW = "replaymod.input.pathpreview";
|
||||||
public static final String KEY_ADD_ASSETS = "replaymod.input.addassets";
|
public static final String KEY_ASSET_MANAGER = "replaymod.input.assetmanager";
|
||||||
private static Minecraft mc = Minecraft.getMinecraft();
|
private static Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
@@ -40,7 +40,7 @@ public class KeybindRegistry {
|
|||||||
bindings.add(new KeyBinding(KEY_ROLL_COUNTERCLOCKWISE, Keyboard.KEY_J, "replaymod.title"));
|
bindings.add(new KeyBinding(KEY_ROLL_COUNTERCLOCKWISE, Keyboard.KEY_J, "replaymod.title"));
|
||||||
bindings.add(new KeyBinding(KEY_PLAY_PAUSE, Keyboard.KEY_P, "replaymod.title"));
|
bindings.add(new KeyBinding(KEY_PLAY_PAUSE, Keyboard.KEY_P, "replaymod.title"));
|
||||||
bindings.add(new KeyBinding(KEY_PATH_PREVIEW, Keyboard.KEY_H, "replaymod.title"));
|
bindings.add(new KeyBinding(KEY_PATH_PREVIEW, Keyboard.KEY_H, "replaymod.title"));
|
||||||
bindings.add(new KeyBinding(KEY_ADD_ASSETS, Keyboard.KEY_G, "replaymod.title"));
|
bindings.add(new KeyBinding(KEY_ASSET_MANAGER, Keyboard.KEY_G, "replaymod.title"));
|
||||||
|
|
||||||
mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]);
|
mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]);
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,14 @@ public class ResourceHelper {
|
|||||||
return openResources.contains(loc);
|
return openResources.contains(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void freeResource(ResourceLocation loc) {
|
public static void freeResource(final ResourceLocation loc) {
|
||||||
Minecraft.getMinecraft().getTextureManager().deleteTexture(loc);
|
Minecraft.getMinecraft().addScheduledTask(new Runnable() {
|
||||||
openResources.remove(loc);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Minecraft.getMinecraft().getTextureManager().deleteTexture(loc);
|
||||||
|
openResources.remove(loc);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void freeAllResources() {
|
public static void freeAllResources() {
|
||||||
|
|||||||
@@ -562,6 +562,7 @@ public class ReplayHandler {
|
|||||||
try {
|
try {
|
||||||
ReplayMod.overlay.resetUI(true);
|
ReplayMod.overlay.resetUI(true);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
// TODO: Fix exceptionsudo
|
// TODO: Fix exceptionsudo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,6 +585,7 @@ public class ReplayHandler {
|
|||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
|
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
|
||||||
networkManager.setNetHandler(pc);
|
networkManager.setNetHandler(pc);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package eu.crushedpixel.replaymod.utils;
|
||||||
|
|
||||||
|
import org.lwjgl.util.Dimension;
|
||||||
|
|
||||||
|
public class BoundingUtils {
|
||||||
|
|
||||||
|
public static Dimension fitIntoBounds(Dimension toFit, Dimension bounds) {
|
||||||
|
int width = toFit.getWidth();
|
||||||
|
int height = toFit.getHeight();
|
||||||
|
|
||||||
|
float w = (float)width/bounds.getWidth();
|
||||||
|
float h = (float)height/bounds.getHeight();
|
||||||
|
|
||||||
|
if(w > h) {
|
||||||
|
height = (int)(height/w);
|
||||||
|
width = (int)(width/w);
|
||||||
|
} else {
|
||||||
|
height = (int)(height/h);
|
||||||
|
width = (int)(width/h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Dimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.google.common.base.Supplier;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import eu.crushedpixel.replaymod.assets.AssetRepository;
|
||||||
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
import eu.crushedpixel.replaymod.holders.KeyframeSet;
|
||||||
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
import eu.crushedpixel.replaymod.holders.MarkerKeyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
import eu.crushedpixel.replaymod.holders.PlayerVisibility;
|
||||||
@@ -14,6 +15,7 @@ import org.apache.commons.compress.archivers.zip.ZipFile;
|
|||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ public class ReplayFile extends ZipFile {
|
|||||||
public static final String ENTRY_VISIBILITY_OLD = "visibility";
|
public static final String ENTRY_VISIBILITY_OLD = "visibility";
|
||||||
public static final String ENTRY_VISIBILITY = "visibility" + JSON_FILE_EXTENSION;
|
public static final String ENTRY_VISIBILITY = "visibility" + JSON_FILE_EXTENSION;
|
||||||
public static final String ENTRY_MARKERS = "markers" + JSON_FILE_EXTENSION;
|
public static final String ENTRY_MARKERS = "markers" + JSON_FILE_EXTENSION;
|
||||||
|
public static final String ENTRY_ASSET_FOLDER = "asset/";
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
|
|
||||||
@@ -220,4 +223,32 @@ public class ReplayFile extends ZipFile {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Supplier<AssetRepository> assetRepository() {
|
||||||
|
return new Supplier<AssetRepository>() {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public AssetRepository get() {
|
||||||
|
AssetRepository assetRepository = new AssetRepository();
|
||||||
|
|
||||||
|
Enumeration<ZipArchiveEntry> entries = getEntries();
|
||||||
|
|
||||||
|
while(entries.hasMoreElements()) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ZipArchiveEntry entry = entries.nextElement();
|
||||||
|
|
||||||
|
if(entry.getName().startsWith(ENTRY_ASSET_FOLDER)) {
|
||||||
|
String name = entry.getName().substring(ENTRY_ASSET_FOLDER.length());
|
||||||
|
assetRepository.addAsset(name, getInputStream(entry));
|
||||||
|
}
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetRepository;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package eu.crushedpixel.replaymod.video.frame;
|
package eu.crushedpixel.replaymod.video.frame;
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||||
|
import eu.crushedpixel.replaymod.utils.BoundingUtils;
|
||||||
import eu.crushedpixel.replaymod.video.entity.CustomEntityRenderer;
|
import eu.crushedpixel.replaymod.video.entity.CustomEntityRenderer;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
@@ -9,6 +10,7 @@ import net.minecraft.client.renderer.texture.TextureUtil;
|
|||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.Timer;
|
import net.minecraft.util.Timer;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.util.Dimension;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.DataBufferInt;
|
import java.awt.image.DataBufferInt;
|
||||||
@@ -120,18 +122,12 @@ public abstract class FrameRenderer {
|
|||||||
* @param height Height of the box
|
* @param height Height of the box
|
||||||
*/
|
*/
|
||||||
public void renderPreview(int x, int y, int width, int height) {
|
public void renderPreview(int x, int y, int width, int height) {
|
||||||
int actualWidth = width;
|
Dimension dimension = BoundingUtils.fitIntoBounds(new Dimension(x, y), new Dimension(width, height));
|
||||||
int actualHeight = height;
|
|
||||||
if (width / height > getVideoWidth() / getVideoHeight()) {
|
|
||||||
actualWidth = height * getVideoWidth() / getVideoHeight();
|
|
||||||
} else {
|
|
||||||
actualHeight = width * getVideoHeight() / getVideoWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
x += (width - actualWidth) / 2;
|
x += (width - dimension.getWidth()) / 2;
|
||||||
y += (height - actualHeight) / 2;
|
y += (height - dimension.getHeight()) / 2;
|
||||||
|
|
||||||
drawPreviewTexture(x, y, actualWidth, actualHeight);
|
drawPreviewTexture(x, y, dimension.getWidth(), dimension.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderNoPreview(int x, int y, int width, int height) {
|
public static void renderNoPreview(int x, int y, int width, int height) {
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ replaymod.input.resettilt=Reset Camera Tilt
|
|||||||
replaymod.input.playpause=Play/Pause Replay
|
replaymod.input.playpause=Play/Pause Replay
|
||||||
replaymod.input.marker=Add Event Marker
|
replaymod.input.marker=Add Event Marker
|
||||||
replaymod.input.pathpreview=Toggle Path Preview
|
replaymod.input.pathpreview=Toggle Path Preview
|
||||||
replaymod.input.addassets=Add Assets
|
replaymod.input.assetmanager=Open Asset Manager
|
||||||
|
|
||||||
#Keyframe Presets GUI
|
#Keyframe Presets GUI
|
||||||
replaymod.gui.keyframerepository.title=Keyframe Repository
|
replaymod.gui.keyframerepository.title=Keyframe Repository
|
||||||
@@ -357,10 +357,10 @@ replaymod.gui.ingame.unnamedmarker=Unnamed Event Marker
|
|||||||
replaymod.gui.clearcallback.title=Clear all Keyframes?
|
replaymod.gui.clearcallback.title=Clear all Keyframes?
|
||||||
replaymod.gui.clearcallback.message=This Callback can be disabled in the Replay Settings.
|
replaymod.gui.clearcallback.message=This Callback can be disabled in the Replay Settings.
|
||||||
|
|
||||||
#Asset Adder Gui
|
#Asset Manager Gui
|
||||||
replaymod.gui.assets.title=Asset Manager
|
replaymod.gui.assets.title=Asset Manager
|
||||||
replaymod.gui.assets.filechooser=Image File
|
replaymod.gui.assets.filechooser=Asset File
|
||||||
replaymod.gui.assets.defaultname=New Asset
|
replaymod.gui.assets.defaultname=New Asset
|
||||||
replaymod.gui.assets.emptylist=No Assets available
|
replaymod.gui.assets.emptylist=No Assets available
|
||||||
replaymod.gui.assets.namehint=Asset Name
|
replaymod.gui.assets.namehint=Asset Name
|
||||||
replaymod.gui.assets.backvisible=Visible from behind
|
replaymod.gui.assets.changefile=Change Asset File
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Reference in New Issue
Block a user