diff --git a/src/java/com/threerings/media/image/ColorPository.java b/src/java/com/threerings/media/image/ColorPository.java new file mode 100644 index 000000000..916fa39cf --- /dev/null +++ b/src/java/com/threerings/media/image/ColorPository.java @@ -0,0 +1,377 @@ +// +// $Id: ColorPository.java,v 1.1 2003/01/31 23:10:45 mdb Exp $ + +package com.threerings.media.image; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Iterator; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + +import com.threerings.media.Log; +import com.threerings.resource.ResourceManager; +import com.threerings.util.CompiledConfig; +import com.threerings.util.RandomUtil; + +/** + * A repository of image recoloration information. It was called the + * recolor repository but the re-s cancelled one another out. + */ +public class ColorPository implements Serializable +{ + /** + * Used to store information on a class of colors. These are public to + * simplify the XML parsing process, so pay them no mind. + */ + public static class ClassRecord implements Serializable + { + /** An integer identifier for this class. */ + public int classId; + + /** The name of the color class. */ + public String name; + + /** The source color to use when recoloring colors in this class. */ + public Color source; + + /** Data identifying the range of colors around the source color + * that will be recolored when recoloring using this class. */ + public float[] range; + + /** The default starting legality value for this color class. See + * {@link ColorRecord#starter}. */ + public boolean starter; + + /** A table of target colors included in this class. */ + public HashIntMap colors = new HashIntMap(); + + /** Used when parsing the color definitions. */ + public void addColor (ColorRecord record) + { + // validate the color id + if (record.colorId > 255) { + Log.warning("Refusing to add color record; colorId > 255 " + + "[class=" + this + ", record=" + record + "]."); + } else { + record.cclass = this; + colors.put(record.colorId, record); + } + } + + /** Returns a random starting id from the entries in this + * class. */ + public ColorRecord randomStartingColor () + { + // figure out our starter ids if we haven't already + if (_starters == null) { + ArrayList list = new ArrayList(); + Iterator iter = colors.values().iterator(); + while (iter.hasNext()) { + ColorRecord color = (ColorRecord)iter.next(); + if (color.starter) { + list.add(color); + } + } + _starters = (ColorRecord[]) + list.toArray(new ColorRecord[list.size()]); + } + + // return a random entry from the array + return _starters[RandomUtil.getInt(_starters.length)]; + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + return "[id=" + classId + ", name=" + name + ", source=#" + + Integer.toString(source.getRGB() & 0xFFFFFF, 16) + + ", range=" + StringUtil.toString(range) + + ", starter=" + starter + ", colors=" + + StringUtil.toString(colors.values().iterator()) + "]"; + } + + protected transient ColorRecord[] _starters; + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } + + /** + * Used to store information on a particular color. These are public + * to simplify the XML parsing process, so pay them no mind. + */ + public static class ColorRecord implements Serializable + { + /** The colorization class to which we belong. */ + public ClassRecord cclass; + + /** A unique colorization identifier (used in fingerprints). */ + public int colorId; + + /** The name of the target color. */ + public String name; + + /** Data indicating the offset (in HSV color space) from the + * source color to recolor to this color. */ + public float[] offsets; + + /** Tags this color as a legal starting color or not. This is a + * shameful copout, placing application-specific functionality + * into a general purpose library class. */ + public boolean starter; + + /** + * Returns a value that is the composite of our class id and color + * id which can be used to identify a colorization record. This + * value will always be a positive integer that fits into 16 bits. + */ + public int getColorPrint () + { + return ((cclass.classId << 8) | colorId); + } + + /** + * Returns the data in this record configured as a colorization + * instance. + */ + public Colorization getColorization () + { + return new Colorization(getColorPrint(), cclass.source, + cclass.range, offsets); + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + return "[id=" + colorId + ", name=" + name + + ", offsets=" + StringUtil.toString(offsets) + + ", starter=" + starter + "]"; + } + + /** Increase this value when object's serialized state is impacted + * by a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 2; + } + + /** + * Returns an iterator over all color classes in this pository. + */ + public Iterator enumerateClasses () + { + return _classes.values().iterator(); + } + + /** + * Returns an array containing the records for the colors in the + * specified class. + */ + public ColorRecord[] enumerateColors (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + if (record == null) { + return null; + } + + // create the array + ColorRecord[] crecs = new ColorRecord[record.colors.size()]; + Iterator iter = record.colors.values().iterator(); + for (int i = 0; iter.hasNext(); i++) { + crecs[i] = ((ColorRecord)iter.next()); + } + return crecs; + } + + /** + * Returns an array containing the ids of the colors in the specified + * class. + */ + public int[] enumerateColorIds (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + if (record == null) { + return null; + } + + int[] cids = new int[record.colors.size()]; + Iterator crecs = record.colors.values().iterator(); + for (int i = 0; crecs.hasNext(); i++) { + cids[i] = ((ColorRecord)crecs.next()).colorId; + } + return cids; + } + + /** + * Returns true if the specified color is legal for use at character + * creation time. false is always returned for non-existent colors or + * classes. + */ + public boolean isLegalStartColor (int classId, int colorId) + { + ColorRecord color = getColorRecord(classId, colorId); + return (color == null) ? false : color.starter; + } + + /** + * Returns a random starting color from the specified color class. + */ + public ColorRecord getRandomStartingColor (String className) + { + // make sure the class exists + ClassRecord record = getClassRecord(className); + return (record == null) ? null : record.randomStartingColor(); + } + + /** + * Looks up a colorization by id. + */ + public Colorization getColorization (int classId, int colorId) + { + ColorRecord color = getColorRecord(classId, colorId); + return (color == null) ? null : color.getColorization(); + } + + /** + * Looks up a colorization by color print. + */ + public Colorization getColorization (int colorPrint) + { + return getColorization(colorPrint >> 8, colorPrint & 0xFF); + } + + /** + * Looks up a colorization by name. + */ + public Colorization getColorization (String className, int colorId) + { + ClassRecord crec = getClassRecord(className); + if (crec != null) { + ColorRecord color = (ColorRecord)crec.colors.get(colorId); + if (color != null) { + color.getColorization(); + } + } + return null; + } + + /** + * Loads up a colorization class by name and logs a warning if it + * doesn't exist. + */ + public ClassRecord getClassRecord (String className) + { + Iterator iter = _classes.values().iterator(); + while (iter.hasNext()) { + ClassRecord crec = (ClassRecord)iter.next(); + if (crec.name.equals(className)) { + return crec; + } + } + Log.warning("No such color class [class=" + className + "]."); + Thread.dumpStack(); + return null; + } + + /** + * Looks up the requested color record. + */ + protected ColorRecord getColorRecord (int classId, int colorId) + { + ClassRecord record = (ClassRecord)_classes.get(classId); + if (record == null) { + // if they request color class zero, we assume they're just + // decoding a blank colorprint, otherwise we complain + if (classId != 0) { + Log.warning("Requested unknown color class " + + "[classId=" + classId + + ", colorId=" + colorId + "]."); + Thread.dumpStack(); + } + return null; + } + return (ColorRecord)record.colors.get(colorId); + } + + /** + * Adds a fully configured color class record to the pository. This is + * only called by the XML parsing code, so pay it no mind. + */ + public void addClass (ClassRecord record) + { + // validate the class id + if (record.classId > 255) { + Log.warning("Refusing to add class; classId > 255 " + record + "."); + } else { + _classes.put(record.classId, record); + } + } + + /** + * Loads up a serialized color pository from the supplied resource + * manager. + */ + public static ColorPository loadColorPository (ResourceManager rmgr) + { + try { + return loadColorPository(rmgr.getResource(CONFIG_PATH)); + } catch (IOException ioe) { + Log.warning("Failure loading color pository [path=" + CONFIG_PATH + + ", error=" + ioe + "]."); + return new ColorPository(); + } + } + + /** + * Loads up a serialized color pository from the supplied resource + * manager. + */ + public static ColorPository loadColorPository (InputStream source) + { + try { + return (ColorPository)CompiledConfig.loadConfig(source); + } catch (IOException ioe) { + Log.warning("Failure loading color pository: " + ioe + "."); + return new ColorPository(); + } + } + + /** + * Serializes and saves color pository to the supplied file. + */ + public static void saveColorPository (ColorPository posit, File root) + { + File path = new File(root, CONFIG_PATH); + try { + CompiledConfig.saveConfig(path, posit); + } catch (IOException ioe) { + Log.warning("Failure saving color pository " + + "[path=" + path + ", error=" + ioe + "]."); + } + } + + /** Our mapping from class names to class records. */ + protected HashIntMap _classes = new HashIntMap(); + + /** Increase this value when object's serialized state is impacted by + * a class change (modification of fields, inheritance). */ + private static final long serialVersionUID = 1; + + /** + * The path (relative to the resource directory) at which the + * serialized recolorization repository should be loaded and stored. + */ + protected static final String CONFIG_PATH = "config/media/colordefs.dat"; +} diff --git a/src/java/com/threerings/media/image/tools/DumpColorPository.java b/src/java/com/threerings/media/image/tools/DumpColorPository.java new file mode 100644 index 000000000..88003eb9c --- /dev/null +++ b/src/java/com/threerings/media/image/tools/DumpColorPository.java @@ -0,0 +1,36 @@ +// +// $Id: DumpColorPository.java,v 1.1 2003/01/31 23:10:45 mdb Exp $ + +package com.threerings.media.image.tools; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Iterator; + +import com.threerings.media.image.ColorPository; + +/** + * Simple tool for dumping a serialized color pository. + */ +public class DumpColorPository +{ + public static void main (String[] args) + { + if (args.length == 0) { + System.err.println("Usage: DumpColorPository colorpos.dat"); + System.exit(-1); + } + + try { + ColorPository pos = ColorPository.loadColorPository( + new FileInputStream(args[0])); + Iterator iter = pos.enumerateClasses(); + while (iter.hasNext()) { + System.out.println(iter.next()); + } + + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } + } +} diff --git a/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java b/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java new file mode 100644 index 000000000..c6b110935 --- /dev/null +++ b/src/java/com/threerings/media/image/tools/xml/ColorPositoryParser.java @@ -0,0 +1,59 @@ +// +// $Id: ColorPositoryParser.java,v 1.1 2003/01/31 23:10:45 mdb Exp $ + +package com.threerings.media.image.tools.xml; + +import java.io.Serializable; + +import org.xml.sax.Attributes; +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.Rule; +import com.samskivert.xml.SetPropertyFieldsRule; + +import com.threerings.tools.xml.CompiledConfigParser; + +import com.threerings.media.image.ColorPository.ClassRecord; +import com.threerings.media.image.ColorPository.ColorRecord; +import com.threerings.media.image.ColorPository; + +/** + * Parses the XML color repository definition and creates a {@link + * ColorPository} instance that reflects its contents. + */ +public class ColorPositoryParser extends CompiledConfigParser +{ + // documentation inherited + protected Serializable createConfigObject () + { + return new ColorPository(); + } + + // documentation inherited + protected void addRules (Digester digest) + { + // create and configure class record instances + String prefix = "colors/class"; + digest.addObjectCreate(prefix, ClassRecord.class.getName()); + digest.addRule(prefix, new SetPropertyFieldsRule(digest)); + digest.addSetNext(prefix, "addClass", ClassRecord.class.getName()); + + // create and configure color record instances + prefix += "/color"; + digest.addRule(prefix, new Rule(digest) { + public void begin (Attributes attributes) throws Exception { + // we want to inherit settings from the color class when + // creating the record, so we do some custom stuff + ColorRecord record = new ColorRecord(); + ClassRecord clrec = (ClassRecord)digester.peek(); + record.starter = clrec.starter; + digester.push(record); + } + + public void end () throws Exception { + digester.pop(); + } + }); + digest.addRule(prefix, new SetPropertyFieldsRule(digest)); + digest.addSetNext(prefix, "addColor", ColorRecord.class.getName()); + } +} diff --git a/src/java/com/threerings/miso/client/DirtyItemList.java b/src/java/com/threerings/miso/client/DirtyItemList.java index de9435eed..2e1d5f029 100644 --- a/src/java/com/threerings/miso/client/DirtyItemList.java +++ b/src/java/com/threerings/miso/client/DirtyItemList.java @@ -1,7 +1,7 @@ // -// $Id: DirtyItemList.java,v 1.17 2002/10/16 01:53:10 ray Exp $ +// $Id: DirtyItemList.java,v 1.18 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Color; import java.awt.Graphics2D; @@ -17,7 +17,7 @@ import com.samskivert.util.StringUtil; import com.threerings.media.Log; import com.threerings.media.sprite.Sprite; import com.threerings.media.tile.ObjectTile; -import com.threerings.miso.scene.util.IsoUtil; +import com.threerings.miso.client.util.IsoUtil; /** * The dirty item list keeps track of dirty sprites and object tiles @@ -48,10 +48,10 @@ public class DirtyItemList * @param footprint the footprint of the object tile if it should be * rendered, null otherwise. */ - public void appendDirtyObject (SceneObject scobj, Shape footprint) + public void appendDirtyObject (DisplayObjectInfo info, Shape footprint) { DirtyItem item = getDirtyItem(); - item.init(scobj, scobj.bounds, footprint, scobj.x, scobj.y); + item.init(info, info.bounds, footprint, info.x, info.y); _items.add(item); } @@ -234,8 +234,8 @@ public class DirtyItemList // rightmost tiles are equivalent lx = rx = ox; ly = ry = oy; - if (obj instanceof SceneObject) { - ObjectTile tile = ((SceneObject)obj).tile; + if (obj instanceof DisplayObjectInfo) { + ObjectTile tile = ((DisplayObjectInfo)obj).tile; lx -= (tile.getBaseWidth() - 1); ry -= (tile.getBaseHeight() - 1); } @@ -258,7 +258,7 @@ public class DirtyItemList if (obj instanceof Sprite) { ((Sprite)obj).paint(gfx); } else { - ((SceneObject)obj).tile.paint(gfx, bounds.x, bounds.y); + ((DisplayObjectInfo)obj).tile.paint(gfx, bounds.x, bounds.y); } } @@ -289,7 +289,7 @@ public class DirtyItemList // } // // objects are equivalent if they are the same object -// if ((obj instanceof SceneObject) && (b.obj instanceof SceneObject)) { +// if ((obj instanceof DisplayObjectInfo) && (b.obj instanceof DisplayObjectInfo)) { // return (obj == b.obj); // } @@ -534,10 +534,10 @@ public class DirtyItemList // priority scene; this allows us to avoid all sorts of sticky // business wherein the render order between two overlapping // objects cannot be determined without a z-buffer - if ((da.obj instanceof SceneObject) && - (db.obj instanceof SceneObject)) { - SceneObject soa = (SceneObject)da.obj; - SceneObject sob = (SceneObject)db.obj; + if ((da.obj instanceof DisplayObjectInfo) && + (db.obj instanceof DisplayObjectInfo)) { + DisplayObjectInfo soa = (DisplayObjectInfo)da.obj; + DisplayObjectInfo sob = (DisplayObjectInfo)db.obj; if (IsoUtil.objectFootprintsOverlap(soa, sob)) { return (soa.priority - sob.priority); } diff --git a/src/java/com/threerings/miso/client/DisplayMisoScene.java b/src/java/com/threerings/miso/client/DisplayMisoScene.java index e685a2af3..64e4fb545 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoScene.java +++ b/src/java/com/threerings/miso/client/DisplayMisoScene.java @@ -1,14 +1,14 @@ // -// $Id: DisplayMisoScene.java,v 1.8 2003/01/13 22:53:56 mdb Exp $ +// $Id: DisplayMisoScene.java,v 1.9 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Rectangle; import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.Tile; -import com.threerings.miso.scene.util.ObjectSet; +import com.threerings.miso.client.util.ObjectSet; import com.threerings.miso.tile.BaseTile; /** @@ -30,10 +30,10 @@ public interface DisplayMisoScene public Tile getFringeTile (int x, int y); /** - * Populates the supplied scene object set with all objects whose + * Populates the supplied object set with info on all objects whose * origin falls in the requested region. */ - public void getSceneObjects (Rectangle region, ObjectSet set); + public void getObjects (Rectangle region, ObjectSet set); /** * Returns true if the supplied traverser can traverse the specified diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 289ede2cc..57cad5d17 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,15 +1,13 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.64 2003/01/13 22:53:56 mdb Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.65 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Random; -import com.samskivert.util.StringUtil; - import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.ObjectTile; @@ -17,7 +15,9 @@ import com.threerings.media.tile.Tile; import com.threerings.media.tile.TileLayer; import com.threerings.miso.Log; -import com.threerings.miso.scene.util.ObjectSet; +import com.threerings.miso.client.util.ObjectSet; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; import com.threerings.miso.tile.AutoFringer; import com.threerings.miso.tile.BaseTile; import com.threerings.miso.tile.BaseTileLayer; @@ -56,6 +56,62 @@ public class DisplayMisoSceneImpl setMisoSceneModel(model); } + /** + * Provides this display miso scene with a tile manager from which it + * can load up all of its tiles. + */ + public void setTileManager (MisoTileManager tmgr) + { + _tmgr = tmgr; + _fringer = tmgr.getAutoFringer(); + populateLayers(); + } + + // documentation inherited from interface + public BaseTile getBaseTile (int x, int y) + { + return _base.getTile(x, y); + } + + // documentation inherited from interface + public Tile getFringeTile (int x, int y) + { + return _fringe.getTile(x, y); + } + + // documentation inherited from interface + public void getObjects (Rectangle region, ObjectSet set) + { + // iterate over all of our objects, creating and including scene + // objects for those that intersect the region + int ocount = _objects.size(); + for (int ii = 0; ii < ocount; ii++) { + DisplayObjectInfo scobj = (DisplayObjectInfo)_objects.get(ii); + if (region.contains(scobj.x, scobj.y)) { + set.insert(scobj); + } + } + } + + // documentation inherited from interface + public boolean canTraverse (Object trav, int x, int y) + { + BaseTile tile = getBaseTile(x, y); + return (((tile == null) || tile.isPassable()) && + !_covered[y*_model.width+x]); + } + + /** + * Return a string representation of this Miso scene object. + */ + public String toString () + { + StringBuffer buf = new StringBuffer(); + buf.append("[width=").append(_base.getWidth()); + buf.append(", height=").append(_base.getHeight()); + return buf.append("]").toString(); + } + /** * Instructs this miso scene to use the supplied model instead of its * current model. This should be followed up by a called to {@link @@ -73,17 +129,20 @@ public class DisplayMisoSceneImpl _base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei); _fringe = new TileLayer(new Tile[swid*shei], swid, shei); _covered = new boolean[swid*shei]; - } - /** - * Provides this display miso scene with a tile manager from which it - * can load up all of its tiles. - */ - public void setTileManager (MisoTileManager tmgr) - { - _tmgr = tmgr; - _fringer = tmgr.getAutoFringer(); - populateLayers(); + // create display object infos for our uninteresting objects + int ocount = (_model.objectTileIds == null) ? 0 : + _model.objectTileIds.length; + for (int ii = 0; ii < ocount; ii++) { + _objects.add(new DisplayObjectInfo(_model.objectTileIds[ii], + _model.objectXs[ii], + _model.objectYs[ii])); + } + + // create display object infos for our interesting objects + for (int ii = 0, ll = _model.objectInfo.length; ii < ll; ii++) { + _objects.add(new DisplayObjectInfo(_model.objectInfo[ii])); + } } /** @@ -127,132 +186,57 @@ public class DisplayMisoSceneImpl } } - // sanity check the object layer info - int ocount = _model.objectTileIds.length; - if (ocount % 3 != 0) { - throw new IllegalArgumentException( - "model.objectTileIds.length % 3 != 0"); - } - - // create object tile instances for our objects - for (int ii = 0; ii < ocount; ii += 3) { - int col = _model.objectTileIds[ii]; - int row = _model.objectTileIds[ii+1]; - int fqTid = _model.objectTileIds[ii+2]; - int tsid = (fqTid >> 16) & 0xFFFF, tid = (fqTid & 0xFFFF); - try { - expandObject(col, row, tsid, tid, fqTid, ii/3); - } catch (NoSuchTileSetException te) { - Log.warning("Scene contains non-existent object tile " + - "[tsid=" + tsid + ", tid=" + tid + - ", col=" + col + ", row=" + row + "]."); - } + // populate our display objects with object tiles + int ocount = _objects.size(); + for (int ii = 0; ii < ocount; ii++) { + populateObject((DisplayObjectInfo)_objects.get(ii)); } } /** - * Called to expand each object read from the model into an actual - * object tile instance with the appropriate additional data. - * - * @return the scene object record for the newly created object tile - * (which will have been put into all the appropriate lists and - * tables). + * Called to populate an object with its object tile when we have been + * configured with a tile manager from which to obtain such things. */ - protected SceneObject expandObject ( - int col, int row, int tsid, int tid, int fqTid, int objidx) - throws NoSuchTileException, NoSuchTileSetException + protected void populateObject (DisplayObjectInfo info) { - // create and initialize an object info record for this object - SceneObject scobj = createSceneObject( - col, row, (ObjectTile)_tmgr.getTile(tsid, tid)); + int tsid = (info.tileId >> 16) & 0xFFFF, tid = (info.tileId & 0xFFFF); + try { + initObject(info, (ObjectTile)_tmgr.getTile(tsid, tid)); + } catch (NoSuchTileSetException te) { + Log.warning("Scene contains non-existent object tile " + + "[info=" + info + ", tsid=" + tsid + + ", tid=" + tid + "]."); + } + } - // assign the object's remaining attributes - if (!StringUtil.blank(_model.objectActions[objidx])) { - scobj.action = _model.objectActions[objidx]; - } - // if we have object priorities, use 'em - if (_model.objectPrios != null) { - scobj.priority = _model.objectPrios[objidx]; - } + /** + * Initializes the supplied object with its object tile and configures + * any necessary peripheral scene business that couldn't be configured + * prior to the object having its tile. + */ + protected void initObject (DisplayObjectInfo info, ObjectTile tile) + { + // configure the object info with its object tile + info.setObjectTile(tile); // generate a "shadow" for this object tile by toggling the // "covered" flag on in all base tiles below it (to prevent // sprites from walking on those tiles) - setObjectTileFootprint(scobj.tile, col, row, true); - - // add the info record to the list - _objects.add(scobj); - - // return the object info so that derived classes may access it - return scobj; - } - - // documentation inherited from interface - public BaseTile getBaseTile (int x, int y) - { - return _base.getTile(x, y); - } - - // documentation inherited from interface - public Tile getFringeTile (int x, int y) - { - return _fringe.getTile(x, y); - } - - // documentation inherited from interface - public void getSceneObjects (Rectangle region, ObjectSet set) - { - // iterate over all of our objects, creating and including scene - // objects for those that intersect the region - int ocount = _objects.size(); - for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = (SceneObject)_objects.get(ii); - if (region.contains(scobj.x, scobj.y)) { - set.insert(scobj); - } - } - } - - // documentation inherited from interface - public boolean canTraverse (Object trav, int x, int y) - { - BaseTile tile = getBaseTile(x, y); - return (((tile == null) || tile.isPassable()) && - !_covered[y*_model.width+x]); + setObjectTileFootprint(info.tile, info.x, info.y, true); } /** - * Return a string representation of this Miso scene object. - */ - public String toString () - { - StringBuffer buf = new StringBuffer(); - buf.append("[width=").append(_base.getWidth()); - buf.append(", height=").append(_base.getHeight()); - return buf.append("]").toString(); - } - - /** - * Creates a scene object record. This allows derived classes to - * provide extended records. - */ - protected SceneObject createSceneObject (int x, int y, ObjectTile tile) - { - return new SceneObject(x, y, tile); - } - - /** - * Locates the scene object record for the object tile at the + * Locates the display object info record for the object tile at the * specified location. Two of the same kind of object tile cannot * exist at the same location. */ - protected SceneObject getSceneObject (ObjectTile tile, int x, int y) + protected DisplayObjectInfo getObjectInfo (ObjectTile tile, int x, int y) { int ocount = _objects.size(); for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = (SceneObject)_objects.get(ii); - if (scobj.tile == tile && scobj.x == x && scobj.y == y) { - return scobj; + DisplayObjectInfo oinfo = (DisplayObjectInfo)_objects.get(ii); + if (oinfo.tile == tile && oinfo.x == x && oinfo.y == y) { + return oinfo; } } return null; diff --git a/src/java/com/threerings/miso/client/DisplayObjectInfo.java b/src/java/com/threerings/miso/client/DisplayObjectInfo.java index 4df9b4873..cc40f8e6e 100644 --- a/src/java/com/threerings/miso/client/DisplayObjectInfo.java +++ b/src/java/com/threerings/miso/client/DisplayObjectInfo.java @@ -1,44 +1,56 @@ // -// $Id: DisplayObjectInfo.java,v 1.5 2002/11/28 03:41:58 mdb Exp $ +// $Id: DisplayObjectInfo.java,v 1.6 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Rectangle; -import com.samskivert.util.StringUtil; - import com.threerings.media.tile.ObjectTile; +import com.threerings.miso.data.ObjectInfo; /** * Used to track information about an object in the scene. */ -public class SceneObject +public class DisplayObjectInfo extends ObjectInfo { /** A reference to the object tile itself. */ public ObjectTile tile; - /** The x and y tile coordinates of the object. */ - public int x = -1, y = -1; - - /** The object's render priority. */ - public byte priority = 0; - - /** The action associated with this object or null if it has no - * action. */ - public String action; - /** The object's bounding rectangle. This will be filled in - * automatically by the Miso scene view when the object is used. */ + * automatically by the scene view when the object is used. */ public Rectangle bounds; /** * Convenience constructor. */ - public SceneObject (int x, int y, ObjectTile tile) + public DisplayObjectInfo (int tileId, int x, int y) + { + super(tileId, x, y); + } + + /** + * Convenience constructor. + */ + public DisplayObjectInfo (ObjectInfo source) + { + super(source); + } + + /** + * Provides this display object with a reference to its object tile + * when it becomes available. This must be called before the tile is + * used in any sort of display circumstances. + */ + public void setObjectTile (ObjectTile tile) { this.tile = tile; - this.x = x; - this.y = y; + + // if we don't already have an overridden render priority; use the + // one from our object tile (assuming we have one) + if (priority == 0 && tile != null) { + priority = (byte)Math.max( + Byte.MIN_VALUE, Math.min(Byte.MAX_VALUE, tile.getPriority())); + } } /** @@ -50,29 +62,4 @@ public class SceneObject { return false; } - - // documentation inherited - public boolean equals (Object other) - { - if (other instanceof SceneObject) { - SceneObject oso = (SceneObject)other; - return (x == oso.x && y == oso.y && tile == oso.tile); - } else { - return false; - } - } - - // documentation inherited - public int hashCode () - { - return x ^ y ^ tile.hashCode(); - } - - /** - * Generates a string representation of this instance. - */ - public String toString () - { - return StringUtil.fieldsToString(this); - } } diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java index c4f887d0c..f56f812fc 100644 --- a/src/java/com/threerings/miso/client/IsoSceneView.java +++ b/src/java/com/threerings/miso/client/IsoSceneView.java @@ -1,7 +1,7 @@ // -// $Id: IsoSceneView.java,v 1.130 2003/01/15 21:12:45 shaper Exp $ +// $Id: IsoSceneView.java,v 1.131 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.AlphaComposite; import java.awt.BasicStroke; @@ -36,10 +36,10 @@ import com.threerings.media.tile.Tile; import com.threerings.miso.Log; import com.threerings.miso.MisoPrefs; -import com.threerings.miso.scene.DirtyItemList.DirtyItem; -import com.threerings.miso.scene.util.AStarPathUtil; -import com.threerings.miso.scene.util.IsoUtil; -import com.threerings.miso.scene.util.ObjectSet; +import com.threerings.miso.client.DirtyItemList.DirtyItem; +import com.threerings.miso.client.util.AStarPathUtil; +import com.threerings.miso.client.util.IsoUtil; +import com.threerings.miso.client.util.ObjectSet; import com.threerings.miso.tile.BaseTile; /** @@ -124,12 +124,12 @@ public class IsoSceneView implements SceneView // grab all available objects Rectangle rect = new Rectangle(Short.MIN_VALUE, Short.MIN_VALUE, 2*Short.MAX_VALUE, 2*Short.MAX_VALUE); - _scene.getSceneObjects(rect, _objects); + _scene.getObjects(rect, _objects); // and fill in the new objects' bounds int ocount = _objects.size(); for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = _objects.get(ii); + DisplayObjectInfo scobj = _objects.get(ii); if (scobj.bounds == null) { scobj.bounds = IsoUtil.getObjectBounds(_model, scobj); } @@ -194,8 +194,8 @@ public class IsoSceneView implements SceneView Polygon hpoly = null; // if we have a hover object, do some business - if (_hobject != null && _hobject instanceof SceneObject) { - SceneObject scobj = (SceneObject)_hobject; + if (_hobject != null && _hobject instanceof DisplayObjectInfo) { + DisplayObjectInfo scobj = (DisplayObjectInfo)_hobject; if (scobj.action != null || _hmode == HIGHLIGHT_ALWAYS) { hpoly = IsoUtil.getObjectFootprint(_model, scobj); } @@ -421,7 +421,7 @@ public class IsoSceneView implements SceneView // add any objects impacted by the dirty rectangle int ocount = _objects.size(); for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = (SceneObject)_objects.get(ii); + DisplayObjectInfo scobj = _objects.get(ii); if (!scobj.bounds.intersects(clip)) { continue; } @@ -467,13 +467,13 @@ public class IsoSceneView implements SceneView // grab all available objects Rectangle rect = new Rectangle(Short.MIN_VALUE, Short.MIN_VALUE, 2*Short.MAX_VALUE, 2*Short.MAX_VALUE); - _scene.getSceneObjects(rect, _objects); - addAdditionalSceneObjects(_objects); + _scene.getObjects(rect, _objects); + addAdditionalObjects(_objects); // and fill in those objects' bounds int ocount = _objects.size(); for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = _objects.get(ii); + DisplayObjectInfo scobj = _objects.get(ii); scobj.bounds = IsoUtil.getObjectBounds(_model, scobj); } } @@ -482,7 +482,7 @@ public class IsoSceneView implements SceneView * A place for subclasses to add any additional scene objects they * may have. */ - protected void addAdditionalSceneObjects (ObjectSet set) + protected void addAdditionalObjects (ObjectSet set) { // nothing by default } @@ -581,8 +581,8 @@ public class IsoSceneView implements SceneView } // unhover the old - if (_hobject instanceof SceneObject) { - SceneObject oldhov = (SceneObject) _hobject; + if (_hobject instanceof DisplayObjectInfo) { + DisplayObjectInfo oldhov = (DisplayObjectInfo) _hobject; if (oldhov.setHovered(false)) { _remgr.invalidateRegion(oldhov.bounds); } @@ -593,8 +593,8 @@ public class IsoSceneView implements SceneView _hobject = newHover; // hover the new - if (_hobject instanceof SceneObject) { - SceneObject newhov = (SceneObject) _hobject; + if (_hobject instanceof DisplayObjectInfo) { + DisplayObjectInfo newhov = (DisplayObjectInfo) _hobject; if (newhov.setHovered(true)) { _remgr.invalidateRegion(newhov.bounds); } @@ -622,7 +622,7 @@ public class IsoSceneView implements SceneView { int ocount = _objects.size(); for (int ii = 0; ii < ocount; ii++) { - SceneObject scobj = (SceneObject)_objects.get(ii); + DisplayObjectInfo scobj = (DisplayObjectInfo)_objects.get(ii); Rectangle pbounds = scobj.bounds; // skip bounding rects that don't contain the point if (!pbounds.contains(x, y)) { diff --git a/src/java/com/threerings/miso/client/IsoSceneViewModel.java b/src/java/com/threerings/miso/client/IsoSceneViewModel.java index c61087e22..2bb1130d7 100644 --- a/src/java/com/threerings/miso/client/IsoSceneViewModel.java +++ b/src/java/com/threerings/miso/client/IsoSceneViewModel.java @@ -1,14 +1,14 @@ // -// $Id: IsoSceneViewModel.java,v 1.27 2003/01/15 21:12:45 shaper Exp $ +// $Id: IsoSceneViewModel.java,v 1.28 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Point; import java.awt.Rectangle; import com.threerings.miso.Log; import com.threerings.miso.MisoConfig; -import com.threerings.miso.scene.util.IsoUtil; +import com.threerings.miso.client.util.IsoUtil; /** * Provides a holding place for the myriad parameters and bits of data diff --git a/src/java/com/threerings/miso/client/SceneView.java b/src/java/com/threerings/miso/client/SceneView.java index ae3f886c7..7fd1d08ef 100644 --- a/src/java/com/threerings/miso/client/SceneView.java +++ b/src/java/com/threerings/miso/client/SceneView.java @@ -1,7 +1,7 @@ // -// $Id: SceneView.java,v 1.32 2003/01/13 22:53:56 mdb Exp $ +// $Id: SceneView.java,v 1.33 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Graphics2D; import java.awt.Point; @@ -79,7 +79,7 @@ public interface SceneView /** * Returns information about the object over which the mouse is - * currently hovering (either a {@link SceneObject} or a {@link + * currently hovering (either a {@link DisplayObjectInfo} or a {@link * Sprite}), or null if the mouse is not hovering over anything of * interest. */ diff --git a/src/java/com/threerings/miso/client/SceneViewPanel.java b/src/java/com/threerings/miso/client/SceneViewPanel.java index 947e92de6..305990505 100644 --- a/src/java/com/threerings/miso/client/SceneViewPanel.java +++ b/src/java/com/threerings/miso/client/SceneViewPanel.java @@ -1,7 +1,7 @@ // -// $Id: SceneViewPanel.java,v 1.48 2003/01/15 21:12:45 shaper Exp $ +// $Id: SceneViewPanel.java,v 1.49 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.Dimension; import java.awt.Graphics2D; @@ -22,7 +22,7 @@ import com.threerings.media.sprite.Sprite; import com.threerings.media.sprite.SpriteManager; import com.threerings.miso.Log; -import com.threerings.miso.scene.util.IsoUtil; +import com.threerings.miso.client.util.IsoUtil; /** * The scene view panel is responsible for managing a {@link diff --git a/src/java/com/threerings/miso/client/TilePath.java b/src/java/com/threerings/miso/client/TilePath.java index a32b7ae57..cfdecb14b 100644 --- a/src/java/com/threerings/miso/client/TilePath.java +++ b/src/java/com/threerings/miso/client/TilePath.java @@ -1,7 +1,7 @@ // -// $Id: TilePath.java,v 1.12 2003/01/13 22:53:56 mdb Exp $ +// $Id: TilePath.java,v 1.13 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import java.awt.*; import java.util.List; @@ -14,7 +14,7 @@ import com.threerings.media.util.PathNode; import com.threerings.media.util.Pathable; import com.threerings.miso.Log; -import com.threerings.miso.scene.util.IsoUtil; +import com.threerings.miso.client.util.IsoUtil; /** * The tile path represents a path of tiles through a scene. The path is diff --git a/src/java/com/threerings/miso/client/TilePathNode.java b/src/java/com/threerings/miso/client/TilePathNode.java index 2c8b8b5fa..ec9bc5d5d 100644 --- a/src/java/com/threerings/miso/client/TilePathNode.java +++ b/src/java/com/threerings/miso/client/TilePathNode.java @@ -1,7 +1,7 @@ // -// $Id: TilePathNode.java,v 1.2 2002/05/31 03:38:03 mdb Exp $ +// $Id: TilePathNode.java,v 1.3 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.client; import com.threerings.media.util.PathNode; diff --git a/src/java/com/threerings/miso/client/util/AStarPathUtil.java b/src/java/com/threerings/miso/client/util/AStarPathUtil.java index ef2f8dc8e..3c7deb7ad 100644 --- a/src/java/com/threerings/miso/client/util/AStarPathUtil.java +++ b/src/java/com/threerings/miso/client/util/AStarPathUtil.java @@ -1,7 +1,7 @@ // -// $Id: AStarPathUtil.java,v 1.24 2003/01/15 21:44:52 shaper Exp $ +// $Id: AStarPathUtil.java,v 1.25 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene.util; +package com.threerings.miso.client.util; import java.awt.Point; import java.util.*; @@ -11,7 +11,7 @@ import com.samskivert.util.HashIntMap; import com.threerings.media.util.MathUtil; import com.threerings.miso.Log; -import com.threerings.miso.scene.DisplayMisoScene; +import com.threerings.miso.client.DisplayMisoScene; import com.threerings.miso.tile.BaseTile; /** diff --git a/src/java/com/threerings/miso/client/util/IsoUtil.java b/src/java/com/threerings/miso/client/util/IsoUtil.java index 2909c16e4..a61faf61c 100644 --- a/src/java/com/threerings/miso/client/util/IsoUtil.java +++ b/src/java/com/threerings/miso/client/util/IsoUtil.java @@ -1,7 +1,7 @@ // -// $Id: IsoUtil.java,v 1.42 2003/01/13 22:53:56 mdb Exp $ +// $Id: IsoUtil.java,v 1.43 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene.util; +package com.threerings.miso.client.util; import java.awt.Point; import java.awt.Polygon; @@ -16,8 +16,8 @@ import com.threerings.util.DirectionCodes; import com.threerings.util.DirectionUtil; import com.threerings.miso.Log; -import com.threerings.miso.scene.IsoSceneViewModel; -import com.threerings.miso.scene.SceneObject; +import com.threerings.miso.client.IsoSceneViewModel; +import com.threerings.miso.client.DisplayObjectInfo; /** * The IsoUtil class is a holding place for miscellaneous @@ -38,7 +38,7 @@ public class IsoUtil * @return the bounding polygon. */ public static Polygon getObjectFootprint ( - IsoSceneViewModel model, SceneObject scobj) + IsoSceneViewModel model, DisplayObjectInfo scobj) { Polygon boundsPoly = new SmartPolygon(); Point tpos = tileToScreen(model, scobj.x, scobj.y, new Point()); @@ -84,7 +84,7 @@ public class IsoUtil * @return the bounding rectangle. */ public static Rectangle getObjectBounds ( - IsoSceneViewModel model, SceneObject scobj) + IsoSceneViewModel model, DisplayObjectInfo scobj) { Point tpos = tileToScreen(model, scobj.x, scobj.y, new Point()); @@ -110,7 +110,7 @@ public class IsoUtil * the objects occupy the specified coordinates, false if not. */ public static boolean objectFootprintsOverlap ( - SceneObject so1, SceneObject so2) + DisplayObjectInfo so1, DisplayObjectInfo so2) { return (so2.x > so1.x - so1.tile.getBaseWidth() && so1.x > so2.x - so2.tile.getBaseWidth() && diff --git a/src/java/com/threerings/miso/client/util/ObjectSet.java b/src/java/com/threerings/miso/client/util/ObjectSet.java index da3a9cb71..4be769f21 100644 --- a/src/java/com/threerings/miso/client/util/ObjectSet.java +++ b/src/java/com/threerings/miso/client/util/ObjectSet.java @@ -1,7 +1,7 @@ // -// $Id: ObjectSet.java,v 1.2 2002/10/15 21:01:39 ray Exp $ +// $Id: ObjectSet.java,v 1.3 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene.util; +package com.threerings.miso.client.util; import java.util.Arrays; import java.util.Comparator; @@ -9,31 +9,36 @@ import java.util.Comparator; import com.samskivert.util.ArrayUtil; import com.samskivert.util.ListUtil; -import com.threerings.miso.scene.SceneObject; +import com.threerings.miso.Log; +import com.threerings.miso.client.DisplayObjectInfo; /** * Used to store an (arbitrarily) ordered, low-impact iteratable (doesn't - * require object creation), set of {@link SceneObject} instances. + * require object creation), set of {@link DisplayObjectInfo} instances. */ public class ObjectSet { /** - * Inserts the supplied scene object into the set. + * Inserts the supplied object into the set. * * @return true if it was inserted, false if the object was already in * the set. */ - public boolean insert (SceneObject scobj) + public boolean insert (DisplayObjectInfo info) { // bail if it's already in the set - int ipos = indexOf(scobj); + int ipos = indexOf(info); if (ipos >= 0) { + // log a warning because the caller shouldn't be doing this + Log.warning("Requested to add a display object to a set that " + + "already contains such an object [ninfo=" + info + + ", oinfo=" + _objs[ipos] + "]."); return false; } // otherwise insert it ipos = -(ipos+1); - _scobjs = ListUtil.insert(_scobjs, ipos, scobj); + _objs = ListUtil.insert(_objs, ipos, info); _size++; return true; } @@ -42,13 +47,13 @@ public class ObjectSet * Returns true if the specified object is in the set, false if it is * not. */ - public boolean contains (SceneObject scobj) + public boolean contains (DisplayObjectInfo info) { - return (indexOf(scobj) >= 0); + return (indexOf(info) >= 0); } /** - * Returns the number of scene objects in this set. + * Returns the number of objects in this set. */ public int size () { @@ -56,12 +61,12 @@ public class ObjectSet } /** - * Returns the scene object with the specified index. The index must & - * be between 0 and {@link #size}-1. + * Returns the object with the specified index. The index must & be + * between 0 and {@link #size}-1. */ - public SceneObject get (int index) + public DisplayObjectInfo get (int index) { - return (SceneObject)_scobjs[index]; + return (DisplayObjectInfo)_objs[index]; } /** @@ -69,18 +74,18 @@ public class ObjectSet */ public void remove (int index) { - ListUtil.remove(_scobjs, index); + ListUtil.remove(_objs, index); _size--; } /** - * Removes the specified scene object from the set. + * Removes the specified object from the set. * * @return true if it was removed, false if it was not in the set. */ - public boolean remove (SceneObject scobj) + public boolean remove (DisplayObjectInfo info) { - int opos = indexOf(scobj); + int opos = indexOf(info); if (opos >= 0) { remove(opos); return true; @@ -95,30 +100,50 @@ public class ObjectSet public void clear () { _size = 0; - Arrays.fill(_scobjs, null); + Arrays.fill(_objs, null); + } + + /** + * Returns a string representation of this instance. + */ + public String toString () + { + StringBuffer buf = new StringBuffer("["); + for (int ii = 0; ii < _size; ii++) { + if (ii > 0) { + buf.append(", "); + } + buf.append(_objs[ii]); + } + return buf.append("]").toString(); } /** * Returns the index of the object or it's insertion index if it is * not in the set. */ - protected final int indexOf (SceneObject scobj) + protected final int indexOf (DisplayObjectInfo info) { - return ArrayUtil.binarySearch(_scobjs, 0, _size, scobj, SCOBJ_COMP); + return ArrayUtil.binarySearch(_objs, 0, _size, info, INFO_COMP); } - /** Our sorted array of scene objects. */ - protected Object[] _scobjs = new Object[DEFAULT_SIZE]; + /** Our sorted array of objects. */ + protected Object[] _objs = new Object[DEFAULT_SIZE]; /** The number of objects in the set. */ protected int _size; - /** We simply sort the scene objects in order of their hash code. We - * don't care about their orderer, it simply needs to exist to support - * binary search. */ - protected static final Comparator SCOBJ_COMP = new Comparator() { + /** We simply sort the objects in order of their hash code. We don't + * care about their order, it exists only to support binary search. */ + protected static final Comparator INFO_COMP = new Comparator() { public int compare (Object o1, Object o2) { - return o1.hashCode() - o2.hashCode(); + DisplayObjectInfo do1 = (DisplayObjectInfo)o1; + DisplayObjectInfo do2 = (DisplayObjectInfo)o2; + if (do1.tileId == do2.tileId) { + return ((do1.x << 16) + do1.y) - ((do2.x << 16) + do2.y); + } else { + return do1.tileId - do2.tileId; + } } }; diff --git a/src/java/com/threerings/miso/data/MisoSceneModel.java b/src/java/com/threerings/miso/data/MisoSceneModel.java index 2cfe0c746..fbe49bd0b 100644 --- a/src/java/com/threerings/miso/data/MisoSceneModel.java +++ b/src/java/com/threerings/miso/data/MisoSceneModel.java @@ -1,14 +1,12 @@ // -// $Id: MisoSceneModel.java,v 1.10 2002/09/23 23:07:11 mdb Exp $ +// $Id: MisoSceneModel.java,v 1.11 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene; +package com.threerings.miso.data; -import com.samskivert.util.StringUtil; +import java.util.ArrayList; import com.threerings.io.SimpleStreamableObject; -import com.threerings.miso.Log; - /** * The scene model is the bare bones representation of the data for a * scene in the Miso system. From the scene model, one would create an @@ -29,24 +27,26 @@ public class MisoSceneModel extends SimpleStreamableObject /** The viewport height in tiles. */ public int vheight; - /** The combined tile ids (tile set id and tile id) - * in compressed format. - * Don't go poking around in here, use the accessor methods. */ + /** The combined tile ids (tile set id and tile id) in compressed + * format. Don't go poking around in here, use the accessor + * methods. */ public int[] baseTileIds; - /** The combined tile ids (tile set id and tile id) of the files in - * the object layer in (x, y, tile id) format. */ + /** The combined tile ids (tile set id and tile id) of the + * "uninteresting" tiles in the object layer. */ public int[] objectTileIds; - /** The action strings associated with the object tiles in the order - * that the tiles are specified in the {@link #objectTileIds} array. - * Elements of this array may be null but will be converted to the - * empty string during serialization. */ - public String[] objectActions; + /** The x coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectXs; - /** Render priorities for each object tile in the scene, which are - * used to resolve overlapped object render order conflicts. */ - public byte[] objectPrios; + /** The y coordinate of the "uninteresting" tiles in the object + * layer. */ + public short[] objectYs; + + /** Information records for the "interesting" objects in the object + * layer. */ + public ObjectInfo[] objectInfo; /** * Get the fully-qualified tile id of the base tile at the specified @@ -140,11 +140,37 @@ public class MisoSceneModel extends SimpleStreamableObject MisoSceneModel model = (MisoSceneModel)super.clone(); model.baseTileIds = (int[])baseTileIds.clone(); model.objectTileIds = (int[])objectTileIds.clone(); - model.objectActions = (String[])objectActions.clone(); - model.objectPrios = (byte[])objectPrios.clone(); + model.objectXs = (short[])objectXs.clone(); + model.objectYs = (short[])objectYs.clone(); + model.objectInfo = (ObjectInfo[])objectInfo.clone(); return model; } + /** + * Populates the interesting and uninteresting parts of a miso scene + * model given lists of {@link ObjectInfo} records for each. + */ + public static void populateObjects (MisoSceneModel model, + ArrayList ilist, ArrayList ulist) + { + // set up the uninteresting arrays + int ucount = ulist.size(); + model.objectTileIds = new int[ucount]; + model.objectXs = new short[ucount]; + model.objectYs = new short[ucount]; + for (int ii = 0; ii < ucount; ii++) { + ObjectInfo info = (ObjectInfo)ulist.get(ii); + model.objectTileIds[ii] = info.tileId; + model.objectXs[ii] = (short)info.x; + model.objectYs[ii] = (short)info.y; + } + + // set up the interesting array + int icount = ilist.size(); + model.objectInfo = new ObjectInfo[icount]; + ilist.toArray(model.objectInfo); + } + /** * Creates and returns a blank scene model (with zero width and * height). @@ -180,7 +206,8 @@ public class MisoSceneModel extends SimpleStreamableObject model.vheight = vheight; model.allocateBaseTileArray(); model.objectTileIds = new int[0]; - model.objectActions = new String[0]; - model.objectPrios = new byte[0]; + model.objectXs = new short[0]; + model.objectYs = new short[0]; + model.objectInfo = new ObjectInfo[0]; } } diff --git a/src/java/com/threerings/miso/data/ObjectInfo.java b/src/java/com/threerings/miso/data/ObjectInfo.java new file mode 100644 index 000000000..de6c9a7d1 --- /dev/null +++ b/src/java/com/threerings/miso/data/ObjectInfo.java @@ -0,0 +1,120 @@ +// +// $Id: ObjectInfo.java,v 1.1 2003/01/31 23:10:45 mdb Exp $ + +package com.threerings.miso.data; + +import com.samskivert.util.StringUtil; +import com.threerings.io.SimpleStreamableObject; + +/** + * Contains information about an object in a Miso scene. + */ +public class ObjectInfo extends SimpleStreamableObject +{ + /** The fully qualified object tile id. */ + public int tileId; + + /** The x and y tile coordinates of the object. */ + public int x, y; + + /** The object's render priority. */ + public byte priority = 0; + + /** The action associated with this object or null if it has no + * action. */ + public String action; + + /** A "spot" associated with this object (specified as an offset from + * the fine coordinates of the object's origin tile). */ + public byte sx, sy; + + /** The orientation of the "spot" associated with this object. */ + public byte sorient; + + /** Up to two colorization assignments for this object. */ + public int zations; + + /** + * Convenience constructor. + */ + public ObjectInfo (int tileId, int x, int y) + { + this.tileId = tileId; + this.x = x; + this.y = y; + } + + /** + * Creates an object info that is a copy of the supplied info. + */ + public ObjectInfo (ObjectInfo other) + { + this.tileId = other.tileId; + this.x = other.x; + this.y = other.y; + this.priority = other.priority; + this.action = other.action; + this.sx = other.sx; + this.sy = other.sy; + this.sorient = other.sorient; + this.zations = zations; + } + + /** + * Zero argument constructor needed for unserialization. + */ + public ObjectInfo () + { + } + + /** + * Returns the primary colorization assignment. + */ + public int getPrimaryZation () + { + return (zations & 0xFFFF); + } + + /** + * Returns the secondary colorization assignment. + */ + public int getSecondaryZation () + { + return ((zations >> 16) & 0xFFFF); + } + + /** + * Sets the primary and secondary colorization assignments. + */ + public void setZations (short primary, short secondary) + { + zations = ((secondary << 16) | primary); + } + + /** + * Returns true if this object info contains non-default data for + * anything other than the tile id and coordinates. + */ + public boolean isInteresting () + { + return (!StringUtil.blank(action) || priority != 0 || + sx != 0 || sy != 0 || zations != 0); + } + + // documentation inherited + public boolean equals (Object other) + { + if (other instanceof ObjectInfo) { + ObjectInfo ooi = (ObjectInfo)other; + return (x == ooi.x && y == ooi.y && tileId == ooi.tileId); + } else { + return false; + } + } + + // documentation inherited + public int hashCode () + { + return x ^ y ^ tileId; + } +} diff --git a/src/java/com/threerings/miso/server/RuntimeMisoScene.java b/src/java/com/threerings/miso/server/RuntimeMisoScene.java index b85777a98..8b04fb01c 100644 --- a/src/java/com/threerings/miso/server/RuntimeMisoScene.java +++ b/src/java/com/threerings/miso/server/RuntimeMisoScene.java @@ -1,11 +1,11 @@ // -// $Id: RuntimeMisoScene.java,v 1.1 2002/12/11 23:07:21 shaper Exp $ +// $Id: RuntimeMisoScene.java,v 1.2 2003/01/31 23:10:45 mdb Exp $ package com.threerings.miso.server; import java.util.Iterator; -import com.threerings.miso.scene.SceneObject; +import com.threerings.miso.data.ObjectInfo; /** * The Miso scene interface used by the server to deal with scenes. @@ -13,8 +13,8 @@ import com.threerings.miso.scene.SceneObject; public interface RuntimeMisoScene { /** - * Iterates over the {@link RuntimeSceneObject} instances representing - * all available objects in the scene. + * Iterates over the {@link ObjectInfo} instances representing all + * "interesting" objects in the scene. */ - public Iterator enumerateSceneObjects (); + public Iterator enumerateObjects (); } diff --git a/src/java/com/threerings/miso/server/RuntimeMisoSceneImpl.java b/src/java/com/threerings/miso/server/RuntimeMisoSceneImpl.java index 69baa7ebb..ba94aa3fc 100644 --- a/src/java/com/threerings/miso/server/RuntimeMisoSceneImpl.java +++ b/src/java/com/threerings/miso/server/RuntimeMisoSceneImpl.java @@ -1,13 +1,13 @@ // -// $Id: RuntimeMisoSceneImpl.java,v 1.1 2002/12/11 23:07:21 shaper Exp $ +// $Id: RuntimeMisoSceneImpl.java,v 1.2 2003/01/31 23:10:45 mdb Exp $ package com.threerings.miso.server; import java.util.ArrayList; import java.util.Iterator; -import com.threerings.miso.scene.MisoSceneModel; -import com.threerings.miso.scene.SceneObject; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; /** * A basic implementation of the {@link RuntimeMisoScene} interface which @@ -18,41 +18,22 @@ public class RuntimeMisoSceneImpl { /** * Creates an instance that will obtain data from the supplied scene - * model and place config. + * model. */ public RuntimeMisoSceneImpl (MisoSceneModel model) { - // keep a casted reference to our scene model around - _model = model; - - // build a list of all objects in the scene - populateSceneObjects(); - } - - /** - * Gathers and stores information about all objects in the scene. - */ - protected void populateSceneObjects () - { - int ocount = _model.objectTileIds.length; - for (int ii = 0; ii < ocount; ii += 3) { - RuntimeSceneObject scobj = new RuntimeSceneObject(); - scobj.x = _model.objectTileIds[ii]; - scobj.y = _model.objectTileIds[ii+1]; - scobj.action = _model.objectActions[ii/3]; - _objects.add(scobj); + // stick all of the interesting scene objects into an array list + for (int ii = 0, ll = model.objectInfo.length; ii < ll; ii++) { + _objects.add(model.objectInfo[ii]); } } // documentation inherited - public Iterator enumerateSceneObjects () + public Iterator enumerateObjects () { return _objects.iterator(); } - /** A casted reference to our scene model. */ - protected MisoSceneModel _model; - - /** The scene object records. */ + /** The object info records. */ protected ArrayList _objects = new ArrayList(); } diff --git a/src/java/com/threerings/miso/server/RuntimeSceneObject.java b/src/java/com/threerings/miso/server/RuntimeSceneObject.java deleted file mode 100644 index 862ed1066..000000000 --- a/src/java/com/threerings/miso/server/RuntimeSceneObject.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id: RuntimeSceneObject.java,v 1.1 2002/12/11 23:07:21 shaper Exp $ - -package com.threerings.miso.server; - -import com.samskivert.util.StringUtil; - -/** - * Used to track server-side information about an object in a miso scene. - */ -public class RuntimeSceneObject -{ - /** The x and y tile coordinates of the object. */ - public int x = -1, y = -1; - - /** The action associated with this object or null if it has no - * action. */ - public String action; - - // documentation inherited - public boolean equals (Object other) - { - if (other instanceof RuntimeSceneObject) { - RuntimeSceneObject oso = (RuntimeSceneObject)other; - // TODO: we should probably check the tile type as well, but - // for now we only differentiate runtime miso scene objects by - // their coordinates within the scene since we don't bother - // keeping around tile information server-side - return (x == oso.x && y == oso.y); - } else { - return false; - } - } - - // documentation inherited - public int hashCode () - { - return x ^ y; - } - - /** Generates a string representation of this instance. */ - public String toString () - { - return StringUtil.fieldsToString(this); - } -} diff --git a/src/java/com/threerings/miso/tile/AutoFringer.java b/src/java/com/threerings/miso/tile/AutoFringer.java index e76efab8f..321769821 100644 --- a/src/java/com/threerings/miso/tile/AutoFringer.java +++ b/src/java/com/threerings/miso/tile/AutoFringer.java @@ -1,5 +1,5 @@ // -// $Id: AutoFringer.java,v 1.17 2003/01/14 02:50:54 mdb Exp $ +// $Id: AutoFringer.java,v 1.18 2003/01/31 23:10:45 mdb Exp $ package com.threerings.miso.tile; @@ -36,7 +36,7 @@ import com.threerings.media.image.BackedVolatileMirage; import com.threerings.media.image.ImageManager; import com.threerings.media.image.Mirage; -import com.threerings.miso.scene.MisoSceneModel; +import com.threerings.miso.data.MisoSceneModel; /** * Automatically fringes a scene according to the rules in the diff --git a/src/java/com/threerings/miso/tools/EditableMisoScene.java b/src/java/com/threerings/miso/tools/EditableMisoScene.java index 22ed1038a..89d9aa555 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoScene.java +++ b/src/java/com/threerings/miso/tools/EditableMisoScene.java @@ -1,7 +1,7 @@ // -// $Id: EditableMisoScene.java,v 1.18 2002/09/23 21:54:50 mdb Exp $ +// $Id: EditableMisoScene.java,v 1.19 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene.tools; +package com.threerings.miso.tools; import java.awt.Rectangle; @@ -9,9 +9,9 @@ import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.Tile; import com.threerings.media.tile.TileUtil; -import com.threerings.miso.scene.DisplayMisoScene; -import com.threerings.miso.scene.MisoSceneModel; -import com.threerings.miso.scene.SceneObject; +import com.threerings.miso.client.DisplayMisoScene; +import com.threerings.miso.client.DisplayObjectInfo; +import com.threerings.miso.data.MisoSceneModel; import com.threerings.miso.tile.BaseTile; import com.threerings.miso.tile.BaseTileSet; @@ -70,7 +70,7 @@ public interface EditableMisoScene * * @return the new scene object instance. */ - public SceneObject addSceneObject ( + public DisplayObjectInfo addObject ( ObjectTile tile, int x, int y, int fqTileId); /** @@ -81,7 +81,7 @@ public interface EditableMisoScene /** * Removes the specified object from the scene. */ - public boolean removeSceneObject (SceneObject scobj); + public boolean removeObject (DisplayObjectInfo scobj); /** * Returns a reference to the miso scene model that reflects the diff --git a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java index f4b5b063d..547220466 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java +++ b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java @@ -1,11 +1,12 @@ // -// $Id: EditableMisoSceneImpl.java,v 1.24 2002/09/23 23:07:11 mdb Exp $ +// $Id: EditableMisoSceneImpl.java,v 1.25 2003/01/31 23:10:45 mdb Exp $ -package com.threerings.miso.scene.tools; +package com.threerings.miso.tools; import java.awt.Point; import java.awt.Rectangle; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -21,10 +22,11 @@ import com.threerings.miso.tile.BaseTile; import com.threerings.miso.tile.BaseTileSet; import com.threerings.miso.tile.MisoTileManager; -import com.threerings.miso.scene.DisplayMisoSceneImpl; -import com.threerings.miso.scene.MisoSceneModel; -import com.threerings.miso.scene.SceneObject; -import com.threerings.miso.scene.util.IsoUtil; +import com.threerings.miso.client.DisplayMisoSceneImpl; +import com.threerings.miso.client.DisplayObjectInfo; +import com.threerings.miso.client.util.IsoUtil; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; /** * The default implementation of the {@link EditableMisoScene} interface. @@ -111,20 +113,22 @@ public class EditableMisoSceneImpl } // documentation inherited - public SceneObject addSceneObject ( + public DisplayObjectInfo addObject ( ObjectTile tile, int x, int y, int fqTileId) { + // sanity check + if (x > Short.MAX_VALUE || y > Short.MAX_VALUE || + x < Short.MIN_VALUE || y < Short.MIN_VALUE) { + throw new IllegalArgumentException( + "Invalid tile coordinates [x=" + x + ", y=" + y + "]"); + } + // create a scene object record and add it to the list - EditableSceneObject scobj = (EditableSceneObject) - createSceneObject(x, y, tile); - scobj.fqTileId = fqTileId; - _objects.add(scobj); + DisplayObjectInfo info = new DisplayObjectInfo(fqTileId, x, y); + initObject(info, tile); + _objects.add(info); - // toggle the "covered" flag on in all base tiles below this - // object tile - setObjectTileFootprint(tile, x, y, true); - - return scobj; + return info; } // documentation inherited @@ -136,12 +140,12 @@ public class EditableMisoSceneImpl } // documentation inherited - public boolean removeSceneObject (SceneObject scobj) + public boolean removeObject (DisplayObjectInfo info) { - if (_objects.remove(scobj)) { + if (_objects.remove(info)) { // toggle the "covered" flag off on the base tiles in this object // tile's footprint - setObjectTileFootprint(scobj.tile, scobj.x, scobj.y, false); + setObjectTileFootprint(info.tile, info.x, info.y, false); return true; } else { return false; @@ -152,68 +156,26 @@ public class EditableMisoSceneImpl public MisoSceneModel getMisoSceneModel () { // we need to flush the object layer to the model prior to - // returning it - int ocount = _objects.size(); - - // but only do it if we've actually got some objects - if (ocount > 0) { - int[] otids = new int[ocount*3]; - String[] actions = new String[ocount]; - byte[] prios = new byte[ocount]; - - for (int ii = 0; ii < ocount; ii++) { - EditableSceneObject scobj = (EditableSceneObject) - _objects.get(ii); - otids[3*ii] = scobj.x; - otids[3*ii+1] = scobj.y; - otids[3*ii+2] = scobj.fqTileId; - actions[ii] = scobj.action; - prios[ii] = scobj.priority; + // returning it; first split our objects into two lists + ArrayList ilist = new ArrayList(); + ArrayList ulist = new ArrayList(); + for (int ii = 0, ll = _objects.size(); ii < ll; ii++) { + ObjectInfo info = (ObjectInfo)_objects.get(ii); + if (info.isInteresting()) { + // convert to a plain object info record + ilist.add(new ObjectInfo(info)); + } else { + ulist.add(info); } - - // stuff the new arrays into the model - _model.objectTileIds = otids; - _model.objectActions = actions; - _model.objectPrios = prios; } + // now populate the scene model appropriately + MisoSceneModel.populateObjects(_model, ilist, ulist); + // and we're ready to roll return _model; } - // documentation inherited - protected SceneObject createSceneObject (int x, int y, ObjectTile tile) - { - return new EditableSceneObject(x, y, tile); - } - - // documentation inherited - protected SceneObject expandObject ( - int col, int row, int tsid, int tid, int fqTid, int objidx) - throws NoSuchTileException, NoSuchTileSetException - { - // do the actual object creation - EditableSceneObject scobj = (EditableSceneObject) - super.expandObject(col, row, tsid, tid, fqTid, objidx); - - // we need this to track object layer mods - scobj.fqTileId = fqTid; - - // pass on the objecty goodness - return scobj; - } - - /** Used to report information on objects in this scene. */ - protected static class EditableSceneObject extends SceneObject - { - public int fqTileId; - - public EditableSceneObject (int x, int y, ObjectTile tile) - { - super(x, y, tile); - } - } - /** The default tileset with which to fill the base layer. */ protected BaseTileSet _defaultBaseTileSet; diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneParser.java b/src/java/com/threerings/miso/tools/xml/MisoSceneParser.java index 4e99055e5..842f06cc4 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneParser.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneParser.java @@ -1,15 +1,16 @@ // -// $Id: MisoSceneParser.java,v 1.2 2002/02/02 01:09:53 mdb Exp $ +// $Id: MisoSceneParser.java,v 1.3 2003/01/31 23:10:46 mdb Exp $ -package com.threerings.miso.scene.tools.xml; +package com.threerings.miso.tools.xml; import java.io.IOException; import java.io.FileInputStream; import org.xml.sax.SAXException; import org.apache.commons.digester.Digester; +import org.apache.commons.digester.RuleSet; -import com.threerings.miso.scene.MisoSceneModel; +import com.threerings.miso.data.MisoSceneModel; /** * A simple class for parsing a standalone miso scene model. @@ -18,17 +19,34 @@ public class MisoSceneParser { /** * Constructs a miso scene parser that parses scenes with the - * specified XML path prefix. See the {@link - * MisoSceneRuleSet#MisoSceneRuleSet} documentation for more + * specified XML path prefix and a standard scene rule set. See the + * {@link MisoSceneRuleSet#MisoSceneRuleSet} documentation for more * information. */ public MisoSceneParser (String prefix) { - // create and configure our digester - _digester = new Digester(); MisoSceneRuleSet set = new MisoSceneRuleSet(); set.setPrefix(prefix); - _digester.addRuleSet(set); + init(prefix, set); + } + + /** + * Constructs a miso scene parser that parses scenes with the + * specified XML path prefix, using the supplied rule set. The rule + * set should leave a {@link MisoSceneModel} at the top of the + * digester's stack. + */ + public MisoSceneParser (String prefix, RuleSet rules) + { + init(prefix, rules); + } + + /** Constructor helper function. */ + protected void init (String prefix, RuleSet rules) + { + // create and configure our digester + _digester = new Digester(); + _digester.addRuleSet(rules); _digester.addSetNext(prefix, "setSceneModel", MisoSceneModel.class.getName()); } diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java index 0970f8c26..4d4ba5864 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java @@ -1,16 +1,20 @@ // -// $Id: MisoSceneRuleSet.java,v 1.11 2002/09/23 23:53:33 mdb Exp $ +// $Id: MisoSceneRuleSet.java,v 1.12 2003/01/31 23:10:46 mdb Exp $ -package com.threerings.miso.scene.tools.xml; +package com.threerings.miso.tools.xml; + +import java.util.ArrayList; import org.apache.commons.digester.Digester; import org.apache.commons.digester.RuleSetBase; import com.samskivert.xml.CallMethodSpecialRule; import com.samskivert.xml.SetFieldRule; +import com.samskivert.xml.SetPropertyFieldsRule; import com.threerings.miso.Log; -import com.threerings.miso.scene.MisoSceneModel; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; /** * Used to parse a {@link MisoSceneModel} from XML. @@ -58,31 +62,37 @@ public class MisoSceneRuleSet extends RuleSetBase new SetFieldRule(digester, "vheight")); digester.addRule(_prefix + "/base", new SetFieldRule(digester, "baseTileIds")); - digester.addRule(_prefix + "/object", - new SetFieldRule(digester, "objectTileIds")); - digester.addRule(_prefix + "/actions", - new SetFieldRule(digester, "objectActions")); - digester.addRule(_prefix + "/priorities", - new SetFieldRule(digester, "objectPrios")); - // we have to unfuck the objectActions field in the event that - // there's one object in the objects element which has a blank - // action string (which the parser will parse as a zero length - // array, when we want a length one array with a blank string) - digester.addRule(_prefix, new CallMethodSpecialRule(digester) { + digester.addObjectCreate(_prefix + "/objects", + ArrayList.class.getName()); + digester.addObjectCreate(_prefix + "/objects/object", + ObjectInfo.class.getName()); + digester.addSetNext(_prefix + "/objects/object", "add", + Object.class.getName()); + + digester.addRule(_prefix + "/objects/object", + new SetPropertyFieldsRule(digester)); + + digester.addRule(_prefix + "/objects", new CallMethodSpecialRule( + digester) { public void parseAndSet (String bodyText, Object target) throws Exception { - MisoSceneModel model = (MisoSceneModel)target; - if (model.objectTileIds.length > 0 && - model.objectActions.length == 0) { - model.objectActions = new String[1]; + ArrayList ilist = (ArrayList)target; + ArrayList ulist = new ArrayList(); + MisoSceneModel model = (MisoSceneModel)this.digester.peek(1); + + // filter interesting and uninteresting into two lists + for (int ii = 0; ii < ilist.size(); ii++) { + ObjectInfo info = (ObjectInfo)ilist.get(ii); + if (!info.isInteresting()) { + ilist.remove(ii--); + ulist.add(info); + } } - // create our object priorities if we don't have 'em - if (model.objectPrios == null) { - model.objectPrios = new byte[model.objectActions.length]; - } + // now populate the model + MisoSceneModel.populateObjects(model, ilist, ulist); } }); } diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java index c0395fd8d..85fda03d7 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java @@ -1,13 +1,16 @@ // -// $Id: MisoSceneWriter.java,v 1.8 2002/09/23 23:07:11 mdb Exp $ +// $Id: MisoSceneWriter.java,v 1.9 2003/01/31 23:10:46 mdb Exp $ -package com.threerings.miso.scene.tools.xml; +package com.threerings.miso.tools.xml; import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + import com.megginson.sax.DataWriter; import com.samskivert.util.StringUtil; -import com.threerings.miso.scene.MisoSceneModel; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; /** * Generates an XML representation of a {@link MisoSceneModel}. @@ -42,11 +45,53 @@ public class MisoSceneWriter writer.dataElement("viewheight", Integer.toString(model.vheight)); writer.dataElement("base", StringUtil.toString(model.baseTileIds, "", "")); - writer.dataElement("object", - StringUtil.toString(model.objectTileIds, "", "")); - writer.dataElement("actions", - StringUtil.joinEscaped(model.objectActions)); - writer.dataElement("priorities", - StringUtil.toString(model.objectPrios, "", "")); + + // write our uninteresting object tile information + writer.startElement("objects"); + for (int ii = 0; ii < model.objectTileIds.length; ii++) { + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(model.objectTileIds[ii])); + attrs.addAttribute("", "x", "", "", + String.valueOf(model.objectXs[ii])); + attrs.addAttribute("", "y", "", "", + String.valueOf(model.objectYs[ii])); + writer.emptyElement("", "object", "", attrs); + } + + // write our uninteresting object tile information + for (int ii = 0; ii < model.objectInfo.length; ii++) { + ObjectInfo info = model.objectInfo[ii]; + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "tileId", "", "", + String.valueOf(info.tileId)); + attrs.addAttribute("", "x", "", "", String.valueOf(info.x)); + attrs.addAttribute("", "y", "", "", String.valueOf(info.y)); + + if (!StringUtil.blank(info.action)) { + attrs.addAttribute("", "action", "", "", info.action); + } + + if (info.priority != 0) { + attrs.addAttribute("", "priority", "", "", + String.valueOf(info.priority)); + } + + if (info.sx != 0 || info.sy != 0) { + attrs.addAttribute("", "sx", "", "", + String.valueOf(info.sx)); + attrs.addAttribute("", "sy", "", "", + String.valueOf(info.sy)); + attrs.addAttribute("", "sorient", "", "", + String.valueOf(info.sorient)); + } + + if (info.zations != 0) { + attrs.addAttribute("", "zations", "", "", + String.valueOf(info.zations)); + } + writer.emptyElement("", "object", "", attrs); + } + writer.endElement("objects"); } } diff --git a/src/java/com/threerings/whirled/spot/server/SpotSceneManager.java b/src/java/com/threerings/whirled/spot/server/SpotSceneManager.java index 081186052..5ee8a3b9b 100644 --- a/src/java/com/threerings/whirled/spot/server/SpotSceneManager.java +++ b/src/java/com/threerings/whirled/spot/server/SpotSceneManager.java @@ -1,5 +1,5 @@ // -// $Id: SpotSceneManager.java,v 1.23 2003/01/18 22:59:17 mdb Exp $ +// $Id: SpotSceneManager.java,v 1.24 2003/01/31 23:10:46 mdb Exp $ package com.threerings.whirled.spot.server; @@ -41,12 +41,12 @@ public class SpotSceneManager extends SceneManager SpotSceneManager mgr = (SpotSceneManager) CrowdServer.plreg.getPlaceManager(body.location); if (mgr != null) { - SpotSceneModel model = (SpotSceneModel) mgr.getSceneModel(); + RuntimeSpotScene scene = (RuntimeSpotScene)mgr.getScene(); try { - mgr.handleChangeLocRequest(body, model.defaultEntranceId); + mgr.handleChangeLocRequest(body, scene.getDefaultEntranceId()); } catch (InvocationException ie) { - Log.warning("Could not walk user to default portal [error=" + - ie + "]."); + Log.warning("Could not walk user to default portal " + + "[error=" + ie + "]."); } } } diff --git a/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java index 8449077c7..8c89b6a6c 100644 --- a/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java +++ b/src/java/com/threerings/whirled/spot/tools/EditableSpotSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: EditableSpotSceneImpl.java,v 1.10 2001/12/16 21:22:31 mdb Exp $ +// $Id: EditableSpotSceneImpl.java,v 1.11 2003/01/31 23:10:46 mdb Exp $ package com.threerings.whirled.tools.spot; @@ -201,6 +201,8 @@ public class EditableSpotSceneImpl extends EditableSceneImpl */ protected void flushToModel () { + super.flushToModel(); + List locations = _delegate.getLocations(); // flush the locations diff --git a/src/java/com/threerings/whirled/tools/EditableSceneImpl.java b/src/java/com/threerings/whirled/tools/EditableSceneImpl.java index 90b76add9..e5137b6ed 100644 --- a/src/java/com/threerings/whirled/tools/EditableSceneImpl.java +++ b/src/java/com/threerings/whirled/tools/EditableSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: EditableSceneImpl.java,v 1.6 2001/12/12 19:06:15 mdb Exp $ +// $Id: EditableSceneImpl.java,v 1.7 2003/01/31 23:10:46 mdb Exp $ package com.threerings.whirled.tools; @@ -121,9 +121,18 @@ public class EditableSceneImpl implements EditableScene // documentation inherited public EditableSceneModel getSceneModel () { + flushToModel(); return _emodel; } + /** + * Derived classes should override this method and flush any editable + * modifications to the scene model when this method is called. + */ + protected void flushToModel () + { + } + /** A reference to our scene model. */ protected SceneModel _model;