diff --git a/src/MoF/MapViewer.java b/src/MoF/MapViewer.java index 93c8fd5a..43b4eae5 100644 --- a/src/MoF/MapViewer.java +++ b/src/MoF/MapViewer.java @@ -13,6 +13,7 @@ import amidst.map.MapObjectPlayer; import amidst.map.layers.BiomeLayer; import amidst.map.layers.GridLayer; +import amidst.map.layers.MineshaftLayer; import amidst.map.layers.NetherFortressLayer; import amidst.map.layers.PlayerLayer; import amidst.map.layers.SlimeLayer; @@ -62,7 +63,7 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi // TODO: This should likely be moved somewhere else. private static FragmentManager fragmentManager; private static PlayerLayer playerLayer; - + private Widget mouseOwner; private static BufferedImage dropShadowBottomLeft = ResourceLoader.getImage("dropshadow/inner_bottom_left.png"), @@ -88,39 +89,40 @@ public class MapViewer extends JComponent implements MouseListener, MouseWheelLi new TempleLayer(), new SpawnLayer(), new NetherFortressLayer(), + new MineshaftLayer(), playerLayer = new PlayerLayer() }); } - + private Project proj; - + private JPopupMenu menu = new JPopupMenu(); public int strongholdCount, villageCount; - + private Map worldMap; private MapObject selectedObject = null; private Point lastMouse; public Point lastRightClick = null; private Point2D.Double panSpeed; - + private static int zoomLevel = 0, zoomTicksRemaining = 0; private static double targetZoom = 0.25f, curZoom = 0.25f; private Point zoomMouse = new Point(); - + private Font textFont = new Font("arial", Font.BOLD, 15); - + private FontMetrics textMetrics; - + private ArrayList widgets = new ArrayList(); private long lastTime; - + public void dispose() { Log.debug("Disposing of map viewer."); worldMap.dispose(); menu.removeAll(); proj = null; } - + MapViewer(Project proj) { panSpeed = new Point2D.Double(); this.proj = proj; @@ -130,10 +132,10 @@ public void dispose() { menu.add(new PlayerMenuItem(this, player, playerLayer)); } } - + worldMap = new Map(fragmentManager); //TODO: implement more layers worldMap.setZoom(curZoom); - + widgets.add(new FpsWidget(this).setAnchorPoint(CornerAnchorPoint.BOTTOM_LEFT)); widgets.add(new SeedWidget(this).setAnchorPoint(CornerAnchorPoint.TOP_LEFT)); widgets.add(new DebugWidget(this).setAnchorPoint(CornerAnchorPoint.BOTTOM_RIGHT)); @@ -143,7 +145,7 @@ public void dispose() { widgets.add(BiomeWidget.get(this).setAnchorPoint(CornerAnchorPoint.NONE)); addMouseListener(this); addMouseWheelListener(this); - + setFocusable(true); lastTime = System.currentTimeMillis(); @@ -151,25 +153,25 @@ public void dispose() { } @Override - public void paint(Graphics g) { + public void paint(Graphics g) { Graphics2D g2d = (Graphics2D)g.create(); - + long currentTime = System.currentTimeMillis(); float time = Math.min(Math.max(0, currentTime - lastTime), 100) / 1000.0f; lastTime = currentTime; - + g2d.setColor(Color.black); g2d.fillRect(0, 0, this.getWidth(), this.getHeight()); if (zoomTicksRemaining-- > 0) { double lastZoom = curZoom; curZoom = (targetZoom + curZoom) * 0.5; - + Point2D.Double targetZoom = worldMap.getScaled(lastZoom, curZoom, zoomMouse); worldMap.moveBy(targetZoom); worldMap.setZoom(curZoom); } - + Point curMouse = getMousePosition(); if (lastMouse != null) { if (curMouse != null) { @@ -178,7 +180,7 @@ public void paint(Graphics g) { // TODO : Scale with time panSpeed.setLocation(difX * 0.2, difY * 0.2); } - + lastMouse.translate((int) panSpeed.x, (int)panSpeed.y); } @@ -190,17 +192,17 @@ public void paint(Graphics g) { panSpeed.x *= 0.f; panSpeed.y *= 0.f; } - + worldMap.width = getWidth(); worldMap.height = getHeight(); - + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); worldMap.draw((Graphics2D)g2d.create(), time); g2d.drawImage(dropShadowTopLeft, 0, 0, null); g2d.drawImage(dropShadowTopRight, getWidth() - 10, 0, null); g2d.drawImage(dropShadowBottomLeft, 0, getHeight() - 10, null); g2d.drawImage(dropShadowBottomRight, getWidth() - 10, getHeight() - 10, null); - + g2d.drawImage(dropShadowTop, 10, 0, getWidth() - 20, 10, null); g2d.drawImage(dropShadowBottom, 10, getHeight() - 10, getWidth() - 20, 10, null); g2d.drawImage(dropShadowLeft, 0, 10, 10, getHeight() - 20, null); @@ -214,12 +216,12 @@ public void paint(Graphics g) { } } } - - + + public void centerAt(long x, long y) { worldMap.centerOn(x, y); } - + public void adjustZoom(Point position, int notches) { zoomMouse = position; if (notches > 0) { @@ -236,7 +238,7 @@ public void adjustZoom(Point position, int notches) { } } } - + @Override public void mouseWheelMoved(MouseWheelEvent e) { int notches = e.getWheelRotation(); @@ -268,7 +270,7 @@ public void mouseClicked(MouseEvent e) { } } MapObject object = worldMap.getObjectAt(mouse, 50.0); - + if (selectedObject != null) selectedObject.localScale = 1.0; @@ -277,8 +279,8 @@ public void mouseClicked(MouseEvent e) { selectedObject = object; } } - - + + @Override public void mouseEntered(MouseEvent arg0) { } @@ -304,7 +306,7 @@ public void mousePressed(MouseEvent e) { } lastMouse = mouse; } - + @Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger() && MinecraftUtil.getVersion().saveEnabled()) { @@ -321,38 +323,38 @@ public void mouseReleased(MouseEvent e) { } } } - + public MapObject getSelectedObject() { return selectedObject; } - - + + public void movePlayer(String name, ActionEvent e) { //PixelInfo p = getCursorInformation(new Point(tempX, tempY)); - + //proj.movePlayer(name, p); } - + public void saveToFile(File f) { BufferedImage image = new BufferedImage(worldMap.width, worldMap.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); - + worldMap.draw(g2d, 0); for (Widget widget : widgets) if (widget.isVisible()) widget.draw(g2d, 0); - + try { ImageIO.write(image, "png", f); } catch (IOException e) { e.printStackTrace(); } - + g2d.dispose(); image.flush(); } - + @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub @@ -368,13 +370,13 @@ else if (e.getKeyCode() == KeyEvent.VK_MINUS) @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub - + } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub - + } public FragmentManager getFragmentManager() { @@ -384,7 +386,7 @@ public FragmentManager getFragmentManager() { public Map getMap() { return worldMap; } - + public FontMetrics getFontMetrics() { return textMetrics; } diff --git a/src/amidst/Options.java b/src/amidst/Options.java index 632b57bb..e2597b3c 100644 --- a/src/amidst/Options.java +++ b/src/amidst/Options.java @@ -15,54 +15,56 @@ */ public enum Options { instance; - + //per-run preferences. TODO: store elsewhere? public long seed; public String seedText; - + //permanent preferences public final FilePrefModel jar; public final BooleanPrefModel showSlimeChunks; public final BooleanPrefModel showGrid; public final BooleanPrefModel showNetherFortresses; + public final BooleanPrefModel showMineshafts; public final BooleanPrefModel showTemples, showPlayers, showStrongholds, showVillages, showSpawn; public final BooleanPrefModel mapFlicking, mapFading, showFPS, showDebug; public final BooleanPrefModel updateToUnstable; public final BooleanPrefModel maxZoom; - + public final StringPreference lastProfile; - + public final SelectPrefModel worldType; public BiomeColorProfile biomeColorProfile; private Preferences preferences; - + //CLI @Option (name="-history", usage="Sets the path to seed history file.", metaVar="") public String historyPath; - + @Option (name="-log", usage="Sets the path to logging file.", metaVar="") public String logPath; - + @Option (name="-mcpath", usage="Sets the path to the .minecraft directory.", metaVar="") public String minecraftPath; - + @Option (name="-mcjar", usage="Sets the path to the minecraft .jar", metaVar="") public String minecraftJar; - + @Option (name="-mcjson", usage="Sets the path to the minecraft .json", metaVar="") public String minecraftJson; - + private Options() { seed = 0L; seedText = null; - - + + Preferences pref = Preferences.userNodeForPackage(Amidst.class); preferences = pref; jar = new FilePrefModel( pref, "jar", new File(Util.minecraftDirectory, "bin/minecraft.jar")); showSlimeChunks = new BooleanPrefModel(pref, "slimeChunks", false); showGrid = new BooleanPrefModel(pref, "grid", false); showNetherFortresses = new BooleanPrefModel(pref, "netherFortressIcons", false); + showMineshafts = new BooleanPrefModel(pref, "mineshaftIcons", false); mapFlicking = new BooleanPrefModel(pref, "mapFlicking", true); mapFading = new BooleanPrefModel(pref, "mapFading", true); maxZoom = new BooleanPrefModel(pref, "maxZoom", true); @@ -78,18 +80,18 @@ private Options() { biomeColorProfile = new BiomeColorProfile(); worldType = new SelectPrefModel( pref, "worldType", "Prompt each time", new String[] { "Prompt each time", "Default", "Flat", "Large Biomes", "Amplified" }); biomeColorProfile.fillColorArray(); - - + + } - + public Preferences getPreferences() { return preferences; } - + public File getJar() { return jar.get(); } - + public String getSeedMessage() { if (seedText == null) return "Seed: " + seed; diff --git a/src/amidst/gui/menu/AmidstMenu.java b/src/amidst/gui/menu/AmidstMenu.java index fe068a43..a92eb980 100644 --- a/src/amidst/gui/menu/AmidstMenu.java +++ b/src/amidst/gui/menu/AmidstMenu.java @@ -43,23 +43,23 @@ public class AmidstMenu extends JMenuBar { public final JMenu mapMenu; //TODO: protected final JMenu optionsMenu; final JMenu helpMenu; - + private final FinderWindow window; - + public AmidstMenu(FinderWindow window) { this.window = window; - + fileMenu = add(new FileMenu()); mapMenu = add(new MapMenu()); optionsMenu = add(new OptionsMenu()); helpMenu = add(new HelpMenu()); } - + private class FileMenu extends JMenu { private FileMenu() { super("File"); setMnemonic(KeyEvent.VK_F); - + add(new JMenu("New") {{ setMnemonic(KeyEvent.VK_N); add(new SeedMenuItem()); @@ -67,7 +67,7 @@ private FileMenu() { add(new RandomSeedMenuItem()); //add(new JMenuItem("From Server")); }}); - + add(new JMenuItem("Save player locations") {{ setEnabled(MinecraftUtil.getVersion().saveEnabled()); setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); @@ -85,7 +85,7 @@ public void actionPerformed(ActionEvent arg0) { } }); }}); - + add(new JMenuItem("Exit") {{ addActionListener(new ActionListener() { @Override @@ -99,7 +99,7 @@ private String showSeedPrompt(String title) { final String blankText = "A random seed will be generated if left blank."; final String leadingSpaceText = "Warning: There is a space at the start!"; final String trailingSpaceText = "Warning: There is a space at the end!"; - + final JTextField inputText = new JTextField(); inputText.addAncestorListener( new AncestorListener() { @@ -116,7 +116,7 @@ public void ancestorRemoved(AncestorEvent arg0) { inputText.requestFocus(); } }); - + final JLabel inputInformation = new JLabel(blankText); inputInformation.setForeground(Color.red); inputInformation.setFont(new Font("arial", Font.BOLD, 10)); @@ -156,7 +156,7 @@ public void update() { } } }); - + final JComponent[] inputs = new JComponent[] { new JLabel("Enter your seed: "), inputInformation, @@ -165,7 +165,7 @@ public void update() { int result = JOptionPane.showConfirmDialog(window, inputs, title, JOptionPane.OK_CANCEL_OPTION); return (result == 0)?inputText.getText():null; } - + private class SeedMenuItem extends JMenuItem { private SeedMenuItem() { super("From seed"); @@ -182,7 +182,7 @@ public void actionPerformed(ActionEvent arg0) { } else { worldType = SaveLoader.Type.fromMixedCase(worldTypePreference); } - + if (seed.equals("")) seed = "" + (new Random()).nextLong(); if (worldType != null) { @@ -194,7 +194,7 @@ public void actionPerformed(ActionEvent arg0) { }); } } - + private class RandomSeedMenuItem extends JMenuItem { private RandomSeedMenuItem() { super("From random seed"); @@ -212,18 +212,18 @@ public void actionPerformed(ActionEvent arg0) { } else { worldType = SaveLoader.Type.fromMixedCase(worldTypePreference); } - + //If a string was returned, say so. if (worldType != null) { window.clearProject(); window.setProject(new Project(seed, worldType.getValue())); } } - + }); } } - + private class FileMenuItem extends JMenuItem { private FileMenuItem() { super("From file or folder"); @@ -247,7 +247,7 @@ public void actionPerformed(ActionEvent arg0) { fc.setFileHidingEnabled(false); if (fc.showOpenDialog(window) == JFileChooser.APPROVE_OPTION) { File f = fc.getSelectedFile(); - + SaveLoader s = null; if (f.isDirectory()) s = new SaveLoader(new File(f.getAbsoluteFile() + "/level.dat")); @@ -280,9 +280,9 @@ private MapMenu() { add(new LayersMenu()); add(new CopySeedMenuItem()); add(new CaptureMenuItem()); - + } - + private class FindMenu extends JMenu { private FindMenu() { super("Find"); @@ -299,7 +299,7 @@ public void actionPerformed(ActionEvent arg0) { }}); } } - + private class GoToMenu extends JMenu { private GoToMenu() { super("Go to"); @@ -322,7 +322,7 @@ public void actionPerformed(ActionEvent arg0) { } }); }}); - + add(new JMenuItem("Player") {{ addActionListener(new ActionListener() { @Override @@ -342,7 +342,7 @@ public void actionPerformed(ActionEvent arg0) { //add(new JMenuItem("Chunk")); } } - + private class LayersMenu extends JMenu { private LayersMenu() { super("Layers"); @@ -351,52 +351,57 @@ private LayersMenu() { ResourceLoader.getImage("grid.png"), KeyEvent.VK_1, Options.instance.showGrid)); - + add(new DisplayingCheckbox("Slime chunks", ResourceLoader.getImage("slime.png"), KeyEvent.VK_2, Options.instance.showSlimeChunks)); - + add(new DisplayingCheckbox("Village Icons", ResourceLoader.getImage("village.png"), KeyEvent.VK_3, Options.instance.showVillages)); - + add(new DisplayingCheckbox("Temple/Witch Hut Icons", ResourceLoader.getImage("desert.png"), KeyEvent.VK_4, Options.instance.showTemples)); - + add(new DisplayingCheckbox("Stronghold Icons", ResourceLoader.getImage("stronghold.png"), KeyEvent.VK_5, Options.instance.showStrongholds)); - + add(new DisplayingCheckbox("Player Icons", ResourceLoader.getImage("player.png"), KeyEvent.VK_6, Options.instance.showPlayers)); - + add(new DisplayingCheckbox("Nether Fortress Icons", ResourceLoader.getImage("nether_fortress.png"), KeyEvent.VK_7, Options.instance.showNetherFortresses)); - + + add(new DisplayingCheckbox("Mineshaft Icons", + ResourceLoader.getImage("mineshaft.png"), + KeyEvent.VK_8, + Options.instance.showMineshafts)); + add(new DisplayingCheckbox("Spawn Location Icon", ResourceLoader.getImage("spawn.png"), - KeyEvent.VK_8, + KeyEvent.VK_9, Options.instance.showSpawn)); - + } - + } private class CaptureMenuItem extends JMenuItem { private CaptureMenuItem() { super("Capture"); - + setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK)); - + addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -404,7 +409,7 @@ public void actionPerformed(ActionEvent e) { fc.setFileFilter(new PNGFileFilter()); fc.setAcceptAllFileFilterUsed(false); int returnVal = fc.showSaveDialog(window); - + if (returnVal == JFileChooser.APPROVE_OPTION) { String s = fc.getSelectedFile().toString(); if (!s.toLowerCase().endsWith(".png")) @@ -418,9 +423,9 @@ public void actionPerformed(ActionEvent e) { private class CopySeedMenuItem extends JMenuItem { private CopySeedMenuItem() { super("Copy Seed to Clipboard"); - + setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK)); - + addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -430,7 +435,7 @@ public void actionPerformed(ActionEvent e) { @Override public void lostOwnership(Clipboard arg0, Transferable arg1) { // TODO Auto-generated method stub - + } }); } @@ -438,7 +443,7 @@ public void lostOwnership(Clipboard arg0, Transferable arg1) { } } } - + private class OptionsMenu extends JMenu { private OptionsMenu() { super("Options"); @@ -490,7 +495,7 @@ public void actionPerformed(ActionEvent arg) { profileCheckboxes.get(0).setSelected(true); add(reloadMenuItem); } - + private boolean scanAndLoad(File folder, JMenu menu) { File[] files = folder.listFiles(); BiomeColorProfile profile; @@ -520,7 +525,7 @@ private boolean scanAndLoad(File folder, JMenu menu) { } return foundProfiles; } - + } private class MapOptionsMenu extends JMenu { private MapOptionsMenu() { @@ -530,35 +535,35 @@ private MapOptionsMenu() { null, KeyEvent.VK_I, Options.instance.mapFlicking)); - + add(new DisplayingCheckbox("Restrict Maximum Zoom", null, KeyEvent.VK_Z, Options.instance.maxZoom)); - + add(new DisplayingCheckbox("Show Framerate", null, KeyEvent.VK_L, Options.instance.showFPS)); - + add(new DisplayingCheckbox("Use Fragment Fading", null, -1, Options.instance.mapFading)); - + add(new DisplayingCheckbox("Show Debug Info", null, -1, Options.instance.showDebug)); } - + } private class WorldTypeMenu extends JMenu { private WorldTypeMenu() { super("World type"); SelectButtonModel[] buttonModels = Options.instance.worldType.getButtonModels(); - + for (int i = 0; i < buttonModels.length; i++) { add(new DisplayingCheckbox(buttonModels[i].getName(), null, @@ -566,14 +571,14 @@ private WorldTypeMenu() { buttonModels[i])); } } - + } } - + private class HelpMenu extends JMenu { private HelpMenu() { super("Help"); - + add(new JMenuItem("Check for updates") {{ addActionListener(new ActionListener() { @Override @@ -591,7 +596,7 @@ public void actionPerformed(ActionEvent e) { } }); }}); - + add(new JMenuItem("About") {{ addActionListener(new ActionListener() { @Override @@ -602,12 +607,12 @@ public void actionPerformed(ActionEvent e) { } }); }}); - + } } - + /** Allows the user to choose one of several things. - * + * * Convenience wrapper around JOptionPane.showInputDialog */ private T choose(String title, String message, T[] choices) { @@ -620,7 +625,7 @@ private T choose(String title, String message, T[] choices) { choices, choices[0]); } - + /** Lets the user decide one of the given points and go to it * @param points Given points to choose from * @param name name displayed in the choice diff --git a/src/amidst/map/MapMarkers.java b/src/amidst/map/MapMarkers.java index 0572bffb..654136ca 100644 --- a/src/amidst/map/MapMarkers.java +++ b/src/amidst/map/MapMarkers.java @@ -17,10 +17,11 @@ public enum MapMarkers { DESERT, VILLAGE, SPAWN, - WITCH; - + WITCH, + MINESHAFT; + public final BufferedImage image; - + private MapMarkers() { String fileName = this.toString().toLowerCase() + ".png"; image = ResourceLoader.getImage(fileName); diff --git a/src/amidst/map/MapObjectMineshaft.java b/src/amidst/map/MapObjectMineshaft.java new file mode 100644 index 00000000..3b8de855 --- /dev/null +++ b/src/amidst/map/MapObjectMineshaft.java @@ -0,0 +1,14 @@ +package amidst.map; + +/** Used mainly to be override its toString method for use in choices + */ +public class MapObjectMineshaft extends MapObject { + public MapObjectMineshaft(int x, int y) { + super(MapMarkers.MINESHAFT, x, y); + } + + @Override + public String toString() { + return "Mineshaft at (" + x + ", " + y + ")"; + } +} diff --git a/src/amidst/map/layers/MineshaftLayer.java b/src/amidst/map/layers/MineshaftLayer.java new file mode 100644 index 00000000..7dd0295e --- /dev/null +++ b/src/amidst/map/layers/MineshaftLayer.java @@ -0,0 +1,48 @@ +package amidst.map.layers; + +import java.util.Random; +import amidst.Options; +import amidst.map.Fragment; +import amidst.map.IconLayer; +import amidst.map.MapObjectMineshaft; +import amidst.map.MapObjectNether; + +public class MineshaftLayer extends IconLayer { + private Random random = new Random(); + + public MineshaftLayer() { + } + + @Override + public boolean isVisible() { + return Options.instance.showMineshafts.get(); + } + @Override + public void generateMapObjects(Fragment frag) { + int size = Fragment.SIZE >> 4; + for (int x = 0; x < size; x++) { + for (int y = 0; y < size; y++) { + int chunkX = x + frag.getChunkX(); + int chunkY = y + frag.getChunkY(); + if (checkChunk(chunkX, chunkY)) { + frag.addObject(new MapObjectMineshaft(x << 4, y << 4).setParent(this)); + } + } + } + } + + double _e = 0.004D; + + public boolean checkChunk(int chunkX, int chunkY) { + random.setSeed(Options.instance.seed); + long var7 = random.nextLong(); + long var9 = random.nextLong(); + + long var13 = (long)chunkX * var7; + long var15 = (long)chunkY * var9; + random.setSeed(var13 ^ var15 ^ Options.instance.seed); + random.nextInt(); + + return random.nextDouble() < _e && random.nextInt(80) < Math.max(Math.abs(chunkX), Math.abs(chunkY)); + } +} diff --git a/src/amidst/resources/mineshaft.png b/src/amidst/resources/mineshaft.png new file mode 100644 index 00000000..5c009a3a Binary files /dev/null and b/src/amidst/resources/mineshaft.png differ