summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/WObject.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/WObject.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/WObject.java')
-rw-r--r--NET/worlds/scape/WObject.java1450
1 files changed, 1450 insertions, 0 deletions
diff --git a/NET/worlds/scape/WObject.java b/NET/worlds/scape/WObject.java
new file mode 100644
index 0000000..dd2d26f
--- /dev/null
+++ b/NET/worlds/scape/WObject.java
@@ -0,0 +1,1450 @@
+package NET.worlds.scape;
+
+import NET.worlds.console.Console;
+import NET.worlds.console.Gamma;
+import NET.worlds.console.RightMenu;
+import NET.worlds.core.IniFile;
+import NET.worlds.core.Std;
+import NET.worlds.network.NetworkObject;
+import NET.worlds.network.URL;
+import NET.worlds.network.WorldServer;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+public class WObject extends Transform implements Prerenderable {
+ private boolean mouseOver = false;
+ private String _toolTipText;
+ private Vector<WObject> contents = null;
+ private Shadow shadow;
+ public static boolean shadowsOn = IniFile.gamma().getIniInt("shadows", 0) != 0;
+ protected boolean discarded = false;
+ protected int clumpID;
+ protected int highlightID = 0;
+ protected static final int isVisibleMask = 1;
+ protected static final int isBumpableMask = 2;
+ protected static final int isHologramRoughCutMask = 4;
+ protected static final int isMirrored = 4;
+ protected static final int isOptimizableMask = 8;
+ protected static final int isDrawFirstOnIntersectionMask = 16;
+ protected static final int isDrawOrderUnimportantMask = 32;
+ protected static final int isMaterialVisible = 64;
+ protected static final int isHighlitMask = 128;
+ protected static final int isAutoGapMask = 256;
+ protected static final int isAutoGapFromLocalMask = 512;
+ protected static final int isDisablePixelDoublingMask = 1024;
+ protected static final int isSharerMode0 = 2048;
+ protected static final int isSharerMode1 = 4096;
+ protected static final int isSharerMode2 = 8192;
+ protected static final int duringRestore = 16384;
+ protected static final int isShadowedLocally = 32768;
+ protected static final int isShadowed = 65536;
+ protected static final int isAutobuiltMask = 131072;
+ protected static final int isHologramViewplaneAlignedMask = 262144;
+ protected static final int isDontConnect = 262144;
+ protected static final int isSurfaceUFlippedMask = 524288;
+ protected static final int isSurfaceVFlippedMask = 1048576;
+ protected static final int isReclumpingMask = 2097152;
+ protected static final int isHologramAutosize = 4194304;
+ protected int flags = 3;
+ Vector<Object> eventHandlers;
+ protected Vector<Action> actions = null;
+ protected BumpCalc bumpCalc = null;
+ static BumpCalc standardBoxBumpCalc = new BoxBumpCalc();
+ private static Object classCookie = new Object();
+ public static boolean replaceWithMontyDoor = IniFile.gamma().getIniInt("replaceWithMontyDoor", 0) != 0;
+ private Sharer _sharer = null;
+ public VisiAttribute _visibilityAttribute;
+ public TransAttribute _transformAttribute;
+ public BumpAttribute _bumpableAttribute;
+
+ static {
+ nativeInit();
+ standardBoxBumpCalc.setName("defaultBoxBumpCalc");
+ }
+
+ public static native void nativeInit();
+
+ public boolean getMouseOver() {
+ if (this.mouseOver) {
+ return true;
+ } else {
+ WObject obj;
+ try {
+ obj = (WObject)this.getOwner();
+ } catch (ClassCastException var3) {
+ return false;
+ }
+
+ return obj == null ? false : obj.getMouseOver();
+ }
+ }
+
+ public void setMouseOver(boolean m) {
+ this.mouseOver = m;
+ }
+
+ public String getToolTipText() {
+ if (this._toolTipText != null) {
+ return this._toolTipText;
+ } else {
+ WObject obj;
+ try {
+ obj = (WObject)this.getOwner();
+ } catch (ClassCastException var3) {
+ return null;
+ }
+
+ return obj == null ? null : obj.getToolTipText();
+ }
+ }
+
+ public void setToolTipText(String newText) {
+ this._toolTipText = newText;
+ }
+
+ @Override
+ public void setName(String v) {
+ super.setName(this.getBangName(v));
+ }
+
+ private String getBangName(String s) {
+ boolean hasBang = s.startsWith("!");
+ if (hasBang != this.isDynamic()) {
+ return hasBang ? s.substring(1) : "!" + s;
+ } else {
+ return s;
+ }
+ }
+
+ @Override
+ public void markEdited() {
+ if (!this.isDynamic()) {
+ super.markEdited();
+ }
+ }
+
+ @Override
+ public void getChildren(DeepEnumeration d) {
+ if (this.contents != null) {
+ d.addChildVector(this.contents);
+ }
+
+ if (this.eventHandlers != null) {
+ d.addChildVector(this.eventHandlers);
+ }
+
+ if (this.actions != null) {
+ d.addChildVectorAction(this.actions);
+ }
+
+ if (this._sharer != null) {
+ d.addChildElement(this._sharer);
+ }
+ }
+
+ public void add(WObject child) {
+ super.add(child);
+ if (this.hasClump()) {
+ child.recursiveAddRwChildren(this);
+ }
+
+ if (child._sharer != null) {
+ child._sharer.adjustShare();
+ }
+
+ if (this.contents == null) {
+ this.contents = new Vector<WObject>();
+ }
+
+ this.contents.addElement(child);
+ }
+
+ public Enumeration<?> getContents() {
+ return this.contents == null ? new Vector().elements() : this.contents.elements();
+ }
+
+ public boolean hasContents() {
+ return this.contents != null;
+ }
+
+ public boolean contentsContain(WObject w) {
+ return this.contents == null ? false : this.contents.contains(w);
+ }
+
+ @Override
+ protected void noteUnadding(SuperRoot child) {
+ if (this.contents != null && this.contents.removeElement(child) && this.contents.size() == 0) {
+ this.contents = null;
+ }
+ }
+
+ public void makeShadow() {
+ assert this.shadow == null;
+
+ this.shadow = new DiskShadow(this);
+ }
+
+ @Override
+ public void detach() {
+ if (this.clumpID != 0) {
+ this.markVoid();
+ }
+
+ super.detach();
+ if (this._sharer != null) {
+ this._sharer.adjustShare();
+ }
+
+ if (this.shadow != null) {
+ this.shadow.adjustShadow(this);
+ this.shadow = null;
+ }
+ }
+
+ @Override
+ public void discard() {
+ super.discard();
+ this.discarded = true;
+ if (this.contents != null) {
+ int i = this.contents.size();
+
+ while (--i >= 0) {
+ this.contents.elementAt(i).discard();
+ }
+ }
+
+ if (this.eventHandlers != null) {
+ int i = this.eventHandlers.size();
+
+ while (--i >= 0) {
+ this.removeHandler((SuperRoot)this.eventHandlers.elementAt(i));
+ }
+ }
+
+ if (this.actions != null) {
+ int i = this.actions.size();
+
+ while (--i >= 0) {
+ this.removeAction(this.actions.elementAt(i));
+ }
+ }
+
+ this.releaseAuxilaryData();
+ }
+
+ @Override
+ protected void finalize() {
+ if (!this.discarded) {
+ this.releaseAuxilaryData();
+ }
+
+ super.finalize();
+ }
+
+ public void reclump() {
+ if (this.clumpID != 0) {
+ assert (this.flags & 2097152) == 0;
+
+ this.flags |= 2097152;
+ this.markVoid();
+ this.recursiveAddRwChildren((WObject)this.getOwner());
+
+ assert (this.flags & 2097152) != 0;
+
+ this.flags &= -2097153;
+ }
+ }
+
+ public boolean isReclumping() {
+ return (this.flags & 2097152) != 0;
+ }
+
+ @Override
+ protected void noteTransformChange() {
+ this.setClumpMatrix();
+ this.updateHighlight();
+ if (this.shadow != null) {
+ this.shadow.adjustShadow(this);
+ }
+
+ if (this._transformAttribute != null) {
+ this._transformAttribute.noteChange();
+ }
+ }
+
+ protected void markVoid() {
+ if (this.contents != null) {
+ int i = this.contents.size();
+
+ while (--i >= 0) {
+ this.contents.elementAt(i).markVoid();
+ }
+ }
+
+ Room r = this.getRoomFromClump();
+ if (this instanceof FrameHandler) {
+ r.removeFrameHandler((FrameHandler)this, this);
+ }
+
+ if (this.eventHandlers != null) {
+ int i = this.eventHandlers.size();
+
+ while (--i >= 0) {
+ Object f = this.eventHandlers.elementAt(i);
+ if (f instanceof FrameHandler) {
+ r.removeFrameHandler((FrameHandler)f, this);
+ }
+ }
+ }
+
+ this.voidClump();
+ if (this.shadow != null) {
+ this.shadow.adjustShadow(this);
+ }
+ }
+
+ protected void addRwChildren(WObject parent) {
+ this.addNewRwChild(parent);
+ }
+
+ public void recursiveAddRwChildren(WObject parent) {
+ this.addRwChildren(parent);
+ if (this.contents != null) {
+ int end = this.contents.size();
+
+ for (int i = 0; i < end; i++) {
+ this.contents.elementAt(i).recursiveAddRwChildren(this);
+ }
+ }
+ }
+
+ protected final void addNewRwChild(WObject container) {
+ assert this.clumpID == 0;
+
+ this.createClump();
+ this.newRwClumpChildHelper(container);
+ }
+
+ protected void newRwClumpChildHelper(WObject container) {
+ assert container != null;
+
+ this.addChildToClump(container);
+ this.newRwChildHelper();
+ if (!this.getVisible()) {
+ this.updateVisible();
+ }
+
+ if (this.shadow != null) {
+ this.shadow.adjustShadow(this);
+ } else {
+ if (this.getShadowedLocally() ? !this.getLocalShadowed() : !shadowsOn) {
+ return;
+ }
+
+ if (this.inRoomContents() && this.getOwner() instanceof Room) {
+ this.makeShadow();
+ }
+ }
+ }
+
+ protected void newRwChildHelper() {
+ this.initClumpData();
+ this.setClumpMatrix();
+ Room r = this.getRoom();
+ if (this instanceof FrameHandler) {
+ r.addFrameHandler((FrameHandler)this, this);
+ }
+
+ if (this.eventHandlers != null) {
+ for (int i = 0; i < this.eventHandlers.size(); i++) {
+ Object f = this.eventHandlers.elementAt(i);
+ if (f instanceof FrameHandler) {
+ r.addFrameHandler((FrameHandler)f, this);
+ }
+ }
+ }
+ }
+
+ native void createClump();
+
+ public final boolean hasClump() {
+ return this.clumpID != 0;
+ }
+
+ public final int getID() {
+ return this.clumpID;
+ }
+
+ public native boolean nativeInCamSpace(Camera var1, Point3Temp var2);
+
+ public Point3Temp inCamSpace(Camera cam) {
+ Point3Temp p = Point3Temp.make();
+ return this.nativeInCamSpace(cam, p) ? p : null;
+ }
+
+ protected native void voidClump();
+
+ protected native int extractClump();
+
+ native void addChildToClump(WObject var1);
+
+ native void setClumpMatrix();
+
+ private native void initClumpData();
+
+ native void doneWithEditing();
+
+ native int getNumVerts();
+
+ @Override
+ public Transform getObjectToWorldMatrix() {
+ if (this.hasClump()) {
+ return this.getObjectToWorldMatrix(Transform.make());
+ } else {
+ Transform t = this.getTransform();
+ SuperRoot o = this.getOwner();
+ if (o instanceof WObject) {
+ Transform ot = ((WObject)o).getObjectToWorldMatrix();
+ t.post(ot);
+ ot.recycle();
+ }
+
+ return t;
+ }
+ }
+
+ private native Transform getObjectToWorldMatrix(Transform var1);
+
+ protected native Transform getJointedObjectToWorldMatrix(Transform var1);
+
+ public Point3Temp getWorldPosition() {
+ Transform t = this.getObjectToWorldMatrix();
+ Point3Temp ret = t.getPosition();
+ t.recycle();
+ return ret;
+ }
+
+ public native void updateHighlight();
+
+ public native void getClumpBBox(Point3Temp var1, Point3Temp var2);
+
+ public BoundBoxTemp getClumpBBox() {
+ Point3Temp start = Point3Temp.make();
+ Point3Temp right = Point3Temp.make();
+ this.getClumpBBox(start, right);
+ return BoundBoxTemp.make(start, right);
+ }
+
+ public WObject setHighlit(boolean b) {
+ if (b) {
+ this.flags |= 128;
+ } else {
+ this.flags &= -129;
+ }
+
+ this.updateHighlight();
+ return this;
+ }
+
+ public final boolean getHighlit() {
+ return (this.flags & 128) != 0;
+ }
+
+ public void setAutobuilt(boolean b) {
+ if (b) {
+ this.flags |= 131072;
+ } else {
+ this.flags &= -131073;
+ }
+ }
+
+ public final boolean getAutobuilt() {
+ return (this.flags & 131072) != 0;
+ }
+
+ public WObject setOptimizable(boolean b) {
+ if (b) {
+ this.flags |= 8;
+ } else {
+ this.flags &= -9;
+ }
+
+ return this;
+ }
+
+ public final boolean getOptimizable() {
+ return (this.flags & 8) != 0;
+ }
+
+ final void setSharerMode(int mode) {
+ assert mode >= 0 && mode < 8;
+
+ this.flags &= -14337;
+ this.flags |= mode << 11;
+ this.setName(this.getName());
+ }
+
+ final int getSharerMode() {
+ return this.flags >>> 11 & 7;
+ }
+
+ public final boolean isDynamic() {
+ return (this.getSharerMode() & 4) != 0;
+ }
+
+ public WObject setLocalAutoGap(boolean b) {
+ if (b) {
+ this.flags |= 256;
+ } else {
+ this.flags &= -257;
+ }
+
+ if (this instanceof Room) {
+ Enumeration<Object> e = this.getDeepOwned();
+
+ while (e.hasMoreElements()) {
+ Object o = e.nextElement();
+ if (o instanceof WObject) {
+ ((WObject)o).noteTransformChange();
+ }
+ }
+ }
+
+ return this;
+ }
+
+ public final boolean getLocalAutoGap() {
+ return (this.flags & 256) != 0;
+ }
+
+ public WObject setAutoGapFromRoom(boolean b) {
+ if (b) {
+ this.flags &= -513;
+ } else {
+ this.flags |= 512;
+ }
+
+ this.noteTransformChange();
+ return this;
+ }
+
+ public final boolean getAutoGapFromRoom() {
+ return (this.flags & 512) == 0;
+ }
+
+ public boolean getAutoGap() {
+ return ((WObject)(this.getAutoGapFromRoom() ? this.getRoom() : this)).getLocalAutoGap();
+ }
+
+ public void setVisible(boolean b) {
+ if (b != this.getVisible()) {
+ if (b) {
+ this.flags |= 1;
+ } else {
+ this.flags &= -2;
+ }
+
+ this.updateVisible();
+ if (this.shadow != null) {
+ this.shadow.adjustShadow(this);
+ }
+
+ if (this._visibilityAttribute != null) {
+ this._visibilityAttribute.noteChange();
+ }
+ }
+ }
+
+ public boolean getLocalShadowed() {
+ return (this.flags & 65536) != 0;
+ }
+
+ public void setLocalShadowed(boolean b) {
+ if (b) {
+ this.flags |= 65536;
+ } else {
+ this.flags &= -65537;
+ }
+ }
+
+ public boolean getShadowedLocally() {
+ return (this.flags & 32768) != 0;
+ }
+
+ public void setShadowedLocally(boolean b) {
+ if (b) {
+ this.flags |= 32768;
+ } else {
+ this.flags &= -32769;
+ }
+ }
+
+ protected native void updateVisible();
+
+ public final boolean getVisible() {
+ return (this.flags & 1) != 0;
+ }
+
+ public WObject setBumpable(boolean b) {
+ if (b) {
+ this.flags |= 2;
+ } else {
+ this.flags &= -3;
+ }
+
+ if (this._bumpableAttribute != null) {
+ this._bumpableAttribute.noteChange();
+ }
+
+ return this;
+ }
+
+ public final boolean getBumpable() {
+ return (this.flags & 2) != 0;
+ }
+
+ public boolean deliver(Event event) {
+ event.receiver = this;
+ boolean delivered = event.deliver(this);
+ if (this.eventHandlers != null) {
+ Enumeration<Object> e = this.eventHandlers.elements();
+
+ while (e.hasMoreElements()) {
+ event.receiver = this;
+ if (event.deliver(e.nextElement())) {
+ delivered = true;
+ }
+ }
+ }
+
+ if (delivered) {
+ return true;
+ } else {
+ if (event instanceof UserEvent) {
+ Object o = this.getOwner();
+ if (o instanceof WObject) {
+ return ((WObject)o).deliver(event);
+ }
+ }
+
+ return false;
+ }
+ }
+
+ public Enumeration<Object> getHandlers() {
+ return this.eventHandlers == null ? new Vector<Object>().elements() : this.eventHandlers.elements();
+ }
+
+ public boolean hasHandler(SuperRoot h) {
+ return this.eventHandlers != null && this.eventHandlers.indexOf(h) != -1;
+ }
+
+ public WObject addHandler(SuperRoot h) {
+ if (this.eventHandlers == null) {
+ this.eventHandlers = new Vector<Object>();
+ }
+
+ this.eventHandlers.addElement(h);
+ if (this.clumpID != 0 && h instanceof FrameHandler) {
+ this.getRoomFromClump().addFrameHandler((FrameHandler)h, this);
+ }
+
+ super.add(h);
+ return this;
+ }
+
+ @Override
+ public Room getRoom() {
+ return this.clumpID != 0 ? this.getRoomFromClump() : this.getRoomNotFromClump();
+ }
+
+ public Room getRoomNotFromClump() {
+ SuperRoot o = this.getOwner();
+ return o instanceof WObject ? ((WObject)o).getRoomNotFromClump() : null;
+ }
+
+ public native Room getRoomFromClump();
+
+ public native boolean inRoomContents();
+
+ @Override
+ public World getWorld() {
+ if (this.clumpID != 0) {
+ return this.getRoomFromClump().getWorld();
+ } else {
+ Room r = this.getRoomNotFromClump();
+ return r == null ? null : r.getWorld();
+ }
+ }
+
+ @Override
+ public boolean isActive() {
+ return this.clumpID != 0 ? true : super.isActive();
+ }
+
+ public void removeHandler(SuperRoot h) {
+ if (this.eventHandlers.contains(h)) {
+ h.detach();
+ this.eventHandlers.removeElement(h);
+ if (this.eventHandlers.size() == 0) {
+ this.eventHandlers = null;
+ }
+
+ if (this.clumpID != 0 && h instanceof FrameHandler) {
+ this.getRoomFromClump().removeFrameHandler((FrameHandler)h, this);
+ }
+ }
+ }
+
+ public Enumeration<Action> getActions() {
+ return this.actions == null ? new Vector<Action>().elements() : this.actions.elements();
+ }
+
+ public boolean hasActions() {
+ return this.actions != null;
+ }
+
+ public WObject addAction(Action a) {
+ if (this.actions == null) {
+ this.actions = new Vector<Action>();
+ }
+
+ this.actions.addElement(a);
+ super.add(a);
+ return this;
+ }
+
+ public void removeAction(Action a) {
+ assert a.getOwner() == this;
+
+ a.detach();
+ this.actions.removeElement(a);
+ if (this.actions.size() == 0) {
+ this.actions = null;
+ }
+ }
+
+ public void rightMenu() {
+ new RightMenu(this, this.getActions());
+ }
+
+ public void doAction(String actionLabel, Event evt) {
+ if (actionLabel != null && !actionLabel.equals("")) {
+ if (Gamma.getShaper() != null && actionLabel.equals("Edit Properties...")) {
+ Console.getFrame().getEditTile().viewProperties(this);
+ } else if (this.actions != null) {
+ int i = 0;
+
+ while (i < this.actions.size()) {
+ Action candidate = this.actions.elementAt(i);
+ i++;
+ if (actionLabel.equals(candidate.rightMenuLabel)) {
+ RunningActionHandler.trigger(candidate, this.getWorld(), evt);
+ }
+ }
+ }
+ }
+ }
+
+ public WObject setBumpCalc(BumpCalc b) {
+ if (this.bumpCalc != null) {
+ this.bumpCalc.detach();
+ }
+
+ this.bumpCalc = b;
+ if (this.bumpCalc != null) {
+ super.add(this.bumpCalc);
+ }
+
+ return this;
+ }
+
+ public BumpCalc getBumpCalc(BumpEventTemp b) {
+ return this.bumpCalc == null ? standardBoxBumpCalc : this.bumpCalc;
+ }
+
+ public Point3Temp getPlaneExtent() {
+ return Point3Temp.make();
+ }
+
+ public BoundBoxTemp getBoundBox() {
+ if (this.getVisible()) {
+ return this.getClumpBBox();
+ } else {
+ Transform xfrm = this.getObjectToWorldMatrix();
+ BoundBoxTemp ret = BoundBoxTemp.make(xfrm.getPosition(), this.getPlaneExtent().times(xfrm));
+ xfrm.recycle();
+ return ret;
+ }
+ }
+
+ public float getMinXYExtent() {
+ if (this.getVisible()) {
+ return this.getClumpMinXYExtent();
+ } else {
+ BoundBoxTemp box = this.getBoundBox();
+ float x = box.hi.x - box.lo.x;
+ float y = box.hi.y - box.lo.y;
+ return x < y ? x : y;
+ }
+ }
+
+ public native float getClumpMinXYExtent();
+
+ public void detectBump(BumpEventTemp b) {
+ BoundBoxTemp box = this.getBoundBox();
+ if (!box.isEmpty() && b.bound.overlaps(box)) {
+ this.getBumpCalc(b).detectBump(b, this);
+ }
+
+ if (this.contents != null) {
+ int i = this.contents.size();
+
+ while (--i >= 0) {
+ WObject w = this.contents.elementAt(i);
+ if (w.getBumpable() && b.source != w) {
+ w.detectBump(b);
+ }
+ }
+ }
+ }
+
+ public void premoveThrough(Point3Temp motion) {
+ Point3Temp pos = this.getPosition();
+ this.moveThrough(Point3Temp.make(motion).times(this).minus(pos));
+ }
+
+ public void moveThrough(Point3Temp motion) {
+ if (this.getRoom() == null || !this.getBumpable()) {
+ this.moveBy(motion);
+ } else if (this.getRoom().hasClump()) {
+ int now = Std.getRealTime();
+ WObject me = this;
+
+ for (int loopCount = 4; loopCount > 0; loopCount--) {
+ BumpEventTemp be = BumpEventTemp.make(now, me, motion);
+
+ try {
+ if (be.target == null) {
+ me.moveBy(be.fullPath);
+ break;
+ }
+
+ be.postBumpRoom = me.getRoom();
+ be.postBumpPosition = me.getObjectToWorldMatrix().moveBy(be.path);
+ be.postBumpPath = Point3Temp.make(be.fullPath).times(1.0F - be.fraction);
+ Transform t = me.getTransform();
+
+ try {
+ Room r = this.getRoom();
+ be.target.deliver(be);
+ me.deliver(be);
+ if (!me.isTransformEqual(t) || r != this.getRoom()) {
+ break;
+ }
+ } finally {
+ t.recycle();
+ }
+
+ Transform invPos = be.postBumpRoom.getObjectToWorldMatrix();
+ invPos.invert();
+ if (me.getRoom() != be.postBumpRoom) {
+ invPos.pre(be.postBumpPosition);
+ me = me.changeRoom(be.postBumpRoom, invPos);
+ if (me == null) {
+ break;
+ }
+ } else {
+ me.makeIdentity();
+ me.pre(invPos);
+ me.pre(be.postBumpPosition);
+ }
+
+ be.postBumpPosition.recycle();
+ be.postBumpPosition = null;
+ invPos.recycle();
+ motion = be.postBumpPath;
+ } finally {
+ be.recycle();
+ }
+ }
+ }
+ }
+
+ protected WObject changeRoom(Room newRoom, Transform invPos) {
+ this.detach();
+ newRoom.add(this);
+ this.makeIdentity();
+ this.pre(invPos);
+ return this;
+ }
+
+ @Override
+ public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException {
+ Object ret = null;
+ switch (index - offset) {
+ case 0:
+ if (mode == 0) {
+ ret = PropAdder.make(new VectorProperty(this, index, "Contents"));
+ } else if (mode == 1) {
+ if (this.contents != null) {
+ ret = this.contents.clone();
+ }
+ } else if (mode == 4) {
+ ((WObject)value).detach();
+ } else if (mode == 3) {
+ this.add((WObject)value);
+ } else if (mode == 5 && value instanceof WObject && !(value instanceof Room)) {
+ ret = value;
+ }
+ break;
+ case 1:
+ if (mode == 0) {
+ ret = PropAdder.make(new VectorProperty(this, index, "Event Handlers"));
+ } else if (mode == 1) {
+ if (this.eventHandlers != null) {
+ ret = this.eventHandlers.clone();
+ }
+ } else if (mode == 4) {
+ this.removeHandler((SuperRoot)value);
+ } else if (mode == 3) {
+ this.addHandler((SuperRoot)value);
+ } else if (mode == 5 && (value instanceof SwitchableBehavior || value instanceof Sensor)) {
+ ret = value;
+ }
+ break;
+ case 2:
+ if (mode == 0) {
+ ret = PropAdder.make(new VectorProperty(this, index, "Actions"));
+ } else if (mode == 1) {
+ if (this.actions != null) {
+ ret = this.actions.clone();
+ }
+ } else if (mode == 4) {
+ this.removeAction((Action)value);
+ } else if (mode == 3) {
+ this.addAction((Action)value);
+ } else if (mode == 5 && value instanceof Action) {
+ ret = value;
+ }
+ break;
+ case 3:
+ if (mode == 0) {
+ ret = BooleanPropertyEditor.make(new Property(this, index, "Bumpable"), "No", "Yes");
+ } else if (mode == 1) {
+ ret = new Boolean(this.getBumpable());
+ } else if (mode == 2) {
+ this.setBumpable((Boolean)value);
+ }
+ break;
+ case 4:
+ if (mode == 0) {
+ ret = BooleanPropertyEditor.make(new Property(this, index, "Visible"), "No", "Yes");
+ } else if (mode == 1) {
+ ret = new Boolean(this.getVisible());
+ } else if (mode == 2) {
+ this.setVisible((Boolean)value);
+ }
+ break;
+ case 5:
+ if (mode == 0) {
+ ret = IntegerPropertyEditor.make(new Property(this, index, "Sharing Mode (100 for help)", true));
+ } else if (mode == 1) {
+ ret = new Integer(this.getSharerMode());
+ } else if (mode == 2) {
+ int val = (Integer)value;
+ if (this instanceof Room && val >= 0 && val <= 5) {
+ Console.println("A Room's sharing mode\nmust be 2, and is\nautomatically set by the shaper.");
+ } else if (val != 0 && val != 3 && val != 5) {
+ Console.println("0 = default (chooses 2 or 3 for you)");
+ Console.println("2 = static (stored in .world)");
+ Console.println("3 = forwarded static");
+ Console.println("4 = dynamic (stored only on server)");
+ Console.println("5 = forwarded dynamic");
+ Console.println("Modes 2, and 4, are not generally\nsupported, except that mode 2\nis required for Rooms");
+ } else if (val == 5 && this.getSourceURL() == null) {
+ Console.println("Only WObjects read from files may be forwarded dynamic.");
+ } else {
+ this.getSharer().setMode(val);
+ }
+ }
+ break;
+ case 6:
+ if (mode == 0) {
+ ret = PropAdder.make(new VectorProperty(this, index, "Shared Attributes"));
+ } else if (mode == 1) {
+ if (this._sharer != null) {
+ ret = this._sharer.getAttributesList();
+ } else {
+ ret = new Vector();
+ }
+ } else if (mode == 4) {
+ this.removeShareableAttribute((Attribute)value);
+ } else if (mode == 3) {
+ this.addShareableAttribute((Attribute)value);
+ } else if (mode == 5 && value instanceof Attribute) {
+ ret = value;
+ }
+ break;
+ case 7:
+ if (mode == 0) {
+ ret = StringPropertyEditor.make(new Property(this, index, "Tool Tip Text"));
+ } else if (mode == 1) {
+ ret = this.getToolTipText();
+ } else if (mode == 2) {
+ this.setToolTipText((String)value);
+ }
+ break;
+ case 8:
+ if (mode == 0) {
+ ret = BooleanPropertyEditor.make(new Property(this, index, "Mouse Change"), "No", "Yes");
+ } else if (mode == 1) {
+ ret = new Boolean(this.getMouseOver());
+ } else if (mode == 2) {
+ this.setMouseOver((Boolean)value);
+ }
+ break;
+ default:
+ ret = super.properties(index, offset + 9, mode, value);
+ }
+
+ return ret;
+ }
+
+ public static void saveUnsharedWObjects(Saver s, Vector<WObject> v) throws IOException {
+ int length = 0;
+ Enumeration<WObject> en = v.elements();
+
+ while (en.hasMoreElements()) {
+ WObject w = en.nextElement();
+ if (w instanceof Persister && !(w instanceof NonPersister) && !w.isDynamic()) {
+ length++;
+ }
+ }
+
+ s.saveInt(length);
+ en = v.elements();
+
+ while (en.hasMoreElements()) {
+ WObject w = en.nextElement();
+ if (w instanceof Persister && !(w instanceof NonPersister) && !w.isDynamic()) {
+ s.save(w);
+ }
+ }
+ }
+
+ @Override
+ public void saveState(Saver s) throws IOException {
+ s.saveVersion(10, classCookie);
+ super.saveState(s);
+ s.saveInt(this.flags & -129);
+ if (this.contents == null) {
+ s.saveBoolean(false);
+ } else {
+ s.saveBoolean(true);
+ saveUnsharedWObjects(s, this.contents);
+ }
+
+ s.saveVectorMaybeNull(this.eventHandlers);
+ s.saveVectorMaybeNull(this.actions);
+ s.saveMaybeNull(this.bumpCalc);
+ if (this._sharer != null && this._sharer.isEmpty()) {
+ s.saveMaybeNull(null);
+ } else {
+ s.saveMaybeNull(this._sharer);
+ }
+
+ s.saveString(this.getToolTipText());
+ s.saveBoolean(this.getMouseOver());
+ }
+
+ @Override
+ public void restoreState(Restorer r) throws IOException, TooNewException {
+ this.restoreWObjectState(r);
+ }
+
+ public void restoreWObjectState(Restorer r) throws IOException, TooNewException {
+ Vector<Object> newContents = null;
+ Vector<Object> newActions = null;
+ Vector<Object> newHandlers = null;
+ int vers = r.restoreVersion(classCookie);
+ switch (vers) {
+ case 0:
+ r.setOldFlag();
+ super.restoreState(r);
+ this.flags = r.restoreInt();
+ r.restoreMaybeNull();
+ this.flags |= 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = new Vector<Object>();
+ break;
+ case 1:
+ r.setOldFlag();
+ super.restoreState(r);
+ this.flags = r.restoreInt();
+ r.restoreMaybeNull();
+ this.flags |= 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ break;
+ case 2:
+ r.setOldFlag();
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ break;
+ case 3:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ r.restore();
+ break;
+ case 4:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ r.restore();
+ this._sharer = (Sharer)r.restoreMaybeNull();
+ break;
+ case 5:
+ case 7:
+ case 8:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ this.setBumpCalc((BumpCalc)r.restoreMaybeNull());
+ this._sharer = (Sharer)r.restoreMaybeNull();
+ break;
+ case 6:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ this.setBumpCalc((BumpCalc)r.restoreMaybeNull());
+ this._sharer = (Sharer)r.restoreMaybeNull();
+ r.restoreString();
+ break;
+ case 9:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ this.setBumpCalc((BumpCalc)r.restoreMaybeNull());
+ this._sharer = (Sharer)r.restoreMaybeNull();
+ this.setToolTipText(r.restoreString());
+ break;
+ case 10:
+ super.restoreState(r);
+ this.flags = r.restoreInt() | 16384;
+ newContents = r.restoreVectorMaybeNull();
+ newHandlers = r.restoreVectorMaybeNull();
+ newActions = r.restoreVectorMaybeNull();
+ this.setBumpCalc((BumpCalc)r.restoreMaybeNull());
+ this._sharer = (Sharer)r.restoreMaybeNull();
+ this.setToolTipText(r.restoreString());
+ this.setMouseOver(r.restoreBoolean());
+ break;
+ default:
+ throw new TooNewException();
+ }
+
+ if (vers < 8) {
+ this.flags &= -65;
+ }
+
+ if (newContents != null) {
+ for (int i = 0; i < newContents.size(); i++) {
+ this.add((WObject)newContents.elementAt(i));
+ }
+ }
+
+ if (newActions != null) {
+ for (int i = 0; i < newActions.size(); i++) {
+ this.addAction((Action)newActions.elementAt(i));
+ }
+ }
+
+ if (newHandlers != null) {
+ for (int i = 0; i < newHandlers.size(); i++) {
+ this.addHandler((SuperRoot)newHandlers.elementAt(i));
+ }
+ }
+
+ if (this._sharer != null) {
+ super.add(this._sharer);
+ }
+ }
+
+ @Override
+ public void postRestore(int version) {
+ super.postRestore(version);
+ if (version < 7) {
+ Enumeration<Object> en = this.getHandlers();
+
+ while (en.hasMoreElements()) {
+ SuperRoot h = (SuperRoot)en.nextElement();
+ if (h.getOwner() != this) {
+ SuperRoot newH = (SuperRoot)h.clone();
+ this.eventHandlers.removeElement(h);
+ if (this.eventHandlers.size() == 0) {
+ this.eventHandlers = null;
+ }
+
+ if (this.clumpID != 0 && h instanceof FrameHandler) {
+ this.getRoomFromClump().removeFrameHandler((FrameHandler)h, this);
+ }
+
+ this.addHandler(newH);
+ }
+ }
+ }
+
+ if (replaceWithMontyDoor && this.getClass() == WObject.class) {
+ this.replaceMonty();
+ }
+
+ if (this._sharer != null) {
+ this._sharer.ownerPostRestore();
+ }
+
+ this.flags &= -16385;
+ if (this.isDynamic()) {
+ this.getSharer();
+ }
+ }
+
+ private void replaceMonty() {
+ if (this.actions != null && this.actions.size() == 3 && this.getOwner() instanceof WObject) {
+ int stage = 0;
+
+ try {
+ if (this.actions.elementAt(0) instanceof SetURLAction) {
+ SetURLAction sua = (SetURLAction)this.actions.elementAt(0);
+ if (sua._propName.equals("File") && sua._roomName != null) {
+ stage = 1;
+ Object db = this.actions.elementAt(1);
+ Object cancel = this.actions.elementAt(2);
+ if (db instanceof DialogAction && cancel.getClass() == db.getClass() && ((DialogAction)cancel).cancelOnly != ((DialogAction)db).cancelOnly) {
+ if (((DialogAction)db).cancelOnly) {
+ db = cancel;
+ }
+
+ stage = 2;
+ if (this.actions.elementAt(0) instanceof SetURLAction) {
+ stage = 3;
+ if (this.contents != null
+ && this.contents.size() >= 2
+ && this.contents.size() <= 3
+ && this.contents.elementAt(0).getClass() == Rect.class
+ && this.contents.elementAt(1).getClass() == Portal.class) {
+ stage = 4;
+ boolean isTwoPart = this.contents.size() == 3;
+ Rect top = (Rect)this.contents.elementAt(0);
+ Portal port = (Portal)this.contents.elementAt(1);
+ Rect bottom = null;
+ if (isTwoPart) {
+ if (this.contents.elementAt(2).getClass() != Rect.class) {
+ return;
+ }
+
+ bottom = (Rect)this.contents.elementAt(2);
+ }
+
+ stage = 5;
+ if (top.eventHandlers != null && top.eventHandlers.size() == 1 && top.eventHandlers.elementAt(0).getClass() == ClickSensor.class) {
+ stage = 6;
+ ClickSensor cs = (ClickSensor)top.eventHandlers.elementAt(0);
+ if (cs.countActions() == 1) {
+ stage = 7;
+ if (top.actions != null && top.actions.size() == 3 && top.actions.elementAt(2).getClass() == SequenceAction.class) {
+ stage = 8;
+ SequenceAction seq = (SequenceAction)top.actions.elementAt(2);
+ if (seq.actions != null && seq.actions.size() == (isTwoPart ? 9 : 7)) {
+ stage = 9;
+ if (port.actions != null && port.actions.size() == 2 && port._farSideRoomName != null && port._farSidePortalName != null
+ )
+ {
+ stage = 10;
+ URL texture = (isTwoPart ? bottom : top).getMaterial().textureName;
+ if (texture != null) {
+ stage = 11;
+ MontyDoor md = new MontyDoor();
+ md.setsAvatar = db instanceof SelectAvatarAction;
+ if (!md.setsAvatar) {
+ if (!(db instanceof SendURLAction)) {
+ return;
+ }
+
+ md.description = ((SendURLAction)db).description;
+ md.url = ((SendURLAction)db).destination;
+ } else {
+ md.url = ((SelectAvatarAction)db).url;
+ }
+
+ stage = 12;
+ md.viewURL = sua._value;
+ md.viewName = sua._targetName;
+ md.setFarSideInfo(null, sua._roomName, port._farSidePortalName);
+ md.post(port);
+ md.post(this);
+ String texName = texture.getInternal();
+ if (isTwoPart) {
+ if (!texName.endsWith("b.cmp")) {
+ Console.println("Texture: " + texName);
+ return;
+ }
+
+ int len = texName.length();
+ texName = texName.substring(0, len - 5) + "m2v*.mov";
+ }
+
+ stage = 13;
+ md.setMaterial(new Material(URL.make(texName)));
+ ((WObject)this.getOwner()).add(md);
+ this.detach();
+ port.detach();
+ md.reset();
+ stage = 100;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ if (stage != 100) {
+ Console.println("Failed MontyDoor conversion of " + this.getName() + " in stage " + stage + ".\n");
+ }
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ String base = this.getName();
+ if (!this.isActive()) {
+ base = base + "(inactive)";
+ }
+
+ base = base + this.toTransformSubstring();
+ return this.contents == null ? base : base + this.contents.toString();
+ }
+
+ public static String getSaveExtension() {
+ return "wob";
+ }
+
+ public WObject getServed() {
+ int mode = this.getSharerMode();
+ if (mode == 0) {
+ Sharer s = this.getSharer();
+ if (s != null) {
+ mode = s.getMode();
+ }
+ }
+
+ if ((mode & 1) == 0) {
+ return this;
+ } else {
+ SuperRoot r = this.getOwner();
+ return r != null && r instanceof WObject ? ((WObject)r).getServed() : null;
+ }
+ }
+
+ @Override
+ public void prerender(Camera cam) {
+ WorldScriptManager.getInstance().onPrerender(this, cam);
+ }
+
+ public WorldServer getServer() {
+ WObject wo = this.getServed();
+ NetworkObject no;
+ if (wo instanceof Room) {
+ no = ((Room)wo).getNetworkRoom();
+ } else {
+ no = (NetworkObject)wo;
+ }
+
+ if (no == null) {
+ return null;
+ } else {
+ assert no != this;
+
+ return no.getServer();
+ }
+ }
+
+ public Enumeration<Attribute> getAttributes() {
+ return this.getSharer().getAttributes();
+ }
+
+ public Sharer getSharer() {
+ if (this._sharer == null) {
+ assert (this.flags & 16384) == 0;
+
+ this._sharer = new Sharer();
+ super.add(this._sharer);
+ }
+
+ return this._sharer;
+ }
+
+ public boolean hasSharer() {
+ return this._sharer != null;
+ }
+
+ public Attribute getAttribute(int attrID) {
+ return this.getSharer().getAttribute(attrID);
+ }
+
+ public int addAttribute(Attribute a) {
+ return this.getSharer().addAttribute(a);
+ }
+
+ public int addShareableAttribute(Attribute a) {
+ return this.addAttribute(a);
+ }
+
+ public void removeAttribute(Attribute a) {
+ this.getSharer().removeAttribute(a);
+ }
+
+ public void removeShareableAttribute(Attribute a) {
+ this.removeAttribute(a);
+ }
+
+ public boolean isShared() {
+ return this._sharer != null;
+ }
+
+ public void notifyRegister(int wid) {
+ }
+
+ public boolean acceptsLeftClicks() {
+ return this.getMouseOver();
+ }
+
+ public void releaseAuxilaryData() {
+ if (this._sharer != null) {
+ this._sharer.releaseAuxilaryData();
+ }
+ }
+}