From: <aki...@us...> - 2007-01-11 18:55:15
|
Revision: 1563 http://svn.sourceforge.net/gridarta/?rev=1563&view=rev Author: akirschbaum Date: 2007-01-11 10:55:15 -0800 (Thu, 11 Jan 2007) Log Message: ----------- Use pickmap selection for insert, replace, fill, floodfill. Modified Paths: -------------- trunk/crossfire/ChangeLog trunk/crossfire/src/cfeditor/CMainControl.java trunk/crossfire/src/cfeditor/CMainView.java trunk/crossfire/src/cfeditor/CopyBuffer.java trunk/crossfire/src/cfeditor/gui/ReplaceDialog.java trunk/crossfire/src/cfeditor/map/MapControl.java trunk/crossfire/src/cfeditor/messages_de.properties trunk/daimonin/src/daieditor/messages.properties trunk/src/app/net/sf/gridarta/messages.properties Modified: trunk/crossfire/ChangeLog =================================================================== --- trunk/crossfire/ChangeLog 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/ChangeLog 2007-01-11 18:55:15 UTC (rev 1563) @@ -1,5 +1,7 @@ 2007-01-11 Andreas Kirschbaum + * Use pickmap selection for insert, replace, fill, floodfill. + * Add context menu to pickmap chooser. 2007-01-10 Andreas Kirschbaum Modified: trunk/crossfire/src/cfeditor/CMainControl.java =================================================================== --- trunk/crossfire/src/cfeditor/CMainControl.java 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/CMainControl.java 2007-01-11 18:55:15 UTC (rev 1563) @@ -576,6 +576,11 @@ return mainView.isLockAllPickmaps(); } + // ask arch panel which arches are selectd + public List<GameObject> getArchPanelSelection() { + return mainView.getArchPanelSelection(); + } + // ask arch panel which arch is highlighted public GameObject getArchPanelHighlight() { return mainView.getArchPanelHighlight(); @@ -1865,7 +1870,7 @@ * @param fillBelow true if "Fill Below" was activated, false if "Fill Above" */ private void fillWanted(final boolean fillBelow) { - mainControl.getCopyBuffer().fill(mainControl.getCurrentMap(), fillBelow, -1); + mainControl.getCopyBuffer().fill(mainControl.getCurrentMap(), fillBelow, null, -1); } /** "Random fill above" was selected from the Edit menu. */ @@ -1888,10 +1893,31 @@ */ private void fillRandomWanted(final boolean fillBelow) { final MapControl currentMap = mainControl.getCurrentMap(); + final StringBuilder title = new StringBuilder(fillBelow ? "Random fill below " : "Random fill above "); + final GameObject arch = instance.getArchPanelHighlight(); + MapControl pmap = null; + /* if we have a single arch, use it as random seed. + * We can throw the arch with % chance over the selected area. + * If the arch is null, we look we have a selected pickmap. + * if so, use the pickmap as random arch seed for the filler. + */ + if (arch != null) { + title.append("with arch ").append(arch.getArchetypeName()); + } else { + pmap = mainControl.getMainView().getPickmapChooserControl().getCurrentPickmap(); + if (pmap != null) { + title.append("with pickmap ").append(pmap.getMapArchObject().getMapName()); + } else { // ok ,we have a problem here: arch == null, pmap == null... + // XXX but shouldn't be something told to the user? + // Not even a logging? + return; + } + } + String input = "100"; for (;;) { - input = (String) JOptionPane.showInputDialog(mainControl.getMainView(), "Enter a fill density between 1-100", fillBelow ? "Random fill below" : "Random fill above", JOptionPane.QUESTION_MESSAGE, null, null, input); + input = (String) JOptionPane.showInputDialog(mainControl.getMainView(), "Enter a fill density between 1-100", title.toString(), JOptionPane.QUESTION_MESSAGE, null, null, input); if (input == null) { break; } @@ -1905,7 +1931,7 @@ if (rand < 1 || rand > 100) { JOptionPane.showMessageDialog(mainControl.getMainView(), "The fill density must be between 1-100.", "Illegal Value.", JOptionPane.ERROR_MESSAGE); } else { - mainControl.getCopyBuffer().fill(currentMap, fillBelow, rand); + mainControl.getCopyBuffer().fill(currentMap, fillBelow, pmap, rand); break; } } Modified: trunk/crossfire/src/cfeditor/CMainView.java =================================================================== --- trunk/crossfire/src/cfeditor/CMainView.java 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/CMainView.java 2007-01-11 18:55:15 UTC (rev 1563) @@ -322,7 +322,7 @@ * must be generated before inserting such an arch to the map. * @return the active arch in the left-side panel */ - public GameObject getArchPanelHighlight() { + @Nullable public GameObject getArchPanelHighlight() { if ((isPickmapActive() || archPanel.getArchPanelSelection() == null) && pickmapChooserControl.isLoadComplete() && pickmapChooserControl.getCurrentPickmap() != null) { // get the active pickmap @@ -340,6 +340,7 @@ return arch.getHead(); } } + return null; } // return the arch from the archlist in any case the pickmap is @@ -347,6 +348,36 @@ return archPanel.getArchPanelSelection(); } + /** + * Returns the selected arches in the left-side panel. + * This can either be default arches, or + * custom arches from a pickmap. + * IMPORTANT: The returned GameObject list contains no clone. A copy + * must be generated before inserting such arches to the map. + * @return the selected arches in the left-side panel + */ + @Nullable public List<GameObject> getArchPanelSelection() { + + if ((isPickmapActive() || archPanel.getArchPanelSelection() == null) && pickmapChooserControl.isLoadComplete()) { + // get the active pickmap + final MapControl pmap = pickmapChooserControl.getCurrentPickmap(); + if (pmap != null) { + return CopyBuffer.getMapArchList(pmap, 100); + } + return null; + } + + // return the arch from the archlist in any case the pickmap is + // either not active or didn't work + final GameObject archObject = archPanel.getArchPanelSelection(); + if (archObject != null) { + final ArrayList<GameObject> archPanelList = new ArrayList<GameObject>(); + archPanelList.add(archObject); + return archPanelList; + } + return null; + } + public void showArchPanelQuickObject(final GameObject gameObject) { archPanel.showArchPanelQuickObject(gameObject); } Modified: trunk/crossfire/src/cfeditor/CopyBuffer.java =================================================================== --- trunk/crossfire/src/cfeditor/CopyBuffer.java 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/CopyBuffer.java 2007-01-11 18:55:15 UTC (rev 1563) @@ -31,7 +31,9 @@ import cfeditor.map.MapModel; import java.awt.Point; import java.awt.Rectangle; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import net.sf.gridarta.MainControl; import net.sf.gridarta.Size2D; import net.sf.gridarta.map.MapSquare; @@ -223,14 +225,29 @@ * @param mapControl MapControl of the active map we paste on * @param fillBelow if true, the filling content is placed *below* the * existing map + * @param seed MapControl of the random objects or <code>null</code> to use the currently selected Archetype. * @param density the fill density in percent; -1 to disable */ - public void fill(final MapControl mapControl, final boolean fillBelow, final int density) { + public void fill(final MapControl mapControl, final boolean fillBelow, final MapControl seed, final int density) { if (!mapControl.getMapViewFrame().isHighlight()) { return; // should actually never happen } - if (mainControl.getArchPanelHighlight() == null) { // no selected arch to fill with + final List<GameObject> archList; + if (seed == null) { + final List<GameObject> archPanelSelection = mainControl.getArchPanelSelection(); + if (archPanelSelection == null || archPanelSelection.isEmpty()) { + return; + } + archList = archPanelSelection; + } else { + final int seedSize = countMapArches(seed); + if (seedSize == 0) { + return; + } + archList = getMapArchList(seed, seedSize); + } + if (archList == null || archList.isEmpty()) { return; } @@ -239,13 +256,92 @@ if (density != -1 && density != 100 && density < MainControl.rnd.nextInt(100) + 1) { continue; } - final GameObject gameObject = mainControl.getArchPanelHighlight(); + final GameObject gameObject = archList.get(MainControl.rnd.nextInt(archList.size())); addArchToMap(mapControl, gameObject, p, false, fillBelow); } mapControl.getMapModel().endTransaction(); } /** + * Count the arches in a map. + * @param mapControl MapControl to count arches of + * @return arches in map of <var>mapControl</var> + */ + private static int countMapArches(final MapControl mapControl) { + final MapModel map = mapControl.getMapModel(); + int count = 0; + final Size2D mapSize = map.getMapSize(); + final Point pos = new Point(); + for (pos.x = 0; pos.x < mapSize.getWidth(); pos.x++) { + for (pos.y = 0; pos.y < mapSize.getHeight(); pos.y++) { + for (final GameObject node : map.getMapSquare(pos)) { + // only non multi suckers + if (!node.isTail()) { + count++; + } + } + } + } + return count; + } + + /** + * Get a random gameObject from a map. + * @param mapControl map to get random gameObject from + * @param max Initial size of Array in #getMapArchList + * @return random gameObject from <var>mapControl</var> + */ + @Nullable public static GameObject getRandomMapArch(final MapControl mapControl, final int max) { + final List<GameObject> objects = getMapArchList(mapControl, max); + if (objects == null) { + return null; + } + final int objectSize = objects.size(); + if (objectSize == 0) { + return null; + } + if (objectSize == 1) { + return objects.get(0); + } + return objects.get(CMainControl.rnd.nextInt(objects.size())); + } + + /** + * Returns a list of all ArchObjects on selected MapSquares. + * If no MapSquare is selected all ArchObjects are returned. + * Tail ArchObjects will not be in the list. + * @param mapControl Map to get ArchList from + * @param max Initial size of Array size + * @return Array of selected/all ArchObjects + */ + @Nullable public static List<GameObject> getMapArchList(final MapControl mapControl, final int max) { + if (mapControl == null) { + return null; + } + final MapViewIFrame mapViewIFrame = mapControl.getMapViewFrame(); + final Iterable<MapSquare<GameObject, MapArchObject>> mapSquares; + if (mapViewIFrame == null) { + mapSquares = mapControl.getAllSquares(); + } else { + final List<MapSquare<GameObject, MapArchObject>> selectedMapSquares = mapViewIFrame.getView().getSelectedSquares(); + if (selectedMapSquares.isEmpty()) { + mapSquares = mapControl.getAllSquares(); + } else { + mapSquares = selectedMapSquares; + } + } + final List<GameObject> objects = new ArrayList<GameObject>(max); + for (final MapSquare<GameObject, MapArchObject> mapSquare : mapSquares) { + for (final GameObject node : mapSquare) { + if (!node.isTail()) { + objects.add(node); + } + } + } + return objects.isEmpty() ? null : objects; + } + + /** * Floodfill the the map, starting at the cursor position. * * @param mapControl the map to fill @@ -260,13 +356,13 @@ return; } - final GameObject arch = mainControl.getArchPanelHighlight(); - if (arch == null) { + final List<GameObject> archList = mainControl.getArchPanelSelection(); + if (archList == null || archList.isEmpty()) { return; } mapControl.getMapModel().beginTransaction("Floodfill"); // TODO: I18N/L10N - floodfill(mapControl, cursor.x, cursor.y, arch); + floodfill(mapControl, cursor.x, cursor.y, archList); mapControl.getMapModel().endTransaction(); } @@ -280,21 +376,22 @@ * @param startY starting y-coord for floodfill * @param arch GameObject to fill with */ - private void floodfill(final MapControl mapControl, final int startX, final int startY, final GameObject arch) { - addArchToMap(mapControl, arch, new Point(startX, startY), false, false); + private void floodfill(final MapControl mapControl, final int startX, final int startY, final List<GameObject> archList) { + final GameObject gameObject = archList.get(MainControl.rnd.nextInt(archList.size())); + addArchToMap(mapControl, gameObject, new Point(startX, startY), false, false); // now go recursive into all four directions if (mapControl.isPointValid(new Point(startX - 1, startY)) && !mapControl.containsArchObject(new Point(startX - 1, startY))) { - floodfill(mapControl, startX - 1, startY, arch); + floodfill(mapControl, startX - 1, startY, archList); } if (mapControl.isPointValid(new Point(startX, startY - 1)) && !mapControl.containsArchObject(new Point(startX, startY - 1))) { - floodfill(mapControl, startX, startY - 1, arch); + floodfill(mapControl, startX, startY - 1, archList); } if (mapControl.isPointValid(new Point(startX + 1, startY)) && !mapControl.containsArchObject(new Point(startX + 1, startY))) { - floodfill(mapControl, startX + 1, startY, arch); + floodfill(mapControl, startX + 1, startY, archList); } if (mapControl.isPointValid(new Point(startX, startY + 1)) && !mapControl.containsArchObject(new Point(startX, startY + 1))) { - floodfill(mapControl, startX, startY + 1, arch); + floodfill(mapControl, startX, startY + 1, archList); } } Modified: trunk/crossfire/src/cfeditor/gui/ReplaceDialog.java =================================================================== --- trunk/crossfire/src/cfeditor/gui/ReplaceDialog.java 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/gui/ReplaceDialog.java 2007-01-11 18:55:15 UTC (rev 1563) @@ -35,6 +35,7 @@ import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; @@ -81,6 +82,8 @@ private GameObject replaceArch = null; // objects will be replaced by this arch + private List<GameObject> replacePickmap; // selected objects in pickmap or all if none is selected + private JLabel rfHeading; private JLabel rfArchName = null; @@ -131,6 +134,7 @@ */ public void display(final MapControl mapControl) { replaceArch = mainControl.getArchPanelHighlight(); // highlighted arch + replacePickmap = mainControl.getArchPanelSelection(); // selected arches if (!isBuilt) { this.mapControl = mapControl; @@ -177,9 +181,10 @@ line3.add(label2); line3.add(Box.createVerticalStrut(5)); replaceWithBox = new JComboBox(new String[]{ACTION_FACTORY.getString("replaceByObject"), + ACTION_FACTORY.getString("replaceByPickmap"), ACTION_FACTORY.getString("replaceByNothing")}); if (replaceArch == null) { - replaceWithBox.setSelectedIndex(1); + replaceWithBox.setSelectedIndex(2); } else { replaceWithBox.setSelectedIndex(0); } @@ -288,11 +293,30 @@ return 0; } + final List<GameObject> replaceList; + switch (lastSelectedIndex) { + case 0: + if (replaceArch == null) { + replaceList = null; + } else { + replaceList = new ArrayList<GameObject>(1); + replaceList.add(replaceArch); + } + break; + case 1: + replaceList = replacePickmap; + break; + + default: + replaceList = null; + break; + } final MapViewIFrame mapViewIFrame = mapControl.getMapViewFrame(); assert mapViewIFrame != null; int replaceCount = 0; final ArrayList<GameObject> objectsToReplace = new ArrayList<GameObject>(); + final int replaceListSize = replaceList == null ? 0 : replaceList.size(); mapControl.getMapModel().beginTransaction("Replace"); // TODO: I18N/L10N for (final MapSquare<GameObject, MapArchObject> square : entireMap ? mapControl.getMapModel() : mapViewIFrame.getView().getSelectedSquares()) { // find objects to replace @@ -322,16 +346,25 @@ // first, delete the old arch node.remove(); - if (replaceArch != null && !deleteOnly) { + if (replaceListSize > 0 && !deleteOnly) { + GameObject randomArch; + if (replaceListSize == 1) { + randomArch = replaceList.get(0); + } else { + randomArch = replaceList.get(CMainControl.rnd.nextInt(replaceList.size())); + } + if (randomArch.isMulti()) { + // multi's cannot be inserted properly, so we just put them ontop + randomArch = randomArch.getHead(); + } // insert replacement object - if (replaceArch.isMulti()) { + if (randomArch.isMulti()) { // multi's cannot be inserted properly, so we just put them ontop - replaceArch = replaceArch.getHead(); - mapControl.addArchToMap(replaceArch.getArchetypeName(), new Point(square.getMapX(), square.getMapY()), false, false); + mapControl.addArchToMap(randomArch.getArchetypeName(), new Point(square.getMapX(), square.getMapY()), false, false); // TODO: if from pickmap it could have special attributes -> copy them } else { - mapControl.insertArchToMap(replaceArch, null, prevArch, new Point(square.getMapX(), square.getMapY()), false); + mapControl.insertArchToMap(randomArch, null, prevArch, new Point(square.getMapX(), square.getMapY()), false); } } replaceCount++; @@ -349,6 +382,7 @@ public void itemStateChanged(final ItemEvent e) { final int selectedIndex = replaceWithBox.getSelectedIndex(); if (e.getStateChange() == ItemEvent.SELECTED && lastSelectedIndex != selectedIndex) { + final int size; switch (selectedIndex) { case 0: // replace with arch @@ -357,6 +391,20 @@ break; case 1: + // replace with pickmap + replacePickmap = mainControl.getArchPanelSelection(); // selected arches + iconLabel.setIcon(null); + if (replacePickmap == null) { + size = 0; + } else { + size = replacePickmap.size(); + } + rfArchName.setText(String.valueOf(size)); + colonLabel.setText(":"); + dialog.pack(); + break; + + case 2: // replace with nothing iconLabel.setIcon(null); rfArchName.setText(""); @@ -375,7 +423,7 @@ */ public void replaceOk() { final String matchString = replaceInput1.getText().trim(); - final boolean deleteOnly = replaceWithBox.getSelectedIndex() == 1; + final boolean deleteOnly = replaceWithBox.getSelectedIndex() == 2; final boolean entireMap = replaceEntireBox.getSelectedIndex() == 0; final MapViewIFrame mapViewIFrame = mapControl.getMapViewFrame(); Modified: trunk/crossfire/src/cfeditor/map/MapControl.java =================================================================== --- trunk/crossfire/src/cfeditor/map/MapControl.java 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/map/MapControl.java 2007-01-11 18:55:15 UTC (rev 1563) @@ -25,6 +25,7 @@ package cfeditor.map; import cfeditor.CMainControl; +import cfeditor.CopyBuffer; import cfeditor.IGUIConstants; import cfeditor.MapViewIFrame; import cfeditor.gameobject.GameObject; @@ -39,6 +40,7 @@ import net.sf.gridarta.gui.map.MapGridListener; import net.sf.gridarta.map.AbstractMapControl; import net.sf.gridarta.map.MapModelListener; +import net.sf.gridarta.map.MapSquare; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -346,7 +348,7 @@ // this is the arch that would get inserted from pickmap, but it also could // be a default arch (when pickmap has no selection) - GameObject newarch = mainControl.getArchPanelHighlight(); + GameObject newarch = CopyBuffer.getRandomMapArch(mainControl.getMainView().getPickmapChooserControl().getCurrentPickmap(), 100); if (!mainControl.getMainView().isPickmapActive() || isPickmap() || (newarch != null && newarch.isArchetype())) { // insert default arch from archlist: @@ -505,6 +507,14 @@ } /** + * Get Iterable of all MapSquares. + * @return Iterable of all MapSquares + */ + public Iterable<MapSquare<GameObject, MapArchObject>> getAllSquares() { + return mapModel; + } + + /** * Determines if this map has an active selection. * * @return <code>true</code> if this map has an active selection, Modified: trunk/crossfire/src/cfeditor/messages_de.properties =================================================================== --- trunk/crossfire/src/cfeditor/messages_de.properties 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/crossfire/src/cfeditor/messages_de.properties 2007-01-11 18:55:15 UTC (rev 1563) @@ -175,6 +175,7 @@ replaceDelete=l\xF6sche Objekte mit replaceBy=und ersetze durch replaceByObject=Objekt +replaceByPickmap=Pickmap replaceByNothing=nichts (=l\xF6schen) replaceMapGone.title=Karte nicht mehr verf\xFCgbar Modified: trunk/daimonin/src/daieditor/messages.properties =================================================================== --- trunk/daimonin/src/daieditor/messages.properties 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/daimonin/src/daieditor/messages.properties 2007-01-11 18:55:15 UTC (rev 1563) @@ -154,7 +154,6 @@ mapTilePathMode.shortdescription=Switch between relative and absolute path replaceByCopyBuffer=clipboard -replaceByPickmap=pickmap arcDoc.htmlText=<html><head><meta name="CFJavaEditor" content="tmp"><title>{0}</title></head><body><h1 style="text-align:center;colour:navy;">{0}</h1><h3 style="colour:navy;">Functionality of {0}:</h3><p>{1}</p><h3 style="colour:navy;">Notes on Usage:</h3><p>{2}</p></body></html> Modified: trunk/src/app/net/sf/gridarta/messages.properties =================================================================== --- trunk/src/app/net/sf/gridarta/messages.properties 2007-01-10 23:14:29 UTC (rev 1562) +++ trunk/src/app/net/sf/gridarta/messages.properties 2007-01-11 18:55:15 UTC (rev 1563) @@ -123,6 +123,7 @@ replaceDelete=delete objects with replaceBy=and replace by replaceByObject=object +replaceByPickmap=pickmap replaceByNothing=nothing replaceMapGone.title=Error with Replace This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |