/******************************************************************************* * Copyright (c) 2015 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *******************************************************************************/ package jsettlers.buildingcreator.editor; import go.graphics.swing.sound.SwingSoundPlayer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import jsettlers.buildingcreator.editor.map.BuildingtestMap; import jsettlers.buildingcreator.editor.map.PseudoTile; import jsettlers.common.Color; import jsettlers.common.buildings.EBuildingType; import jsettlers.common.buildings.RelativeBricklayer; import jsettlers.common.buildings.stacks.ConstructionStack; import jsettlers.common.buildings.stacks.RelativeStack; import jsettlers.common.material.EMaterialType; import jsettlers.common.menu.FakeMapGame; import jsettlers.common.menu.IMapInterfaceConnector; import jsettlers.common.menu.IMapInterfaceListener; import jsettlers.common.menu.action.EActionType; import jsettlers.common.menu.action.IAction; import jsettlers.common.movable.EDirection; import jsettlers.common.position.RelativePoint; import jsettlers.common.position.ShortPoint2D; import jsettlers.common.utils.MainUtils; import jsettlers.common.utils.OptionableProperties; import jsettlers.graphics.action.Action; import jsettlers.graphics.action.PointAction; import jsettlers.main.swing.SwingManagedJSettlers; import jsettlers.main.swing.lookandfeel.JSettlersLookAndFeelExecption; import jsettlers.main.swing.resources.SwingResourceLoader.ResourceSetupException; /** * This is the main building creator class. * * @author michael */ public class BuildingCreatorApp implements IMapInterfaceListener, Runnable { private BuildingDefinition definition; private BuildingtestMap map; private ToolType tool = ToolType.SET_BLOCKED; private JLabel positionDisplayer; private JFrame window; private BuildingCreatorApp(OptionableProperties options) throws ResourceSetupException { SwingManagedJSettlers.setupResourceManagers(options); } @Override public void run() { try { EBuildingType type = askType(); definition = new BuildingDefinition(type); map = new BuildingtestMap(definition); for (int x = 0; x < map.getWidth(); x++) { for (int y = 0; y < map.getHeight(); y++) { reloadColor(new ShortPoint2D(x, y)); } } IMapInterfaceConnector connector = startMapWindow(); connector.addListener(this); JPanel menu = generateMenu(); window = new JFrame("Edit " + type.toString()); window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); window.add(menu); window.pack(); window.setVisible(true); connector.fireAction(new Action(EActionType.TOGGLE_DEBUG)); } catch (JSettlersLookAndFeelExecption e) { throw new RuntimeException(e); } } private JPanel generateMenu() { JPanel menu = new JPanel(); menu.setLayout(new BoxLayout(menu, BoxLayout.Y_AXIS)); // menu.setPreferredSize(new Dimension(200, 100)); // actionList = new JPanel(); // actionList.setLayout(new BoxLayout(actionList, BoxLayout.Y_AXIS)); // menu.add(new JScrollPane(actionList)); menu.add(createToolChangeBar()); // JButton addButton = new JButton("add new action"); // addButton.addActionListener(new ActionListener() { // @Override // public void actionPerformed(ActionEvent e) { // addNewAction(); // } // }); // menu.add(addButton); JButton xmlButton = new JButton("show xml data"); xmlButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showXML(); } }); menu.add(xmlButton); positionDisplayer = new JLabel(); menu.add(positionDisplayer); return menu; } private IMapInterfaceConnector startMapWindow() throws JSettlersLookAndFeelExecption { return SwingManagedJSettlers.showJSettlers(new FakeMapGame(map)); } private JButton createToolChangeBar() { JButton button = new JButton("Select tool..."); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ToolType newTool = (ToolType) JOptionPane.showInputDialog(null, "Select building type", "Building Type", JOptionPane.QUESTION_MESSAGE, null, ToolType.values(), tool); if (newTool != null) { tool = newTool; } for (int x = 0; x < map.getWidth(); x++) { for (int y = 0; y < map.getWidth(); y++) { reloadColor(new ShortPoint2D(x, y)); } } } }); return button; } private EBuildingType askType() { EBuildingType[] buildingTypes = EBuildingType.values(); Arrays.sort(buildingTypes, new Comparator<EBuildingType>() { @Override public int compare(EBuildingType o1, EBuildingType o2) { return o1.name().compareTo(o2.name()); } }); return (EBuildingType) JOptionPane.showInputDialog(null, "Select building type", "Building Type", JOptionPane.QUESTION_MESSAGE, null, buildingTypes, null); } public static void main(String[] args) throws ResourceSetupException, InvocationTargetException, InterruptedException { SwingUtilities.invokeAndWait(new BuildingCreatorApp(MainUtils.loadOptions(args))); } @Override public void action(final IAction action) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { doAction(action); } }); } private void doAction(IAction action) { if (action instanceof PointAction) { PointAction sAction = (PointAction) action; ShortPoint2D pos = sAction.getPosition(); RelativePoint relative = absoluteToRelative(pos); positionDisplayer.setText("x = " + (pos.x - BuildingtestMap.OFFSET) + ", y = " + (pos.y - BuildingtestMap.OFFSET)); switch (tool) { case SET_BLOCKED: toogleUsedTile(relative); break; case SET_DOOR: setDoor(relative); break; case ADD_CONSTRUCTION_STACK: addConstructionStack(relative); break; case ADD_REQUEST_STACK: case ADD_OFFER_STACK: addStack(relative, tool == ToolType.ADD_REQUEST_STACK); break; case REMOVE_STACK: removeStack(relative); break; case SET_FLAG: setFlag(relative); break; case SET_BUILDMARK: definition.toggleBuildmarkStatus(relative); break; case BRICKLAYER_NE: definition.toggleBrickayer(relative, EDirection.NORTH_EAST); break; case BRICKLAYER_NW: definition.toggleBrickayer(relative, EDirection.NORTH_WEST); break; } reloadColor(pos); } } private void removeStack(RelativePoint relative) { definition.removeStack(relative); } private void addStack(RelativePoint relative, boolean requestStack) { EMaterialType material = requestMaterialType(tool); if (material != null) { if (requestStack) { definition.setRequestStack(relative, material); } else { definition.setOfferStack(relative, material); } } } private void addConstructionStack(RelativePoint relative) { EMaterialType material = requestMaterialType(tool); Integer buildrequired = (Integer) JOptionPane.showInputDialog(null, "Select building type", "Building Type", JOptionPane.QUESTION_MESSAGE, null, new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8 }, tool); if (material != null && buildrequired != null) { definition.setConstructionStack(relative, material, buildrequired.intValue()); } } private EMaterialType requestMaterialType(ToolType tool) { EMaterialType[] materialTypes = EMaterialType.values(); Arrays.sort(materialTypes, new Comparator<EMaterialType>() { @Override public int compare(EMaterialType o1, EMaterialType o2) { return o1.name().compareTo(o2.name()); } }); return (EMaterialType) JOptionPane.showInputDialog(null, "Select Material Type", "Material Type", JOptionPane.QUESTION_MESSAGE, null, materialTypes, tool); } private void setDoor(RelativePoint tile) { RelativePoint oldDoor = definition.getDoor(); ShortPoint2D oldPos = relativeToAbsolute(oldDoor); reloadColor(oldPos); definition.setDoor(tile); } private void setFlag(RelativePoint tile) { RelativePoint oldFlag = definition.getFlag(); ShortPoint2D oldPos = relativeToAbsolute(oldFlag); reloadColor(oldPos); definition.setFlag(tile); } private ShortPoint2D relativeToAbsolute(RelativePoint oldDoor) { ShortPoint2D oldPos = new ShortPoint2D(oldDoor.getDx() + BuildingtestMap.OFFSET, oldDoor.getDy() + BuildingtestMap.OFFSET); return oldPos; } private RelativePoint absoluteToRelative(ShortPoint2D pos) { RelativePoint tile = new RelativePoint(pos.x - BuildingtestMap.OFFSET, pos.y - BuildingtestMap.OFFSET); return tile; } private void toogleUsedTile(RelativePoint relative) { if (definition.getBlockedStatus(relative)) { definition.setBlockedStatus(relative, false, false); } else if (definition.getProtectedStatus(relative)) { definition.setBlockedStatus(relative, true, true); } else { definition.setBlockedStatus(relative, true, false); } } private void reloadColor(ShortPoint2D pos) { PseudoTile tile = map.getTile(pos); ArrayList<Color> colors = new ArrayList<Color>(); RelativePoint relative = absoluteToRelative(pos); if (definition.getBlockedStatus(relative)) { colors.add(new Color(0xff0343df)); } else if (definition.getProtectedStatus(relative)) { colors.add(new Color(0xff75bbfd)); } switch (tool) { case SET_BUILDMARK: if (definition.getBuildmarkStatus(relative)) { colors.add(new Color(0xfff97306)); } break; case SET_DOOR: if (definition.getDoor().equals(relative)) { colors.add(new Color(0xfff97306)); } break; case SET_FLAG: if (definition.getFlag().equals(relative)) { colors.add(new Color(0xfff97306)); } break; case ADD_CONSTRUCTION_STACK: checkAddConstructionStack(tile, colors, relative); break; case ADD_REQUEST_STACK: checkAddRequestStack(tile, colors, relative); break; case ADD_OFFER_STACK: checkAddOfferStack(tile, colors, relative); break; case REMOVE_STACK: checkAddConstructionStack(tile, colors, relative); checkAddRequestStack(tile, colors, relative); checkAddOfferStack(tile, colors, relative); break; case BRICKLAYER_NE: case BRICKLAYER_NW: if (definition.getBricklayerStatus(relative)) { colors.add(new Color(0xfff97306)); } break; default: break; } if (!colors.isEmpty()) { tile.setDebugColor(mixColors(colors)); } else { tile.setDebugColor(0); } } private void checkAddConstructionStack(PseudoTile tile, ArrayList<Color> colors, RelativePoint relative) { RelativeStack stack = getStackAt(relative, definition.getConstructionStacks()); if (stack != null) { colors.add(new Color(0xfff97386)); } tile.setStack(new MapStack(stack)); } private void checkAddRequestStack(PseudoTile tile, ArrayList<Color> colors, RelativePoint relative) { RelativeStack stack = getStackAt(relative, definition.getRequestStacks()); if (stack != null) { colors.add(new Color(0xfff973F6)); } tile.setStack(new MapStack(stack)); } private void checkAddOfferStack(PseudoTile tile, ArrayList<Color> colors, RelativePoint relative) { RelativeStack stack = getStackAt(relative, definition.getOfferStacks()); if (stack != null) { colors.add(new Color(0xfff97306)); } tile.setStack(new MapStack(stack)); } private static RelativeStack getStackAt(RelativePoint position, List<? extends RelativeStack> stacks) { int indexOf = stacks.indexOf(position); if (indexOf >= 0) { return stacks.get(indexOf); } else { return null; } } private static int mixColors(ArrayList<Color> colors) { float bluesum = 0; float redsum = 0; float greensum = 0; for (Color color : colors) { bluesum += color.getBlue(); redsum += color.getRed(); greensum += color.getGreen(); } int color = Color.getARGB(redsum / colors.size(), greensum / colors.size(), bluesum / colors.size(), 1); return color; } private void showXML() { StringBuilder builder = new StringBuilder(""); for (RelativePoint tile : definition.getBlocked()) { builder.append("\t<blocked dx=\""); builder.append(tile.getDx()); builder.append("\" dy=\""); builder.append(tile.getDy()); builder.append("\" block=\"true\" />\n"); } builder.append("\n"); for (RelativePoint tile : definition.getJustProtected()) { builder.append("\t<blocked dx=\""); builder.append(tile.getDx()); builder.append("\" dy=\""); builder.append(tile.getDy()); builder.append("\" block=\"false\" />\n"); } builder.append("\n"); RelativePoint door = definition.getDoor(); builder.append("\t<door dx=\""); builder.append(door.getDx()); builder.append("\" dy=\""); builder.append(door.getDy()); builder.append("\" />\n"); builder.append("\n"); for (ConstructionStack stack : definition.getConstructionStacks()) { builder.append("\t<constructionStack dx=\""); builder.append(stack.getDx()); builder.append("\" dy=\""); builder.append(stack.getDy()); builder.append("\" material=\""); builder.append(stack.getMaterialType().name()); builder.append("\" buildrequired=\""); builder.append(stack.requiredForBuild()); builder.append("\" />\n"); } for (RelativeStack stack : definition.getRequestStacks()) { builder.append("\t<requestStack dx=\""); builder.append(stack.getDx()); builder.append("\" dy=\""); builder.append(stack.getDy()); builder.append("\" material=\""); builder.append(stack.getMaterialType().name()); builder.append("\" />\n"); } for (RelativeStack stack : definition.getOfferStacks()) { builder.append("\t<offerStack dx=\""); builder.append(stack.getDx()); builder.append("\" dy=\""); builder.append(stack.getDy()); builder.append("\" material=\""); builder.append(stack.getMaterialType().name()); builder.append("\" />\n"); } builder.append("\n"); for (RelativeBricklayer bricklayer : definition.getBricklayers()) { builder.append("\t<bricklayer dx=\""); builder.append(bricklayer.getDx()); builder.append("\" dy=\""); builder.append(bricklayer.getDy()); builder.append("\" direction=\""); builder.append(bricklayer.getDirection()); builder.append("\" />\n"); } builder.append("\n"); RelativePoint flag = definition.getFlag(); builder.append("\t<flag dx=\""); builder.append(flag.getDx()); builder.append("\" dy=\""); builder.append(flag.getDy()); builder.append("\" />\n"); builder.append("\n"); for (RelativePoint mark : definition.getBuildmarks()) { builder.append("\t<buildmark dx=\""); builder.append(mark.getDx()); builder.append("\" dy=\""); builder.append(mark.getDy()); builder.append("\" />\n"); } builder.append("\n"); JDialog dialog = new JDialog(window, "xml"); dialog.add(new JScrollPane(new JTextArea(builder.toString()))); dialog.pack(); dialog.setSize(700, 900); dialog.setLocationRelativeTo(null); dialog.setVisible(true); } }