diff --git a/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java b/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java index b14795db..f54f9dc1 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/handlers/KeyInputHandler.java @@ -2,6 +2,7 @@ package eu.crushedpixel.replaymod.events.handlers; import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection; +import eu.crushedpixel.replaymod.gui.GuiAssetAdder; import eu.crushedpixel.replaymod.gui.GuiKeyframeRepository; import eu.crushedpixel.replaymod.gui.GuiMouseInput; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; @@ -199,5 +200,9 @@ public class KeyInputHandler { if(kb.getKeyDescription().equals(KeybindRegistry.KEY_PATH_PREVIEW) && (kb.isPressed() || kb.getKeyCode() == keyCode)) { ReplayMod.replaySettings.setShowPathPreview(!ReplayMod.replaySettings.showPathPreview()); } + + if(kb.getKeyDescription().equals(KeybindRegistry.KEY_ADD_ASSETS) && (kb.isPressed() || kb.getKeyCode() == keyCode)) { + mc.displayGuiScreen(new GuiAssetAdder()); + } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetAdder.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetAdder.java new file mode 100644 index 00000000..d3976095 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiAssetAdder.java @@ -0,0 +1,101 @@ +package eu.crushedpixel.replaymod.gui; + +import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.gui.elements.GuiAdvancedTextField; +import eu.crushedpixel.replaymod.gui.elements.GuiEntryList; +import eu.crushedpixel.replaymod.gui.elements.GuiFileChooser; +import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput; +import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener; +import eu.crushedpixel.replaymod.holders.CustomImageObject; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.config.GuiCheckBox; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.io.File; + +public class GuiAssetAdder extends GuiScreen { + + private String screenTitle; + + private boolean initialized = false; + + private GuiEntryList objectList; + private GuiButton removeButton; + private GuiFileChooser addButton; + private GuiFileChooser guiFileChooser; + + private GuiAdvancedTextField nameInput; + + private GuiNumberInput xInput, yInput, zInput, yawInput, pitchInput, rollInput, scaleInput; + private GuiCheckBox backVisibleCheckBox; + + public GuiAssetAdder() { + ReplayMod.replaySender.setReplaySpeed(0); + } + + @Override + public void initGui() { + if(!initialized) { + screenTitle = I18n.format("replaymod.gui.assets.title"); + + objectList = new GuiEntryList(0, fontRendererObj, 0, 0, 0, 0); + removeButton = new GuiButton(GuiConstants.ASSET_ADDER_REMOVE_BUTTON, 0, 0, I18n.format("replaymod.gui.remove")); + + addButton = new GuiFileChooser(1, 0, 0, I18n.format("replaymod.gui.add"), null, ImageIO.getReaderFileSuffixes()) { + @Override protected void updateDisplayString() {} + }; + + addButton.registerListener(new FileChooseListener() { + @Override + public void onFileChosen(File file) { + + } + }); + + guiFileChooser = new GuiFileChooser(2, 0, 0, I18n.format("replaymod.gui.assets.filechooser")+": ", null, ImageIO.getReaderFileSuffixes()); + } + + int h = (int)Math.floor(((double)this.height-(45+20+15+20))/14); + + objectList.width = guiFileChooser.width = 150; + objectList.xPosition = width/2 - objectList.width - 5; + objectList.setVisibleElements(h); + objectList.yPosition = 45; + + addButton.width = removeButton.width = 75; + addButton.xPosition = objectList.xPosition; + removeButton.xPosition = addButton.xPosition+addButton.width; + addButton.yPosition = removeButton.yPosition = objectList.yPosition + objectList.height + 2; + + guiFileChooser.xPosition = this.width/2 + 5; + guiFileChooser.yPosition = 45; + + buttonList.add(removeButton); + buttonList.add(addButton); + buttonList.add(guiFileChooser); + + 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); + + objectList.drawTextBox(); + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void updateScreen() { + super.updateScreen(); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java index 46f9a733..626a0db0 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java @@ -110,4 +110,6 @@ public class GuiConstants { public static final int REPLAY_EDITING_CANCEL_BUTTON = 1234; public static final int REPLAY_DOWNLOADING_CANCEL_BUTTON = 2345; + + public static final int ASSET_ADDER_REMOVE_BUTTON = 10; } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiKeyframeRepository.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiKeyframeRepository.java index ea4be129..f44f3ed2 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiKeyframeRepository.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiKeyframeRepository.java @@ -25,7 +25,7 @@ public class GuiKeyframeRepository extends GuiScreen implements GuiReplayOverlay private boolean initialized = false; - private final String screenTitle = I18n.format("replaymod.gui.keyframerepository.title"); + private String screenTitle; private final Minecraft mc = Minecraft.getMinecraft(); private GuiEntryList keyframeSetList; @@ -52,6 +52,8 @@ public class GuiKeyframeRepository extends GuiScreen implements GuiReplayOverlay int h = (int)Math.floor(((double)this.height-(45+20+15))/14); if(!initialized) { + screenTitle = I18n.format("replaymod.gui.keyframerepository.title"); + keyframeSetList = new GuiEntryList(GuiConstants.KEYFRAME_REPOSITORY_LIST, mc.fontRendererObj, 0, 45, 0, h); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiAdvancedTextField.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiAdvancedTextField.java index 3fff1869..cbf7e3ef 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiAdvancedTextField.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiAdvancedTextField.java @@ -41,7 +41,7 @@ public class GuiAdvancedTextField extends GuiTextField implements GuiElement { super.setDisabledTextColour(hintTextColor); text = hint; - drawTextBox(); + super.drawTextBox(); text = ""; super.setDisabledTextColour(disabledTextColor); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiEntryList.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiEntryList.java index 874592ed..806a6a41 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiEntryList.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiEntryList.java @@ -1,6 +1,7 @@ package eu.crushedpixel.replaymod.gui.elements; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; +import eu.crushedpixel.replaymod.holders.GuiEntryListEntry; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiTextField; @@ -10,7 +11,7 @@ import java.awt.*; import java.util.ArrayList; import java.util.List; -public class GuiEntryList extends GuiTextField { +public class GuiEntryList extends GuiTextField { public final static int elementHeight = 14; private int selectionIndex = -1; @@ -61,7 +62,7 @@ public class GuiEntryList extends GuiTextField { drawRect(xPosition, yPosition + (i + 1 - upperIndex) * elementHeight - 1, xPosition + width, yPosition + (i + 1 - upperIndex) * elementHeight, -6250336); - drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).toString(), width - 4), + drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).getDisplayString(), width - 4), xPosition + 2, yPosition + (i - upperIndex) * elementHeight + 3, Color.WHITE.getRGB()); } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java new file mode 100644 index 00000000..22594575 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiFileChooser.java @@ -0,0 +1,90 @@ +package eu.crushedpixel.replaymod.gui.elements; + +import eu.crushedpixel.replaymod.gui.elements.listeners.FileChooseListener; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; + +import java.awt.*; +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +public class GuiFileChooser extends GuiButton { + + @Getter + @Setter + private File selectedFile; + + private String baseString; + + private String[] allowedExtensions = null; + + private List listeners = new ArrayList(); + + public GuiFileChooser(int buttonId, int x, int y, String buttonText, File selectedFile, String[] allowedExtensions) { + super(buttonId, x, y, buttonText); + this.selectedFile = selectedFile; + + this.baseString = buttonText; + updateDisplayString(); + + this.allowedExtensions = allowedExtensions; + } + + public void registerListener(FileChooseListener listener) { + this.listeners.add(listener); + } + + protected void updateDisplayString() { + this.displayString = baseString + (selectedFile == null ? "-" : selectedFile.getName()); + } + + @Override + public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { + boolean success = super.mousePressed(mc, mouseX, mouseY); + if (success) { + new Thread(new Runnable() { + @Override + public void run() { + Frame frame = new Frame(); + FileDialog fileDialog = new FileDialog(frame); + + fileDialog.setFilenameFilter(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if(allowedExtensions == null) return true; + for(String extension : allowedExtensions) { + String[] split = name.split("\\."); + String ext = split[split.length-1]; + if(extension.equalsIgnoreCase(ext)) return true; + } + + return false; + } + }); + + //frame.setVisible(true); + fileDialog.setVisible(true); + + String filename = fileDialog.getFile(); + if(filename != null) { + selectedFile = new File(filename); + + updateDisplayString(); + + for(FileChooseListener listener : listeners) { + listener.onFileChosen(selectedFile); + } + } + + frame.dispose(); + } + }, "replaymod-file-chooser").start(); + } + return success; + } + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/listeners/FileChooseListener.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/listeners/FileChooseListener.java new file mode 100644 index 00000000..a75ad6de --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/listeners/FileChooseListener.java @@ -0,0 +1,9 @@ +package eu.crushedpixel.replaymod.gui.elements.listeners; + +import java.io.File; + +public interface FileChooseListener { + + void onFileChosen(File file); + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiConnectPart.java b/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiConnectPart.java index d26205ed..1cbdd726 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiConnectPart.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiConnectPart.java @@ -5,6 +5,7 @@ import eu.crushedpixel.replaymod.gui.elements.GuiArrowButton; import eu.crushedpixel.replaymod.gui.elements.GuiDropdown; import eu.crushedpixel.replaymod.gui.elements.GuiEntryList; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; +import eu.crushedpixel.replaymod.holders.GuiEntryListStringEntry; import eu.crushedpixel.replaymod.studio.StudioImplementation; import eu.crushedpixel.replaymod.utils.ReplayFileIO; import net.minecraft.client.Minecraft; @@ -26,14 +27,14 @@ public class GuiConnectPart extends GuiStudioPart { private boolean initialized = false; - private GuiEntryList concatList; - private GuiDropdown replayDropdown; + private GuiEntryList concatList; + private GuiDropdown replayDropdown; private GuiButton removeButton, addButton; private GuiArrowButton upButton, downButton; private List replayFiles; - private List filesToConcat; + private List filesToConcat; private Thread filterThread; private File outputFile; @@ -53,14 +54,14 @@ public class GuiConnectPart extends GuiStudioPart { try { List inputFiles = new ArrayList(); OUTER: - for (String fileName : filesToConcat) { + for (GuiEntryListStringEntry fileName : filesToConcat) { for (File file : replayFiles) { if (fileName.equals(FilenameUtils.getBaseName(file.getAbsolutePath()))) { inputFiles.add(file); continue OUTER; } } - throw new RuntimeException(fileName); + throw new RuntimeException(fileName.getDisplayString()); } StudioImplementation.connectReplayFiles(inputFiles, outputFile, GuiConnectPart.this); } catch (Exception e) { @@ -94,15 +95,15 @@ public class GuiConnectPart extends GuiStudioPart { @Override public void initGui() { if(!initialized) { - concatList = new GuiEntryList(1, fontRendererObj, 30, yPos, 150, 0); - filesToConcat = new ArrayList(); + concatList = new GuiEntryList(1, fontRendererObj, 30, yPos, 150, 0); + filesToConcat = new ArrayList(); String selectedName = FilenameUtils.getBaseName(GuiReplayEditor.instance.getSelectedFile().getAbsolutePath()); - filesToConcat.add(selectedName); + filesToConcat.add(new GuiEntryListStringEntry(selectedName)); concatList.setElements(filesToConcat); concatList.setSelectionIndex(0); - replayDropdown = new GuiDropdown(1, fontRendererObj, 250, yPos + 5, 0, 4); + replayDropdown = new GuiDropdown(1, fontRendererObj, 250, yPos + 5, 0, 4); replayDropdown.clearElements(); replayFiles = ReplayFileIO.getAllReplayFiles(); @@ -110,7 +111,7 @@ public class GuiConnectPart extends GuiStudioPart { int i = 0; for(File file : replayFiles) { String name = FilenameUtils.getBaseName(file.getAbsolutePath()); - replayDropdown.addElement(name); + replayDropdown.addElement(new GuiEntryListStringEntry(name)); if(name.equals(selectedName)) { index = i; } @@ -135,10 +136,10 @@ public class GuiConnectPart extends GuiStudioPart { concatList.addSelectionListener(new SelectionListener() { @Override public void onSelectionChanged(int selectionIndex) { - String selName = concatList.getElement(selectionIndex); + String selName = concatList.getElement(selectionIndex).getDisplayString(); int i = 0; for(Object s : replayDropdown.getAllElements()) { - String str = (String) s; + String str = ((GuiEntryListStringEntry)s).getDisplayString(); if(str.equals(selName)) { replayDropdown.setSelectionIndex(i); break; @@ -217,7 +218,7 @@ public class GuiConnectPart extends GuiStudioPart { } if(button.id == GuiConstants.REPLAY_EDITOR_ADD_BUTTON) { - filesToConcat.add(FilenameUtils.getBaseName(replayFiles.get(0).getAbsolutePath())); + filesToConcat.add(new GuiEntryListStringEntry(FilenameUtils.getBaseName(replayFiles.get(0).getAbsolutePath()))); concatList.setElements(filesToConcat); concatList.setSelectionIndex(filesToConcat.size() - 1); } else if(button.id == GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON) { diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/CustomImageObject.java b/src/main/java/eu/crushedpixel/replaymod/holders/CustomImageObject.java index 057a1a34..f55115e0 100644 --- a/src/main/java/eu/crushedpixel/replaymod/holders/CustomImageObject.java +++ b/src/main/java/eu/crushedpixel/replaymod/holders/CustomImageObject.java @@ -2,6 +2,7 @@ package eu.crushedpixel.replaymod.holders; import eu.crushedpixel.replaymod.registry.ResourceHelper; import lombok.Getter; +import lombok.Setter; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.util.ResourceLocation; @@ -11,9 +12,9 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -public class CustomImageObject { +public class CustomImageObject implements GuiEntryListEntry { - public CustomImageObject(Position position, String name, File imageSource) throws IOException { + public CustomImageObject(Position position, String name, File imageSource, boolean backVisible) throws IOException { BufferedImage bufferedImage = ImageIO.read(imageSource); this.textureWidth = bufferedImage.getWidth(); @@ -35,10 +36,13 @@ public class CustomImageObject { this.resourceLocation = new ResourceLocation("customImages/"+imageSource.getAbsolutePath()); this.dynamicTexture = new DynamicTexture(bufferedImage); + + this.backVisible = backVisible; } - @Getter private ExtendedPosition position; - @Getter private String name; + @Getter @Setter private ExtendedPosition position; + @Getter @Setter private String name; + @Getter @Setter private boolean backVisible; private ResourceLocation resourceLocation; private DynamicTexture dynamicTexture; @@ -54,4 +58,9 @@ public class CustomImageObject { return resourceLocation; } + + @Override + public String getDisplayString() { + return name; + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListEntry.java b/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListEntry.java new file mode 100644 index 00000000..7b015d6f --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListEntry.java @@ -0,0 +1,8 @@ +package eu.crushedpixel.replaymod.holders; + + +public interface GuiEntryListEntry { + + public String getDisplayString(); + +} diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListStringEntry.java b/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListStringEntry.java new file mode 100644 index 00000000..08359e04 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/holders/GuiEntryListStringEntry.java @@ -0,0 +1,19 @@ +package eu.crushedpixel.replaymod.holders; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class GuiEntryListStringEntry implements GuiEntryListEntry { + + private String displayName; + + @Override + public String getDisplayString() { + return displayName; + } + + @Override + public String toString() { + return displayName; + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/KeyframeSet.java b/src/main/java/eu/crushedpixel/replaymod/holders/KeyframeSet.java index 900f9810..65dd8911 100644 --- a/src/main/java/eu/crushedpixel/replaymod/holders/KeyframeSet.java +++ b/src/main/java/eu/crushedpixel/replaymod/holders/KeyframeSet.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class KeyframeSet { +public class KeyframeSet implements GuiEntryListEntry { private String name; private PositionKeyframe[] positionKeyframes; private TimeKeyframe[] timeKeyframes; @@ -70,7 +70,7 @@ public class KeyframeSet { } @Override - public String toString() { + public String getDisplayString() { return name; } diff --git a/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java b/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java index 1df106e6..ed1c6071 100755 --- a/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java +++ b/src/main/java/eu/crushedpixel/replaymod/registry/KeybindRegistry.java @@ -22,6 +22,7 @@ public class KeybindRegistry { 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_PATH_PREVIEW = "replaymod.input.pathpreview"; + public static final String KEY_ADD_ASSETS = "replaymod.input.addassets"; private static Minecraft mc = Minecraft.getMinecraft(); public static void initialize() { @@ -39,6 +40,7 @@ public class KeybindRegistry { 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_PATH_PREVIEW, Keyboard.KEY_H, "replaymod.title")); + bindings.add(new KeyBinding(KEY_ADD_ASSETS, Keyboard.KEY_G, "replaymod.title")); mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]); diff --git a/src/main/java/eu/crushedpixel/replaymod/renderer/CustomObjectRenderer.java b/src/main/java/eu/crushedpixel/replaymod/renderer/CustomObjectRenderer.java index 76944372..e2a59a66 100644 --- a/src/main/java/eu/crushedpixel/replaymod/renderer/CustomObjectRenderer.java +++ b/src/main/java/eu/crushedpixel/replaymod/renderer/CustomObjectRenderer.java @@ -38,7 +38,6 @@ public class CustomObjectRenderer { GlStateManager.disableTexture2D(); - //do stuff here for(CustomImageObject object : ReplayHandler.getCustomImageObjects()) { drawCustomImageObject(doubleX, doubleY, doubleZ, object); } diff --git a/src/main/resources/assets/replaymod/lang/en_US.lang b/src/main/resources/assets/replaymod/lang/en_US.lang index 38061197..dbc6585d 100644 --- a/src/main/resources/assets/replaymod/lang/en_US.lang +++ b/src/main/resources/assets/replaymod/lang/en_US.lang @@ -257,6 +257,7 @@ replaymod.input.resettilt=Reset Camera Tilt replaymod.input.playpause=Play/Pause Replay replaymod.input.marker=Add Event Marker replaymod.input.pathpreview=Toggle Path Preview +replaymod.input.addassets=Add Assets #Keyframe Presets GUI replaymod.gui.keyframerepository.title=Keyframe Repository @@ -354,4 +355,8 @@ replaymod.gui.ingame.unnamedmarker=Unnamed Event Marker #Clear Keyframe Callback replaymod.gui.clearcallback.title=Clear all Keyframes? -replaymod.gui.clearcallback.message=This Callback can be disabled in the Replay Settings. \ No newline at end of file +replaymod.gui.clearcallback.message=This Callback can be disabled in the Replay Settings. + +#Asset Adder Gui +replaymod.gui.assets.title=Asset Manager +replaymod.gui.assets.filechooser=Image File \ No newline at end of file