diff --git a/src/java/com/threerings/stage/client/StageSceneController.java b/src/java/com/threerings/stage/client/StageSceneController.java index 4e405b378..227be9154 100644 --- a/src/java/com/threerings/stage/client/StageSceneController.java +++ b/src/java/com/threerings/stage/client/StageSceneController.java @@ -3,12 +3,16 @@ package com.threerings.stage.client; +import com.samskivert.util.Tuple; + import com.threerings.crowd.client.PlaceView; import com.threerings.crowd.util.CrowdContext; import com.threerings.whirled.data.SceneUpdate; import com.threerings.whirled.spot.client.SpotSceneController; +import com.threerings.stage.Log; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.util.StageContext; /** @@ -17,6 +21,25 @@ import com.threerings.stage.util.StageContext; */ public class StageSceneController extends SpotSceneController { + /** + * Called when the user clicks on a location within the scene. + */ + public void handleLocationClicked (Object source, StageLocation loc) + { + Log.warning("handleLocationClicked(" + source + ", " + loc + ")"); + } + + /** + * Handles a cluster clicked event. + * + * @param tuple a Tuple containing (Cluster, Point) with the Cluster + * that was clicked and the Point being the screen coords of the click. + */ + public void handleClusterClicked (Object source, Tuple tuple) + { + Log.warning("handleClusterClicked(" + source + ", " + tuple + ")"); + } + // documentation inherited protected PlaceView createPlaceView (CrowdContext ctx) { diff --git a/src/java/com/threerings/stage/client/StageScenePanel.java b/src/java/com/threerings/stage/client/StageScenePanel.java index f3347f675..3f4b1d4e4 100644 --- a/src/java/com/threerings/stage/client/StageScenePanel.java +++ b/src/java/com/threerings/stage/client/StageScenePanel.java @@ -46,11 +46,14 @@ import com.threerings.crowd.client.PlaceView; import com.threerings.crowd.data.PlaceObject; import com.threerings.whirled.data.SceneUpdate; + import com.threerings.whirled.spot.data.Cluster; import com.threerings.whirled.spot.data.Location; import com.threerings.whirled.spot.data.Portal; +import com.threerings.whirled.spot.data.SceneLocation; import com.threerings.stage.Log; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageMisoSceneModel; import com.threerings.stage.data.StageScene; import com.threerings.stage.data.StageSceneModel; @@ -68,10 +71,6 @@ public class StageScenePanel extends MisoScenePanel * within the scene. */ public static final String LOCATION_CLICKED = "LocationClicked"; - /** An action command generated when something besides the user wants - * us to move to a location. */ - public static final String LOCATION_REQUESTED = "LocationRequested"; - /** An action command generated when a cluster is clicked. */ public static final String CLUSTER_CLICKED = "ClusterClicked"; @@ -163,9 +162,10 @@ public class StageScenePanel extends MisoScenePanel _portobjs.clear(); for (Iterator iter = _scene.getPortals(); iter.hasNext(); ) { Portal portal = (Portal) iter.next(); - Point p = getScreenCoords(portal.loc.x, portal.loc.y); - int tx = MisoUtil.fullToTile(portal.loc.x); - int ty = MisoUtil.fullToTile(portal.loc.y); + StageLocation loc = (StageLocation) portal.loc; + Point p = getScreenCoords(loc.x, loc.y); + int tx = MisoUtil.fullToTile(loc.x); + int ty = MisoUtil.fullToTile(loc.y); Point ts = MisoUtil.tileToScreen(_metrics, tx, ty, new Point()); // Log.info("Added portal " + portal + @@ -180,7 +180,7 @@ public class StageScenePanel extends MisoScenePanel ObjectTile tile = new PortalObjectTile( ts.x + _metrics.tilehwid - p.x + (PORTAL_ICON_WIDTH / 2), ts.y + _metrics.tilehei - p.y + (PORTAL_ICON_HEIGHT / 2)); - tile.setImage(ots.getTileMirage(portal.loc.orient)); + tile.setImage(ots.getTileMirage(loc.orient)); _portobjs.add(new SceneObject(this, info, tile) { public boolean setHovered (boolean hovered) { @@ -266,15 +266,14 @@ public class StageScenePanel extends MisoScenePanel // if the hover object is a cluster, we clicked it! if (event.getButton() == MouseEvent.BUTTON1) { if (hobject instanceof Cluster) { - int mx = event.getX(), my = event.getY(); - Object actarg = new Tuple(hobject, new Point(mx, my)); + Object actarg = new Tuple(hobject, event.getPoint()); Controller.postAction(this, CLUSTER_CLICKED, actarg); } else { // post an action indicating that we've clicked on a location Point lc = MisoUtil.screenToFull( _metrics, event.getX(), event.getY(), new Point()); Controller.postAction(this, LOCATION_CLICKED, - new Location(lc.x, lc.y, (byte)0)); + new StageLocation(lc.x, lc.y, (byte)0)); } return true; } @@ -304,10 +303,10 @@ public class StageScenePanel extends MisoScenePanel { // compute a screen rectangle that contains all possible "spots" // in this cluster - ArrayList spots = StageSceneUtil.getClusterLocs(cluster); + ArrayList spots = StageSceneUtil.getClusterLocs(cluster); Rectangle cbounds = null; for (int ii = 0, ll = spots.size(); ii < ll; ii++) { - Location loc = (Location)spots.get(ii); + StageLocation loc = ((StageLocation) spots.get(ii).loc); Point sp = getScreenCoords(loc.x, loc.y); if (cbounds == null) { cbounds = new Rectangle(sp.x, sp.y, 0, 0); @@ -482,7 +481,8 @@ public class StageScenePanel extends MisoScenePanel Iterator iter = _scene.getPortals(); while (iter.hasNext()) { Portal portal = (Portal)iter.next(); - if (portal.loc.x == fullX && portal.loc.y == fullY) { + StageLocation loc = (StageLocation) portal.loc; + if (loc.x == fullX && loc.y == fullY) { return portal; } } diff --git a/src/java/com/threerings/stage/server/StageSceneManager.java b/src/java/com/threerings/stage/server/StageSceneManager.java index 3512a06f0..c646c0c2e 100644 --- a/src/java/com/threerings/stage/server/StageSceneManager.java +++ b/src/java/com/threerings/stage/server/StageSceneManager.java @@ -37,6 +37,7 @@ import com.threerings.stage.client.StageSceneService; import com.threerings.stage.data.DefaultColorUpdate; import com.threerings.stage.data.ModifyObjectsUpdate; import com.threerings.stage.data.StageCodes; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageMisoSceneModel; import com.threerings.stage.data.StageOccupantInfo; import com.threerings.stage.data.StageScene; @@ -67,7 +68,7 @@ public class StageSceneManager extends SpotSceneManager _tloc.y = MisoUtil.toFull(y, 2); return mayStandAtLocation((BodyObject)traverser, _tloc); } - protected Location _tloc = new Location(); + protected StageLocation _tloc = new StageLocation(); }; } @@ -150,7 +151,7 @@ public class StageSceneManager extends SpotSceneManager * Called by NPPs to determine whether or not they can stand at the * specified location. */ - public boolean mayStandAtLocation (BodyObject source, Location loc) + public boolean mayStandAtLocation (BodyObject source, StageLocation loc) { return validateLocation(source, loc, false); } @@ -279,7 +280,8 @@ public class StageSceneManager extends SpotSceneManager super.updateLocation(source, loc); // keep a rectangle around for each un-clustered occupant - int tx = MisoUtil.fullToTile(loc.x), ty = MisoUtil.fullToTile(loc.y); + StageLocation sloc = (StageLocation) loc; + int tx = MisoUtil.fullToTile(sloc.x), ty = MisoUtil.fullToTile(sloc.y); _loners.put(source.getOid(), new Rectangle(tx, ty, 1, 1)); } @@ -307,8 +309,9 @@ public class StageSceneManager extends SpotSceneManager _plocs.clear(); for (Iterator iter = _sscene.getPortals(); iter.hasNext(); ) { Portal port = (Portal)iter.next(); - _plocs.add(new Point(MisoUtil.fullToTile(port.loc.x), - MisoUtil.fullToTile(port.loc.y))); + StageLocation loc = (StageLocation) port.loc; + _plocs.add(new Point(MisoUtil.fullToTile(loc.x), + MisoUtil.fullToTile(loc.y))); } } @@ -316,7 +319,7 @@ public class StageSceneManager extends SpotSceneManager * Helper function for {@link #mayStandAtLocation} and {@link * #validateLocation(BodyObject,Location)}. */ - protected boolean validateLocation (BodyObject source, Location loc, + protected boolean validateLocation (BodyObject source, StageLocation loc, boolean allowPortals) { int tx = MisoUtil.fullToTile(loc.x), ty = MisoUtil.fullToTile(loc.y); @@ -335,14 +338,16 @@ public class StageSceneManager extends SpotSceneManager } // if they are already standing on this tile, allow it - Location cloc = (Location) + SceneLocation cloc = (SceneLocation) _ssobj.occupantLocs.get(new Integer(source.getOid())); - if (cloc != null && - MisoUtil.fullToTile(cloc.x) == tx && - MisoUtil.fullToTile(cloc.y) == ty) { -// Log.info("Allowing adjust [who=" + source.who () + -// ", cloc=" + cloc + ", nloc=" + loc + "]."); - return true; + if (cloc != null) { + StageLocation sloc = (StageLocation) cloc.loc; + if (MisoUtil.fullToTile(sloc.x) == tx && + MisoUtil.fullToTile(sloc.y) == ty) { +// Log.info("Allowing adjust [who=" + source.who () + +// ", cloc=" + cloc + ", nloc=" + loc + "]."); + return true; + } } // make sure they're not standing in a cluster footprint, an @@ -393,9 +398,10 @@ public class StageSceneManager extends SpotSceneManager MisoSceneMetrics metrics = StageSceneUtil.getMetrics(); SceneLocation loc = new SceneLocation( entry.getOppLocation(), body.getOid()); - int tx = MisoUtil.fullToTile(loc.x), - ty = MisoUtil.fullToTile(loc.y); - int oidx = loc.orient/2; + StageLocation sloc = (StageLocation) loc.loc; + int tx = MisoUtil.fullToTile(sloc.x), + ty = MisoUtil.fullToTile(sloc.y); + int oidx = sloc.orient/2; int lidx = (oidx+3)%4; // rotate to the left int ridx = (oidx+1)%4; // rotate to the right @@ -409,7 +415,7 @@ public class StageSceneManager extends SpotSceneManager ty += PORTAL_DY[oidx]; // look in the center column - if (checkEntry(metrics, body, tx, ty, loc)) { + if (checkEntry(metrics, body, tx, ty, sloc)) { break LOC_SEARCH; } @@ -417,7 +423,7 @@ public class StageSceneManager extends SpotSceneManager for (int lx = tx, ly = ty, ff = 0; ff < fan; ff++) { lx += PORTAL_DX[lidx]; ly += PORTAL_DY[lidx]; - if (checkEntry(metrics, body, lx, ly, loc)) { + if (checkEntry(metrics, body, lx, ly, sloc)) { break LOC_SEARCH; } } @@ -426,7 +432,7 @@ public class StageSceneManager extends SpotSceneManager for (int rx = tx, ry = ty, ff = 0; ff < fan; ff++) { rx += PORTAL_DX[ridx]; ry += PORTAL_DY[ridx]; - if (checkEntry(metrics, body, rx, ry, loc)) { + if (checkEntry(metrics, body, rx, ry, sloc)) { break LOC_SEARCH; } } @@ -434,24 +440,25 @@ public class StageSceneManager extends SpotSceneManager // if this is our last pass and we didn't find anything, // revert back to the portal location if (fan == MAX_FAN-1) { - loc = new SceneLocation( - entry.getOppLocation(), body.getOid()); + sloc = (StageLocation) entry.getOppLocation(); } } - tx = MisoUtil.fullToTile(loc.x); - ty = MisoUtil.fullToTile(loc.y); + tx = MisoUtil.fullToTile(sloc.x); + ty = MisoUtil.fullToTile(sloc.y); _loners.put(body.getOid(), new Rectangle(tx, ty, 1, 1)); + + loc.loc = sloc; return loc; } /** Helper function for {@link #computeEnteringLocation}. */ protected boolean checkEntry (MisoSceneMetrics metrics, BodyObject body, - int tx, int ty, SceneLocation sloc) + int tx, int ty, StageLocation loc) { - sloc.x = MisoUtil.toFull(tx, metrics.finegran/2); - sloc.y = MisoUtil.toFull(ty, metrics.finegran/2); - return validateLocation(body, sloc, false); + loc.x = MisoUtil.toFull(tx, metrics.finegran/2); + loc.y = MisoUtil.toFull(ty, metrics.finegran/2); + return validateLocation(body, loc, false); } // documentation inherited @@ -459,7 +466,7 @@ public class StageSceneManager extends SpotSceneManager { // TODO: make sure the user isn't warping to hell and gone (and if // they are, make sure they're an admin) - return validateLocation(source, loc, true); + return validateLocation(source, (StageLocation)loc, true); } // documentation inherited @@ -653,14 +660,15 @@ public class StageSceneManager extends SpotSceneManager // if we're adding our first player, assign initial dimensions // to the cluster cl.width = 1; cl.height = 1; - Location loc = locationForBody(bodyOid); + SceneLocation loc = locationForBody(bodyOid); if (loc == null) { Log.warning("Foreign body added to cluster [clrec=" + clrec + ", body=" + body.who() + "]."); cl.x = 10; cl.y = 10; } else { - cl.x = MisoUtil.fullToTile(loc.x); - cl.y = MisoUtil.fullToTile(loc.y); + StageLocation sloc = (StageLocation) loc.loc; + cl.x = MisoUtil.fullToTile(sloc.x); + cl.y = MisoUtil.fullToTile(sloc.y); } // we'll do everything else when occupant two shows up return; @@ -703,7 +711,7 @@ public class StageSceneManager extends SpotSceneManager // Log.info("Maybe moving " + bodyOid + " from " + sloc + // " to " + cloc + // " (avail=" + StringUtil.toString(locs) + ")."); - if (cloc != null && !cloc.equivalent(sloc)) { + if (cloc != null && !cloc.loc.equivalent(sloc.loc)) { cloc.bodyOid = bodyOid; // Log.info("Moving " + bodyOid + " to " + cloc + // " for " + cl + "."); @@ -771,14 +779,16 @@ public class StageSceneManager extends SpotSceneManager * supplied location. */ protected static SceneLocation getClosestLoc ( - ArrayList locs, SceneLocation loc) + ArrayList locs, SceneLocation optimalLocation) { + StageLocation loc = (StageLocation) optimalLocation.loc; SceneLocation cloc = null; float cdist = Integer.MAX_VALUE; int cidx = -1; for (int ii = 0, ll = locs.size(); ii < ll; ii++) { SceneLocation tloc = (SceneLocation)locs.get(ii); - float tdist = MathUtil.distance(loc.x, loc.y, tloc.x, tloc.y); + StageLocation sl = (StageLocation) tloc.loc; + float tdist = MathUtil.distance(loc.x, loc.y, sl.x, sl.y); if (tdist < cdist) { cloc = tloc; cdist = tdist; diff --git a/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java b/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java index 6d7c0e57e..969d727bb 100644 --- a/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java +++ b/src/java/com/threerings/stage/tools/editor/EditorScenePanel.java @@ -51,6 +51,7 @@ import com.threerings.miso.data.ObjectInfo; import com.threerings.miso.util.MisoUtil; import com.threerings.stage.client.StageScenePanel; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageMisoSceneModel; import com.threerings.stage.data.StageScene; @@ -888,15 +889,16 @@ public class EditorScenePanel extends StageScenePanel protected void paintPortal (Graphics2D gfx, EditablePortal port) { // get the portal's center coordinate + StageLocation loc = (StageLocation) port.loc; Point spos = new Point(); - MisoUtil.fullToScreen(_metrics, port.loc.x, port.loc.y, spos); + MisoUtil.fullToScreen(_metrics, loc.x, loc.y, spos); int cx = spos.x, cy = spos.y; // translate the origin to center on the portal gfx.translate(cx, cy); // rotate to reflect the portal orientation - double rot = (Math.PI / 4.0f) * port.loc.orient; + double rot = (Math.PI / 4.0f) * loc.orient; gfx.rotate(rot); // draw the triangle diff --git a/src/java/com/threerings/stage/tools/editor/PortalTool.java b/src/java/com/threerings/stage/tools/editor/PortalTool.java index f13ee6306..ce87e623e 100644 --- a/src/java/com/threerings/stage/tools/editor/PortalTool.java +++ b/src/java/com/threerings/stage/tools/editor/PortalTool.java @@ -17,6 +17,7 @@ import com.threerings.util.DirectionUtil; import com.threerings.whirled.spot.data.Location; import com.threerings.whirled.spot.tools.EditablePortal; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageScene; import com.threerings.stage.tools.editor.util.ExtrasPainter; @@ -37,7 +38,7 @@ public class PortalTool extends MouseInputAdapter // configure the portal with these full coordinates _portal = new EditablePortal(); - _portal.loc = new Location(p.x, p.y, (byte)DirectionCodes.NORTH); + _portal.loc = new StageLocation(p.x, p.y, (byte)DirectionCodes.NORTH); // we want to listen to drags and clicks _panel.addMouseListener(this); @@ -99,8 +100,9 @@ public class PortalTool extends MouseInputAdapter } // if our orientation changed, repaint - if (norient != _portal.loc.orient) { - _portal.loc.orient = (byte)norient; + StageLocation loc = (StageLocation) _portal.loc; + if (norient != loc.orient) { + loc.orient = (byte)norient; _panel.repaint(); } } @@ -111,8 +113,8 @@ public class PortalTool extends MouseInputAdapter protected void savePortal () { // try to come up with a reasonable name - String dirname = - DirectionUtil.toString(_portal.loc.orient).toLowerCase(); + byte orient = ((StageLocation) _portal.loc).orient; + String dirname = DirectionUtil.toString(orient).toLowerCase(); String name = dirname; for (int ii=1; portalNameExists(name); ii++) { name = dirname + ii; diff --git a/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java b/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java index 97a36879c..eb0283ebd 100644 --- a/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java +++ b/src/java/com/threerings/stage/tools/viewer/ViewerScenePanel.java @@ -31,6 +31,7 @@ import com.threerings.stage.client.StageScenePanel; import com.threerings.whirled.spot.data.Location; import com.threerings.stage.Log; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageScene; import com.threerings.stage.util.StageContext; @@ -66,8 +67,8 @@ public class ViewerScenePanel extends StageScenePanel setScene(scene); // move all of our sprites to the default entrance - _defloc = defloc; - Point defpos = getScreenCoords(defloc.x, defloc.y); + _defloc = (StageLocation) defloc; + Point defpos = getScreenCoords(_defloc.x, _defloc.y); _sprite.setLocation(defpos.x, defpos.y); if (_decoys != null) { @@ -220,7 +221,7 @@ public class ViewerScenePanel extends StageScenePanel protected static final int DEFAULT_NUM_DECOYS = 10; /** The current scene's default entrance. */ - protected Location _defloc; + protected StageLocation _defloc; /** Provides character sprite data. */ protected CharacterManager _charmgr; diff --git a/src/java/com/threerings/stage/tools/xml/StageSceneParser.java b/src/java/com/threerings/stage/tools/xml/StageSceneParser.java index 7a3936286..54fed8262 100644 --- a/src/java/com/threerings/stage/tools/xml/StageSceneParser.java +++ b/src/java/com/threerings/stage/tools/xml/StageSceneParser.java @@ -11,6 +11,9 @@ import com.threerings.whirled.spot.tools.xml.SpotSceneRuleSet; import com.threerings.whirled.tools.xml.SceneParser; import com.threerings.whirled.tools.xml.SceneRuleSet; +import com.threerings.whirled.spot.data.Location; + +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageSceneModel; /** @@ -37,7 +40,11 @@ public class StageSceneParser extends SceneParser }); // add rule sets for our aux scene models - registerAuxRuleSet(new SpotSceneRuleSet()); + registerAuxRuleSet(new SpotSceneRuleSet() { + protected Location createLocation () { + return new StageLocation(); + } + }); registerAuxRuleSet(new StageMisoSceneRuleSet()); } diff --git a/src/java/com/threerings/stage/util/StageSceneUtil.java b/src/java/com/threerings/stage/util/StageSceneUtil.java index 3b4db7e28..79ef83e02 100644 --- a/src/java/com/threerings/stage/util/StageSceneUtil.java +++ b/src/java/com/threerings/stage/util/StageSceneUtil.java @@ -31,6 +31,7 @@ import com.threerings.whirled.spot.data.Location; import com.threerings.whirled.spot.data.SceneLocation; import com.threerings.stage.Log; +import com.threerings.stage.data.StageLocation; import com.threerings.stage.data.StageMisoSceneModel; import com.threerings.stage.data.StageSceneModel; @@ -51,7 +52,7 @@ public class StageSceneUtil * Does the necessary jiggery pokery to figure out where the specified * object's associated location is. */ - public static Location locationForObject ( + public static StageLocation locationForObject ( TileManager tilemgr, ObjectInfo info) { return locationForObject(tilemgr, info.tileId, info.x, info.y); @@ -67,7 +68,7 @@ public class StageSceneUtil * @param tx the object's x tile coordinate. * @param ty the object's y tile coordinate. */ - public static Location locationForObject ( + public static StageLocation locationForObject ( TileManager tilemgr, int tileId, int tx, int ty) { try { @@ -89,7 +90,8 @@ public class StageSceneUtil // ", sy=" + tset.getYSpot(tidx) + // ", lx=" + opos.x + ", ly=" + opos.y + // ", fg=" + _metrics.finegran + "]."); - return new Location(opos.x, opos.y, (byte)tset.getSpotOrient(tidx)); + return new StageLocation(opos.x, opos.y, + (byte)tset.getSpotOrient(tidx)); } catch (Exception e) { Log.warning("Unable to look up object tile for scene object " + @@ -189,9 +191,9 @@ public class StageSceneUtil /** * Computes a list of the valid locations in this cluster. */ - public static ArrayList getClusterLocs (Cluster cluster) + public static ArrayList getClusterLocs (Cluster cluster) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); // convert our tile coordinates into a cartesian coordinate system // with units equal to one fine coordinate in size @@ -204,9 +206,10 @@ public class StageSceneUtil // if it's a 1x1 cluster, return one location in the center of the // cluster if (cluster.width == 1) { - list.add(new SceneLocation(MisoUtil.toFull(cluster.x, 2), - MisoUtil.toFull(cluster.y, 2), - (byte)DirectionCodes.SOUTHWEST, 0)); + StageLocation loc = new StageLocation( + MisoUtil.toFull(cluster.x, 2), MisoUtil.toFull(cluster.y, 2), + (byte)DirectionCodes.SOUTHWEST); + list.add(new SceneLocation(loc, 0)); return list; } @@ -233,7 +236,8 @@ public class StageSceneUtil sx = MisoUtil.toFull(tx, sx-(tx*_metrics.finegran)); int ty = MathUtil.floorDiv(sy, _metrics.finegran); sy = MisoUtil.toFull(ty, sy-(ty*_metrics.finegran)); - list.add(new SceneLocation(sx, sy, (byte)orient, 0)); + StageLocation loc = new StageLocation(sx, sy, (byte) orient); + list.add(new SceneLocation(loc, 0)); } return list; @@ -279,7 +283,7 @@ public class StageSceneUtil * * @return the closest spot to the */ - public static Location findStandingSpot ( + public static StageLocation findStandingSpot ( Rectangle foot, int dist, AStarPathUtil.TraversalPred pred, Object traverser, final Point nearto, int orient) { @@ -292,28 +296,36 @@ public class StageSceneUtil int xx1 = foot.x-dd, xx2 = foot.x+foot.width+dd-1; // get the corners - spots.add(new Location(xx1, yy1, (byte)DirectionCodes.SOUTHWEST)); - spots.add(new Location(xx1, yy2, (byte)DirectionCodes.SOUTHEAST)); - spots.add(new Location(xx2, yy1, (byte)DirectionCodes.NORTHWEST)); - spots.add(new Location(xx2, yy2, (byte)DirectionCodes.NORTHEAST)); + spots.add( + new StageLocation(xx1, yy1, (byte)DirectionCodes.SOUTHWEST)); + spots.add( + new StageLocation(xx1, yy2, (byte)DirectionCodes.SOUTHEAST)); + spots.add( + new StageLocation(xx2, yy1, (byte)DirectionCodes.NORTHWEST)); + spots.add( + new StageLocation(xx2, yy2, (byte)DirectionCodes.NORTHEAST)); // then the sides for (int xx = xx1+1; xx < xx2; xx++) { - spots.add(new Location(xx, yy1, (byte)DirectionCodes.WEST)); - spots.add(new Location(xx, yy2, (byte)DirectionCodes.EAST)); + spots.add( + new StageLocation(xx, yy1, (byte)DirectionCodes.WEST)); + spots.add( + new StageLocation(xx, yy2, (byte)DirectionCodes.EAST)); } for (int yy = yy1+1; yy < yy2; yy++) { - spots.add(new Location(xx1, yy, (byte)DirectionCodes.SOUTH)); - spots.add(new Location(xx2, yy, (byte)DirectionCodes.NORTH)); + spots.add( + new StageLocation(xx1, yy, (byte)DirectionCodes.SOUTH)); + spots.add( + new StageLocation(xx2, yy, (byte)DirectionCodes.NORTH)); } // sort them in order of closeness to the players current // coordinate spots.sort(new Comparator() { public int compare (Object o1, Object o2) { - return dist((Location)o1) - dist((Location)o2); + return dist((StageLocation)o1) - dist((StageLocation)o2); } - private final int dist (Location l) { + private final int dist (StageLocation l) { return Math.round(100*MathUtil.distance( l.x, l.y, nearto.x, nearto.y)); } @@ -322,7 +334,7 @@ public class StageSceneUtil // return the first spot that can be "traversed" which we're // taking to mean "stood upon" for (int ii = 0, ll = spots.size(); ii < ll; ii++) { - Location loc = (Location)spots.get(ii); + StageLocation loc = (StageLocation)spots.get(ii); if (pred.canTraverse(traverser, loc.x, loc.y)) { // convert to full coordinates loc.x = MisoUtil.toFull(loc.x, 2); diff --git a/src/java/com/threerings/whirled/spot/data/Location.java b/src/java/com/threerings/whirled/spot/data/Location.java index 29da53679..6804bd1fc 100644 --- a/src/java/com/threerings/whirled/spot/data/Location.java +++ b/src/java/com/threerings/whirled/spot/data/Location.java @@ -1,112 +1,34 @@ -// -// $Id$ -// -// Narya library - tools for developing networked games -// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved -// http://www.threerings.net/code/narya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - package com.threerings.whirled.spot.data; -import com.threerings.io.SimpleStreamableObject; -import com.threerings.util.DirectionCodes; -import com.threerings.util.DirectionUtil; +import com.threerings.io.Streamable; -/** - * Contains information on a scene occupant's position and orientation. - */ -public class Location extends SimpleStreamableObject - implements Cloneable +public interface Location extends Streamable, Cloneable { - /** The user's x position (interpreted by the display system). */ - public int x; - - /** The user's y position (interpreted by the display system). */ - public int y; - - /** The user's orientation (defined by {@link DirectionCodes}). */ - public byte orient; - - /** {@link #toString} helper function. */ - public String orientToString () - { - return DirectionUtil.toShortString(orient); - } + /** + * Get a new Location instance that is equals() to this one but that + * has an orientation facing the opposite direction. + */ + public Location getOpposite (); /** - * A zero-argument constructor used when unserializing instances. + * Two locations are equivalent if they specify the same location + * and orientation. */ - public Location () - { - } + public boolean equivalent (Location other); /** - * Constructs a location with the specified coordinates and - * orientation. + * Two locations are equals if they specify the same coordinates, but + * the orientation may be different. */ - public Location (int x, int y, byte orient) - { - this.x = x; - this.y = y; - this.orient = orient; - - if (orient == -1) { - Thread.dumpStack(); - } - } + public boolean equals (Object other); /** - * Creates a clone of this instance. + * The hashcode of a Location should be based only on its coordinates. */ - public Object clone () - { - try { - return (Location)super.clone(); - } catch (CloneNotSupportedException cnse) { - throw new RuntimeException("Location.clone() failed " + cnse); - } - } + public int hashCode (); /** - * Location equality is determined by coordinates. + * Locations are cloneable. */ - public boolean equals (Object other) - { - if (other instanceof Location) { - Location oloc = (Location)other; - return (x == oloc.x) && (y == oloc.y); - } else { - return false; - } - } - - /** - * Location equivalence means that the coordinates and orientation are - * the same. - */ - public boolean equivalent (Location oloc) - { - return equals(oloc) && (orient == oloc.orient); - } - - /** - * Computes a reasonable hashcode for location instances. - */ - public int hashCode () - { - return x ^ y; - } + public Object clone (); } diff --git a/src/java/com/threerings/whirled/spot/data/Portal.java b/src/java/com/threerings/whirled/spot/data/Portal.java index 45b2bc33c..44b9ac860 100644 --- a/src/java/com/threerings/whirled/spot/data/Portal.java +++ b/src/java/com/threerings/whirled/spot/data/Portal.java @@ -22,7 +22,6 @@ package com.threerings.whirled.spot.data; import com.threerings.io.SimpleStreamableObject; -import com.threerings.util.DirectionUtil; /** * Represents an exit to another scene. A body sprite would walk over to a @@ -39,9 +38,8 @@ public class Portal extends SimpleStreamableObject /** This portal's unique identifier. */ public short portalId; - /** The location of the portal. Typically this is a base Location (2d) - * class, but different games could use a different subclass of - * Location. */ + /** The location of the portal. + * This field is present on client and server, it is streamed specially. */ public Location loc; /** The scene identifier of the scene to which a body will exit when @@ -70,9 +68,7 @@ public class Portal extends SimpleStreamableObject */ public Location getOppLocation () { - Location oppLoc = getLocation(); - oppLoc.orient = (byte) DirectionUtil.getOpposite(oppLoc.orient); - return oppLoc; + return loc.getOpposite(); } /** @@ -102,12 +98,8 @@ public class Portal extends SimpleStreamableObject */ public boolean equals (Object other) { - if (other instanceof Portal) { - Portal oport = (Portal)other; - return portalId == oport.portalId; - } else { - return false; - } + return (other instanceof Portal) && + ((Portal) other).portalId == portalId; } /** diff --git a/src/java/com/threerings/whirled/spot/data/SceneLocation.java b/src/java/com/threerings/whirled/spot/data/SceneLocation.java index e3d39c007..47aa3afec 100644 --- a/src/java/com/threerings/whirled/spot/data/SceneLocation.java +++ b/src/java/com/threerings/whirled/spot/data/SceneLocation.java @@ -21,33 +21,29 @@ package com.threerings.whirled.spot.data; +import com.threerings.io.SimpleStreamableObject; + import com.threerings.presents.dobj.DSet; /** * Extends {@link Location} with the data and functionality needed to * represent a particular user's location in a scene. */ -public class SceneLocation extends Location +public class SceneLocation extends SimpleStreamableObject implements DSet.Entry { /** The oid of the body that occupies this location. */ public int bodyOid; - /** - * Creates a scene location with the specified information. - */ - public SceneLocation (int x, int y, byte orient, int bodyOid) - { - super(x, y, orient); - this.bodyOid = bodyOid; - } + /** The actual location, which is interpreted by the display system. */ + public Location loc; /** * Creates a scene location with the specified information. */ public SceneLocation (Location loc, int bodyOid) { - super(loc.x, loc.y, loc.orient); + this.loc = loc; this.bodyOid = bodyOid; } @@ -67,6 +63,26 @@ public class SceneLocation extends Location return _key; } + // documentation inherited + public boolean equals (Object other) + { + // TEMP + if (other instanceof Location) { + Thread.dumpStack(); // this will help us find logic errors, + // as a SceneLocation and a Location shouldn't be compared + } + // END: temp + + return (other instanceof SceneLocation) && + this.loc.equals(((SceneLocation) other).loc); + } + + // documentation inherited + public int hashCode () + { + return loc.hashCode(); + } + /** Used for {@link #getKey}. */ protected transient Integer _key; } diff --git a/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneRuleSet.java b/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneRuleSet.java index ed4a7846b..eaa59811d 100644 --- a/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneRuleSet.java +++ b/src/java/com/threerings/whirled/spot/tools/xml/SpotSceneRuleSet.java @@ -43,7 +43,7 @@ import com.threerings.whirled.spot.tools.EditablePortal; /** * Used to parse a {@link SpotSceneModel} from XML. */ -public class SpotSceneRuleSet implements NestableRuleSet +public abstract class SpotSceneRuleSet implements NestableRuleSet { // documentation inherited from interface public String getOuterElement () @@ -70,10 +70,7 @@ public class SpotSceneRuleSet implements NestableRuleSet * Create a new instance of the Location class that should be used * with Portals. */ - protected Location createNewLocation () - { - return new Location(); - } + protected abstract Location createLocation (); /** * A rule used to create the portal but also initialize the Location @@ -95,7 +92,7 @@ public class SpotSceneRuleSet implements NestableRuleSet // create the empty Location in the Portal Portal p = (Portal) digester.peek(); - p.loc = _ruleset.createNewLocation(); + p.loc = _ruleset.createLocation(); } protected SpotSceneRuleSet _ruleset;