From: <aki...@us...> - 2010-06-03 23:00:48
|
Revision: 8088 http://gridarta.svn.sourceforge.net/gridarta/?rev=8088&view=rev Author: akirschbaum Date: 2010-06-03 23:00:42 +0000 (Thu, 03 Jun 2010) Log Message: ----------- Properly retain "elevation" game object attributes when editing maps. Modified Paths: -------------- trunk/crossfire/ChangeLog trunk/crossfire/src/app/net/sf/gridarta/var/crossfire/model/gameobject/GameObject.java trunk/crossfire.iml trunk/src/app/net/sf/gridarta/model/baseobject/GameObjectContainer.java trunk/src/app/net/sf/gridarta/model/gameobject/DefaultIsoGameObject.java trunk/src/app/net/sf/gridarta/model/gameobject/GameObject.java trunk/src/test/net/sf/gridarta/model/gameobject/TestGameObject.java Added Paths: ----------- trunk/crossfire/src/test/net/ trunk/crossfire/src/test/net/sf/ trunk/crossfire/src/test/net/sf/gridarta/ trunk/crossfire/src/test/net/sf/gridarta/var/ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/GameObjectCreator.java trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/PropagateElevationTest.java Modified: trunk/crossfire/ChangeLog =================================================================== --- trunk/crossfire/ChangeLog 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/crossfire/ChangeLog 2010-06-03 23:00:42 UTC (rev 8088) @@ -1,3 +1,8 @@ +2010-06-04 Andreas Kirschbaum + + * Properly retain "elevation" game object attributes when editing + maps. + 2010-06-03 Andreas Kirschbaum * Make "Move Env" to always insert into the selected map square. Modified: trunk/crossfire/src/app/net/sf/gridarta/var/crossfire/model/gameobject/GameObject.java =================================================================== --- trunk/crossfire/src/app/net/sf/gridarta/var/crossfire/model/gameobject/GameObject.java 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/crossfire/src/app/net/sf/gridarta/var/crossfire/model/gameobject/GameObject.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -80,7 +80,7 @@ * {@inheritDoc} */ @Override - public void propagateElevation(@NotNull final BaseObject<GameObject, MapArchObject, Archetype, ?> gameObject) { + public void propagateElevation(@NotNull final BaseObject<?, ?, ?, ?> gameObject) { final String elevation = gameObject.getAttributeString(ELEVATION, false); if (elevation.length() != 0) { setAttributeString(ELEVATION, elevation); Added: trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/GameObjectCreator.java =================================================================== --- trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/GameObjectCreator.java (rev 0) +++ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/GameObjectCreator.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -0,0 +1,86 @@ +/* + * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games. + * Copyright (C) 2000-2010 The Gridarta Developers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package net.sf.gridarta.var.crossfire.model.gameobject; + +import java.util.regex.Pattern; +import net.sf.gridarta.model.anim.AnimationObjects; +import net.sf.gridarta.model.anim.DefaultAnimationObjects; +import net.sf.gridarta.model.face.ArchFaceProvider; +import net.sf.gridarta.model.face.DefaultFaceObjects; +import net.sf.gridarta.model.face.FaceObjectProviders; +import net.sf.gridarta.model.face.FaceObjects; +import net.sf.gridarta.utils.GUIUtils; +import net.sf.gridarta.utils.SystemIcons; +import net.sf.gridarta.var.crossfire.model.archetype.Archetype; +import net.sf.gridarta.var.crossfire.model.archetype.DefaultArchetype; +import org.jetbrains.annotations.NotNull; + +/** + * Creates {@link GameObject GameObjects}. + * @author Andreas Kirschbaum + */ +public class GameObjectCreator { + + /** + * The {@link Archetype} for created game objects. + */ + @NotNull + private final Archetype archetype; + + /** + * The {@link FaceObjectProviders} for created game objects. + */ + @NotNull + private final FaceObjectProviders faceObjectProviders; + + /** + * The {@link AnimationObjects} for created game objects. + */ + @NotNull + private final AnimationObjects animationObjects; + + /** + * Creates a new instance. + */ + GameObjectCreator() { + final ArchFaceProvider archFaceProvider = new ArchFaceProvider(); + final FaceObjects faceObjects = new DefaultFaceObjects("pngFile", "faceTreeFile", Pattern.compile(""), "", archFaceProvider); + final GUIUtils guiUtils = new GUIUtils(); + final SystemIcons systemIcons = new SystemIcons(guiUtils); + faceObjectProviders = new FaceObjectProviders(1, faceObjects, systemIcons); + animationObjects = new DefaultAnimationObjects("animTreeFile"); + archetype = new DefaultArchetype("arch", faceObjectProviders, animationObjects); + } + + /** + * Creates a new {@link GameObject}. + * @param elevation the game object's elevation + * @return the new game object + */ + @NotNull + public GameObject newGameObject(final int elevation) { + final GameObject gameObject = new GameObject(archetype, faceObjectProviders, animationObjects); + if (elevation != 0) { + gameObject.setAttributeString(GameObject.ELEVATION, Integer.toString(elevation)); + } + return gameObject; + } + +} // class GameObjectCreator Property changes on: trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/GameObjectCreator.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + LF Added: trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/PropagateElevationTest.java =================================================================== --- trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/PropagateElevationTest.java (rev 0) +++ trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/PropagateElevationTest.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -0,0 +1,351 @@ +/* + * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games. + * Copyright (C) 2000-2010 The Gridarta Developers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package net.sf.gridarta.var.crossfire.model.gameobject; + +import java.util.Iterator; +import net.sf.gridarta.model.baseobject.GameObjectContainer; +import net.sf.gridarta.var.crossfire.model.archetype.Archetype; +import net.sf.gridarta.var.crossfire.model.maparchobject.MapArchObject; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.Test; + +/** + * Checks that {@link GameObjectContainer GameObjectContainers} correctly + * propagate elevation information when being modified. + * @author Andreas Kirschbaum + */ +public class PropagateElevationTest { + + /** + * Checks that {@link + * GameObjectContainer#addFirst(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testAddFirst() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> gameObjectContainer = gameObjectCreator.newGameObject(0); + + // first game object => keep + gameObjectContainer.addFirst(gameObjectCreator.newGameObject(123)); + check(gameObjectContainer, 123); + + // without elevation => propagate + gameObjectContainer.addFirst(gameObjectCreator.newGameObject(0)); + check(gameObjectContainer, 123); + + // with elevation => ignore but propagate + gameObjectContainer.addFirst(gameObjectCreator.newGameObject(321)); + check(gameObjectContainer, 123); + } + + /** + * Checks that {@link + * GameObjectContainer#addLast(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testAddLast() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> gameObjectContainer = gameObjectCreator.newGameObject(0); + + // first game object => keep + gameObjectContainer.addLast(gameObjectCreator.newGameObject(123)); + check(gameObjectContainer, 123); + + // without elevation => keep + gameObjectContainer.addLast(gameObjectCreator.newGameObject(0)); + check(gameObjectContainer, 123, 0); + + // with elevation => keep + gameObjectContainer.addLast(gameObjectCreator.newGameObject(321)); + check(gameObjectContainer, 123, 0, 321); + } + + /** + * Checks that {@link + * GameObjectContainer#insertBefore(net.sf.gridarta.model.gameobject.GameObject, + * GameObject)} does work correctly. + */ + @Test + public void testInsertBefore() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> gameObjectContainer = gameObjectCreator.newGameObject(0); + + // first game object => keep + gameObjectContainer.insertBefore(gameObjectCreator.newGameObject(1), null); + check(gameObjectContainer, 1); + + // without elevation => propagate + gameObjectContainer.insertBefore(gameObjectCreator.newGameObject(0), null); + check(gameObjectContainer, 1, 0); + + // with elevation => ignore but propagate + final GameObject ob1 = gameObjectCreator.newGameObject(2); + gameObjectContainer.insertBefore(ob1, null); + check(gameObjectContainer, 1, 0, 0); + + // with elevation => keep + gameObjectContainer.insertBefore(gameObjectCreator.newGameObject(3), ob1); + check(gameObjectContainer, 1, 3, 0, 0); + + // with elevation => ignore but propagate + gameObjectContainer.insertBefore(gameObjectCreator.newGameObject(4), null); + check(gameObjectContainer, 1, 0, 3, 0, 0); + } + + /** + * Checks that {@link + * GameObjectContainer#insertAfter(net.sf.gridarta.model.gameobject.GameObject, + * GameObject)} does work correctly. + */ + @Test + public void testInsertAfter() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> gameObjectContainer = gameObjectCreator.newGameObject(0); + + // first game object => keep + gameObjectContainer.insertAfter(null, gameObjectCreator.newGameObject(1)); + check(gameObjectContainer, 1); + + // at end => keep + final GameObject ob1 = gameObjectCreator.newGameObject(2); + gameObjectContainer.insertAfter(null, ob1); + check(gameObjectContainer, 1, 2); + + // at front, without elevation => propagate + gameObjectContainer.insertAfter(ob1, gameObjectCreator.newGameObject(0)); + check(gameObjectContainer, 1, 0, 2); + + // middle => keep + gameObjectContainer.insertAfter(ob1, gameObjectCreator.newGameObject(3)); + check(gameObjectContainer, 1, 0, 3, 2); + + // at front, with elevation => ignore but propagate + gameObjectContainer.insertAfter(gameObjectContainer.getFirst(), gameObjectCreator.newGameObject(4)); + check(gameObjectContainer, 1, 0, 0, 3, 2); + } + + /** + * Checks that {@link + * GameObjectContainer#moveBottom(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testMoveBottom() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.moveBottom(get(container1, 0)); + check(container1, 1, 0, 0, 0); + container1.moveBottom(get(container1, 1)); + check(container1, 1, 0, 0, 0); + container1.moveBottom(get(container1, 3)); + check(container1, 1, 0, 0, 0); + } + + /** + * Checks that {@link + * GameObjectContainer#moveDown(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testMoveDown() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.moveDown(get(container1, 0)); + check(container1, 1, 0, 0, 0); + container1.moveDown(get(container1, 1)); + check(container1, 1, 0, 0, 0); + container1.moveDown(get(container1, 3)); + check(container1, 1, 0, 0, 0); + } + + /** + * Checks that {@link + * GameObjectContainer#moveUp(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testMoveUp() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.moveUp(get(container1, 0)); + check(container1, 1, 0, 0, 0); + container1.moveUp(get(container1, 1)); + check(container1, 1, 0, 0, 0); + container1.moveUp(get(container1, 3)); + check(container1, 1, 0, 0, 0); + } + + /** + * Checks that {@link + * GameObjectContainer#moveTop(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testMoveTop() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.moveTop(get(container1, 0)); + check(container1, 1, 0, 0, 0); + container1.moveTop(get(container1, 1)); + check(container1, 1, 0, 0, 0); + container1.moveTop(get(container1, 3)); + check(container1, 1, 0, 0, 0); + } + + /** + * Checks that {@link + * GameObjectContainer#remove(net.sf.gridarta.model.gameobject.GameObject)} + * does work correctly. + */ + @Test + public void testRemove() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.remove(get(container1, 0)); + check(container1, 1, 0, 0); + container1.remove(get(container1, 2)); + check(container1, 1, 0); + container1.remove(get(container1, 0)); + check(container1, 1); + container1.remove(get(container1, 0)); + check(container1); + } + + /** + * Checks that {@link + * GameObjectContainer#replace(net.sf.gridarta.model.gameobject.GameObject, + * GameObject)} does work correctly. + */ + @Test + public void testReplace() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0); + container1.replace(get(container1, 0), gameObjectCreator.newGameObject(2)); + check(container1, 1, 0, 0, 0); + container1.replace(get(container1, 1), gameObjectCreator.newGameObject(3)); + check(container1, 1, 3, 0, 0); + container1.replace(get(container1, 0), gameObjectCreator.newGameObject(4)); + check(container1, 1, 3, 0, 0); + } + + /** + * Checks that {@link GameObjectContainer#iterator()}'s {@link + * Iterator#remove()} does work correctly. + */ + @Test + public void testIterator() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0, 0, 0); + final Iterator<GameObject> it = container1.iterator(); + it.next(); + it.remove(); + check(container1, 1, 0, 0, 0, 0); + it.next(); + it.remove(); + check(container1, 1, 0, 0, 0); + it.next(); + it.next(); + it.remove(); + check(container1, 1, 0, 0); + } + + /** + * Checks that {@link GameObjectContainer#reverse()}'s {@link + * Iterator#remove()} does work correctly. + */ + @Test + public void testReverse() { + final GameObjectCreator gameObjectCreator = new GameObjectCreator(); + final GameObjectContainer<GameObject, MapArchObject, Archetype> container1 = newContainer(gameObjectCreator, 1, 0, 0, 0, 0, 0); + final Iterator<GameObject> it= container1.reverse().iterator(); + it.next(); + it.remove(); + check(container1, 1, 0, 0, 0, 0); + it.next(); + it.remove(); + check(container1, 1, 0, 0, 0); + it.next(); + it.next(); + it.remove(); + check(container1, 1, 0, 0); + it.next(); + it.remove(); + check(container1, 1, 0); + it.next(); + it.remove(); + check(container1, 1); + Assert.assertFalse(it.hasNext()); + } + + /** + * Creates a new {@link GameObjectContainer} that contains game objects with + * the given elevation values. + * @param gameObjectCreator the game object creator to use + * @param elevations the elevations + * @return the game object container + */ + @NotNull + private static GameObjectContainer<GameObject, MapArchObject, Archetype> newContainer(@NotNull final GameObjectCreator gameObjectCreator, final int... elevations) { + final GameObjectContainer<GameObject, MapArchObject, Archetype> gameObject = gameObjectCreator.newGameObject(0); + for (final int elevation : elevations) { + gameObject.addLast(gameObjectCreator.newGameObject(elevation)); + } + return gameObject; + } + + /** + * Returns the game object at a given index. + * @param gameObjects the game objects to search + * @param index the index + * @return the game object at <code>index</code> + */ + @NotNull + private static GameObject get(@NotNull final Iterable<GameObject> gameObjects, final int index) { + int left = index; + for (final GameObject gameObject : gameObjects) { + if (left == 0) { + return gameObject; + } + left--; + } + + Assert.fail("index " + index + " not found"); + throw new AssertionError(); + } + + /** + * Checks some game objects for expected elevation values. + * @param gameObjects the game objects + * @param elevation the expected elevation value for the first game object + */ + private static void check(@NotNull final Iterable<GameObject> gameObjects, final int... elevation) { + int i = 0; + for (final GameObject gameObject : gameObjects) { + final int thisElevation = gameObject.getAttributeInt(GameObject.ELEVATION); + final int expectedElevation = i < elevation.length ? elevation[i] : 0; + Assert.assertEquals(gameObject.getBestName(), expectedElevation, thisElevation); + i++; + } + } + +} // class PropagateElevationTest Property changes on: trunk/crossfire/src/test/net/sf/gridarta/var/crossfire/model/gameobject/PropagateElevationTest.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + LF Modified: trunk/crossfire.iml =================================================================== --- trunk/crossfire.iml 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/crossfire.iml 2010-06-03 23:00:42 UTC (rev 8088) @@ -11,6 +11,9 @@ </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="gridarta" /> + <orderEntry type="module" module-name="utils" /> + <orderEntry type="module" module-name="preferences" /> <orderEntry type="module-library"> <library> <CLASSES> @@ -20,9 +23,6 @@ <SOURCES /> </library> </orderEntry> - <orderEntry type="module" module-name="gridarta" /> - <orderEntry type="module" module-name="utils" /> - <orderEntry type="module" module-name="preferences" /> <orderEntry type="module-library"> <library> <CLASSES> @@ -35,6 +35,15 @@ <orderEntry type="module-library"> <library> <CLASSES> + <root url="jar://$MODULE_DIR$/lib/junit-4.2.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> + </orderEntry> + <orderEntry type="module-library"> + <library> + <CLASSES> <root url="jar://$MODULE_DIR$/lib/jdom.jar!/" /> </CLASSES> <JAVADOC /> Modified: trunk/src/app/net/sf/gridarta/model/baseobject/GameObjectContainer.java =================================================================== --- trunk/src/app/net/sf/gridarta/model/baseobject/GameObjectContainer.java 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/src/app/net/sf/gridarta/model/baseobject/GameObjectContainer.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -139,9 +139,12 @@ public void remove() { // keep this in sync with GameObjectContainer#remove(G) // we can't simply invoke GameObjectContainer#remove(current) because that would result in a ConcurrentModificationException. - delegate.remove(); notifyBeginChange(); try { + if (contents.size() >= 2 && contents.get(0) == current) { + contents.get(1).propagateElevation(current); + } + delegate.remove(); current.setContainer(null, 0, 0); } finally { notifyEndChange(); @@ -244,12 +247,12 @@ * @fixme this implementation does not take care of multi square objects. */ public void remove(@NotNull final G gameObject) { + // keep this in sync with iterator() notifyBeginChange(); try { if (contents.size() >= 2 && contents.get(0) == gameObject) { contents.get(1).propagateElevation(gameObject); } - // keep this in sync with iterator() if (!contents.remove(gameObject)) { throw new NotInsideContainerException(this, gameObject); } @@ -473,6 +476,9 @@ int index = 0; for (final G tmpGameObject : contents) { if (tmpGameObject.getHead() == previousGameObject) { + if (index == 0) { + gameObject.propagateElevation(contents.get(0)); + } contents.add(index, gameObject); added = true; break; @@ -491,25 +497,31 @@ /** * Add a GameObject before another. * @param gameObject GameObject to insert - * @param nextGameObject nextGameObject anchor + * @param nextGameObject nextGameObject anchor or <code>null</code> to add + * first * @throws IllegalArgumentException if <var>gameObject</var> already is * inside another container or <var>prev</var> isn't inside this container */ - public void insertBefore(@NotNull final G gameObject, @NotNull final G nextGameObject) { + public void insertBefore(@NotNull final G gameObject, @Nullable final G nextGameObject) { if (gameObject.isInContainer()) { throw new IllegalArgumentException("Can't add " + gameObject + " to " + this + " because it's already inside " + gameObject.getContainer()); } + if (nextGameObject == null) { + addFirst(gameObject); + return; + } + + if (!nextGameObject.isHead()) { + throw new IllegalArgumentException(); + } + notifyBeginChange(); try { final int insertIndex = contents.indexOf(nextGameObject); if (insertIndex == -1) { throw new IllegalArgumentException("Can't insert " + gameObject + " before " + nextGameObject + " because that isn't inside " + this); } - if (insertIndex == 0) { - assert contents.size() >= 1; - gameObject.propagateElevation(contents.get(0)); - } contents.add(insertIndex + 1, gameObject); setThisContainer(gameObject); } finally { @@ -625,7 +637,7 @@ * An iterator for iterating over a list in reverse order. * @todo move this class to JAPI */ - private static class ReverseIterator<T> implements Iterator<T> { + private static class ReverseIterator<T extends GameObject<?, ?, ?>> implements Iterator<T> { /** * The iterator used for delegation. @@ -634,10 +646,17 @@ private final ListIterator<T> delegate; /** + * The list being iterated over. + */ + @NotNull + private final List<T> list; + + /** * Create a reverse iterator. * @param list to iterate over in reverse order */ private ReverseIterator(@NotNull final List<T> list) { + this.list = list; delegate = list.listIterator(list.size()); } @@ -665,6 +684,9 @@ */ @Override public void remove() { + if (delegate.nextIndex() == 0 && list.size() >= 2) { + list.get(1).propagateElevation(list.get(0)); + } delegate.remove(); } Modified: trunk/src/app/net/sf/gridarta/model/gameobject/DefaultIsoGameObject.java =================================================================== --- trunk/src/app/net/sf/gridarta/model/gameobject/DefaultIsoGameObject.java 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/src/app/net/sf/gridarta/model/gameobject/DefaultIsoGameObject.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -91,7 +91,7 @@ * {@inheritDoc} */ @Override - public void propagateElevation(@NotNull final BaseObject<G, A, R, ?> gameObject) { + public void propagateElevation(@NotNull final BaseObject<?, ?, ?, ?> gameObject) { } /** Modified: trunk/src/app/net/sf/gridarta/model/gameobject/GameObject.java =================================================================== --- trunk/src/app/net/sf/gridarta/model/gameobject/GameObject.java 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/src/app/net/sf/gridarta/model/gameobject/GameObject.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -79,7 +79,7 @@ * If there is elevation data in the other game object, move it to here. * @param gameObject the other game object */ - void propagateElevation(@NotNull BaseObject<G, A, R, ?> gameObject); + void propagateElevation(@NotNull BaseObject<?, ?, ?, ?> gameObject); /** * {@inheritDoc} The Iterator returned does not recurse, it only contains Modified: trunk/src/test/net/sf/gridarta/model/gameobject/TestGameObject.java =================================================================== --- trunk/src/test/net/sf/gridarta/model/gameobject/TestGameObject.java 2010-06-03 22:38:31 UTC (rev 8087) +++ trunk/src/test/net/sf/gridarta/model/gameobject/TestGameObject.java 2010-06-03 23:00:42 UTC (rev 8088) @@ -83,7 +83,7 @@ * {@inheritDoc} */ @Override - public void propagateElevation(@NotNull final BaseObject<TestGameObject, TestMapArchObject, TestArchetype, ?> gameObject) { + public void propagateElevation(@NotNull final BaseObject<?, ?, ?, ?> gameObject) { // ignore } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |