diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/Room.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/Room.java')
| -rw-r--r-- | NET/worlds/scape/Room.java | 996 |
1 files changed, 996 insertions, 0 deletions
diff --git a/NET/worlds/scape/Room.java b/NET/worlds/scape/Room.java new file mode 100644 index 0000000..a10305c --- /dev/null +++ b/NET/worlds/scape/Room.java @@ -0,0 +1,996 @@ +package NET.worlds.scape; + +import NET.worlds.console.Main; +import NET.worlds.core.Std; +import NET.worlds.network.Galaxy; +import NET.worlds.network.NetworkRoom; +import java.awt.Color; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class Room extends WObject implements TeleportStatus { + public WObject highlightTarget; + private int sceneID; + public Point3 defaultPosition = new Point3(100.0F, 100.0F, 120.0F); + public Point3 defaultOrientationAxis = new Point3(0.0F, 0.0F, -1.0F); + public float defaultOrientation = 0.0F; + String teleportChain = "home:avatargallery/avatar.world#[email protected],145.0,150.0,89.0"; + int roomLoadTime = 0; + int teleportInterval = -1; + boolean teleported = false; + private RoomEnvironment environment; + private Vector<Portal> outgoingPortals = new Vector<Portal>(); + private Vector<AudibilityFilter> aFilters = new Vector<AudibilityFilter>(); + private Point3 lightPosition = new Point3(-1.0F, 1.0F, -1.0F); + private Color lightColor = new Color(255, 255, 255); + private int lightid = 0; + private int lightid2 = 0; + private int renderStamp; + private static int timeoutAge = 15000; + private Vector<FrameHandler> frameHandlers = new Vector<FrameHandler>(); + private Vector<WObject> frameHandlerWObjects = new Vector<WObject>(); + private Color skyColor; + private Color groundColor; + private Vector<Prerenderable> prerenderHandlers = new Vector<Prerenderable>(); + private Vector<Postrenderable> postrenderHandlers = new Vector<Postrenderable>(); + private static int isRendering = 4; + private static int isVIPOnly = 262144; + private static int isVIPViewOnly = 524288; + private NetworkRoom _netRoom; + private static String[] skyOptions = new String[]{"Blue Sky"}; + private static String[] groundOptions = new String[]{"Green Ground"}; + private boolean allowTeleport = true; + private static Object classCookie = new Object(); + private RoomEnvironment infiniteBackground; + + static { + nativeInit(); + } + + public Room(World world, String name) { + this.setName(name); + this.environment = new RoomEnvironment(); + this.infiniteBackground = new RoomEnvironment(); + super.add(this.environment); + super.add(this.infiniteBackground); + if (world != null) { + world.addRoom(this); + } + } + + public Room() { + } + + public static native void nativeInit(); + + @Override + public void getChildren(DeepEnumeration d) { + if (this.infiniteBackground != null) { + d.addChildElement(this.infiniteBackground); + } + + if (this.environment != null) { + d.addChildElement(this.environment); + } + + super.getChildren(d); + } + + @Override + public void setName(String newName) { + String oldName = this.getName(); + super.setName(newName); + World world = this.getWorld(); + if (world != null) { + world.renameRoom(oldName, this.getName(), this); + } + + if (!oldName.equals(newName)) { + synchronized (this) { + if (this._netRoom != null) { + this._netRoom.setName(newName); + } + } + } + } + + synchronized void register() { + assert this._netRoom == null; + + this._netRoom = new NetworkRoom(this); + } + + @Override + public void detach() { + if (this.hasClump()) { + System.out.println("Detaching clumped room " + this.getName()); + this.markVoid(); + } + + assert this._netRoom != null; + + boolean subscribed = Pilot.getActive().removeSubscribedRoom(this); + if (subscribed) { + this._netRoom.unsubscribe(); + } + + synchronized (this) { + this._netRoom.detach(); + this._netRoom = null; + } + + this.getWorld().removeRoom(this); + super.detach(); + } + + @Override + public void discard() { + this.environment.discard(); + this.infiniteBackground.discard(); + super.discard(); + this.frameHandlers.removeAllElements(); + this.frameHandlerWObjects.removeAllElements(); + this.outgoingPortals.removeAllElements(); + this.aFilters.removeAllElements(); + this.prerenderHandlers.removeAllElements(); + this.postrenderHandlers.removeAllElements(); + } + + int getSceneID() { + return this.sceneID; + } + + public Point3Temp getDefaultPosition() { + return Point3Temp.make(this.defaultPosition); + } + + public Point3Temp getDefaultOrientationAxis() { + return Point3Temp.make(this.defaultOrientationAxis); + } + + public float getDefaultOrientation() { + return this.defaultOrientation; + } + + @Override + protected final void noteAddingTo(SuperRoot s) { + World w = (World)s; + } + + public RoomEnvironment getEnvironment() { + return this.environment; + } + + public Vector<Portal> getOutgoingPortals() { + return this.outgoingPortals; + } + + public void addOutgoingPortal(Portal p) { + if (!this.outgoingPortals.contains(p)) { + this.outgoingPortals.addElement(p); + + for (int index = 0; index < this.aFilters.size(); index++) { + this.aFilters.elementAt(index).moveEmitter(); + } + } + } + + public void removeOutgoingPortal(Portal p) { + this.outgoingPortals.removeElement(p); + Vector<AudibilityFilter> v = this.getAFilters(); + + for (int v_index = 0; v_index < v.size(); v_index++) { + v.elementAt(v_index).moveEmitter(); + } + } + + public Vector<AudibilityFilter> getAFilters() { + return this.aFilters; + } + + public void addAFilter(AudibilityFilter p) { + this.aFilters.addElement(p); + } + + public void removeAFilter(AudibilityFilter a) { + this.aFilters.removeElement(a); + } + + public void move(Room from, Room to) { + Vector<AudibilityFilter> v = from.getAFilters(); + + for (int index = 0; index < v.size(); index++) { + v.elementAt(index).updateListenerState(); + } + + v = to.getAFilters(); + + for (int index = 0; index < v.size(); index++) { + v.elementAt(index).updateListenerState(); + } + } + + static native int addLight(int var0, float var1, float var2, float var3, float var4, float var5, float var6); + + static native void setLightPosition(int var0, float var1, float var2, float var3); + + static native void setLightColor(int var0, float var1, float var2, float var3); + + private void setLightPosition(float x, float y, float z) { + if (this.lightid != 0) { + setLightPosition(this.lightid, x, y, z); + } + + if (this.lightid2 != 0) { + setLightPosition(this.lightid2, -x, -y, -z); + } + } + + private void setLightColor(float red, float green, float blue) { + if (this.lightid != 0) { + setLightColor(this.lightid, red, green, blue); + } + + if (this.lightid2 != 0) { + setLightColor(this.lightid2, red / 2.0F, green / 2.0F, blue / 2.0F); + } + } + + public void setLightPosition(Point3Temp p) { + this.lightPosition.set(p.x, p.y, p.z); + this.setLightPosition(p.x, p.y, p.z); + RoomEnvironment re = this.getEnvironment(); + if (re != null) { + re.setLightPosition(p.x, p.y, p.z); + } + + re = this.getInfiniteBackground(); + if (re != null) { + re.setLightPosition(p.x, p.y, p.z); + } + } + + public void setLightColor(Color c) { + this.lightColor = new Color(c.getRGB()); + float r = c.getRed() / 256.0F; + float g = c.getGreen() / 256.0F; + float b = c.getBlue() / 256.0F; + this.setLightColor(r, g, b); + RoomEnvironment re = this.getEnvironment(); + if (re != null) { + re.setLightColor(r, g, b); + } + + re = this.getInfiniteBackground(); + if (re != null) { + re.setLightColor(r, g, b); + } + } + + public Point3Temp getLightPosition() { + return Point3Temp.make(this.lightPosition); + } + + public Color getLightColor() { + return new Color(this.lightColor.getRGB()); + } + + public void noteRef() { + this.renderStamp = Std.getRealTime(); + World w = this.getWorld(); + if (w != null) { + w.incRef(); + } + } + + public void discardIfOld() { + if (this.hasClump()) { + int age = Std.getFastTime() - this.renderStamp; + if (age > timeoutAge) { + this.markVoid(); + } + } + } + + public void generateFrameEvents(FrameEvent f) { + this.noteRef(); + if (Main.profile != 0) { + for (int i = 0; i < this.frameHandlers.size(); i++) { + FrameHandler fh = this.frameHandlers.elementAt(i); + WObject fhw = this.frameHandlerWObjects.elementAt(i); + int start = Std.getRealTime(); + long startBytes = Runtime.getRuntime().freeMemory(); + f.retargetAndDeliver(fh, fhw); + int dur = Std.getRealTime() - start; + long used = startBytes - Runtime.getRuntime().freeMemory(); + if (dur > Main.profile) { + if (fh instanceof SuperRoot) { + System.out.println("Took " + dur + "ms and " + used + " bytes to call frameHandler " + ((SuperRoot)fh).getName() + " of " + fhw.getName()); + } else { + System.out.println("Took " + dur + "ms and " + used + " bytes to call frameHandler " + fh + " of " + fhw.getName()); + } + } + } + } else { + for (int ix = 0; ix < this.frameHandlers.size(); ix++) { + f.retargetAndDeliver(this.frameHandlers.elementAt(ix), this.frameHandlerWObjects.elementAt(ix)); + } + } + + if (this.teleportChain != null && this.teleportInterval != -1 && !this.teleported && Std.getSynchronizedTime() % this.teleportInterval == 0) { + this.teleported = true; + TeleportAction.teleport(this.teleportChain, this); + } + } + + @Override + public void teleportStatus(String err, String dest) { + if (err != null) { + this.teleported = false; + } + } + + private int findFrameHandler(FrameHandler h, WObject o) { + int next = 0; + + while (true) { + next = this.frameHandlers.indexOf(h, next); + if (next == -1) { + return -1; + } + + if (this.frameHandlerWObjects.elementAt(next) == o) { + return next; + } + + next++; + } + } + + void addFrameHandler(FrameHandler h, WObject o) { + int i = this.findFrameHandler(h, o); + if (i < 0) { + this.frameHandlers.addElement(h); + this.frameHandlerWObjects.addElement(o); + } + } + + void removeFrameHandler(FrameHandler h, WObject o) { + int i = this.findFrameHandler(h, o); + if (i >= 0) { + this.frameHandlers.removeElementAt(i); + this.frameHandlerWObjects.removeElementAt(i); + } + } + + native void createScene(); + + native void destroyScene(); + + @Override + protected void markVoid() { + this.infiniteBackground.markVoid(); + this.environment.markVoid(); + super.markVoid(); + this.destroyScene(); + this.lightid = 0; + this.lightid2 = 0; + } + + @Override + protected void noteTransformChange() { + super.noteTransformChange(); + this.getInfiniteBackground().setTransform(this); + this.getEnvironment().setTransform(this); + int i = this.outgoingPortals.size(); + + while (--i >= 0) { + this.outgoingPortals.elementAt(i).discardTransform(); + } + } + + public void setSkyColor(Color c) { + this.skyColor = c; + } + + public Color getSkyColor() { + return this.skyColor; + } + + public void setGroundColor(Color c) { + this.groundColor = c; + } + + public Color getGroundColor() { + return this.groundColor; + } + + public boolean getVIPOnly() { + return (this.flags & isVIPOnly) != 0; + } + + public void prerender(Camera cam, float x, float y, float z, float d) { + this.flags = this.flags | isRendering; + this.infiniteBackground.prerender(); + this.environment.prerender(); + Pilot.addVisibleRoom(this, x, y, z, d); + int end = this.prerenderHandlers.size(); + + for (int i = 0; i < end; i++) { + Prerenderable p = this.prerenderHandlers.elementAt(i); + p.prerender(cam); + } + } + + public void addPrerenderHandler(Prerenderable o) { + assert (this.flags & isRendering) == 0; + + if (!this.prerenderHandlers.contains(o)) { + this.prerenderHandlers.addElement(o); + } + } + + public void prependPrerenderHandler(Prerenderable o) { + assert (this.flags & isRendering) == 0; + + if (!this.prerenderHandlers.contains(o)) { + this.prerenderHandlers.insertElementAt(o, 0); + } + } + + public void removePrerenderHandler(Prerenderable o) { + assert (this.flags & isRendering) == 0; + + this.prerenderHandlers.removeElement(o); + } + + public void postrender(Camera cam, float x, float y, float z, float d) { + Pilot.addVisibleRoom(this, x, y, z, d); + int i = this.postrenderHandlers.size(); + + while (--i >= 0) { + Postrenderable p = this.postrenderHandlers.elementAt(i); + p.postrender(cam); + } + + this.flags = this.flags & ~isRendering; + } + + public void addPostrenderHandler(Postrenderable o) { + assert (this.flags & isRendering) == 0; + + if (!this.postrenderHandlers.contains(o)) { + this.postrenderHandlers.addElement(o); + } + } + + public void prependPostrenderHandler(Postrenderable o) { + assert (this.flags & isRendering) == 0; + + if (!this.postrenderHandlers.contains(o)) { + this.postrenderHandlers.insertElementAt(o, 0); + } + } + + public void removePostrenderHandler(Postrenderable o) { + assert (this.flags & isRendering) == 0; + + this.postrenderHandlers.removeElement(o); + } + + @Override + public void detectBump(BumpEventTemp b) { + if (this.environment.getBumpable()) { + this.environment.detectBump(b); + } + + super.detectBump(b); + } + + @Override + public BoundBoxTemp getBoundBox() { + return BoundBoxTemp.make(Point3Temp.make(), Point3Temp.make()); + } + + @Override + public World getWorld() { + return (World)this.getOwner(); + } + + @Override + public Room getRoom() { + return this; + } + + @Override + public Room getRoomFromClump() { + return this; + } + + @Override + public Room getRoomNotFromClump() { + return this; + } + + public Galaxy getGalaxy() { + World w = this.getWorld(); + return w == null ? null : w.getConsole().getGalaxy(); + } + + public String getURL() { + return this.getWorld().getSourceURL().getAbsolute() + "#" + this.getName(); + } + + public boolean registerShare(WObject w) { + w.notifyRegister(1); + return true; + } + + private void processPendingRegistrations() { + this.notifyRegister(1); + } + + public NetworkRoom getNetworkRoom() { + return this._netRoom; + } + + void subscribe(RoomSubscribeInfo info) { + assert this._netRoom != null; + + this._netRoom.subscribe(info); + } + + void subscribeDist(RoomSubscribeInfo info) { + assert this._netRoom != null; + + this._netRoom.subscribeDist(info); + } + + void unsubscribe() { + if (this._netRoom != null) { + this._netRoom.unsubscribe(); + } else { + System.out.println(this + ": unsubscribing from bad room?"); + new Exception().printStackTrace(System.out); + } + } + + public boolean getAllowTeleport() { + return this.allowTeleport; + } + + @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 = new Property(this, index, "Environment"); + } else if (mode == 1) { + ret = this.environment; + } + break; + case 1: + if (mode == 0) { + ret = new Property(this, index, "Infinite Background"); + } else if (mode == 1) { + ret = this.infiniteBackground; + } + break; + case 2: + if (mode == 0) { + ret = ColorPropertyEditor.make(new Property(this, index, "Sky Color").allowSetNull()); + if (this.getSkyColor() == null) { + ret = MaybeNullPropertyEditor.make((Property)ret, Color.blue); + } + } else if (mode == 1) { + ret = this.getSkyColor(); + } else if (mode == 2) { + this.setSkyColor((Color)value); + } + break; + case 3: + if (mode == 0) { + ret = ColorPropertyEditor.make(new Property(this, index, "Ground Color").allowSetNull()); + if (this.getGroundColor() == null) { + ret = MaybeNullPropertyEditor.make((Property)ret, Color.green); + } + } else if (mode == 1) { + ret = this.getGroundColor(); + } else if (mode == 2) { + this.setGroundColor((Color)value); + } + break; + case 4: + if (mode == 0) { + ret = Point3PropertyEditor.make(new Property(this, index, "Default Position")); + } else if (mode == 1) { + ret = new Point3(this.getDefaultPosition()); + } else if (mode == 2) { + this.defaultPosition = (Point3)value; + } + break; + case 5: + if (mode == 0) { + ret = Point3PropertyEditor.make(new Property(this, index, "Default Orientation Axis")); + } else if (mode == 1) { + ret = new Point3(this.getDefaultOrientationAxis()); + } else if (mode == 2) { + this.defaultOrientationAxis = (Point3)value; + } + break; + case 6: + if (mode == 0) { + ret = FloatPropertyEditor.make(new Property(this, index, "Default Orientation Angle")); + } else if (mode == 1) { + ret = new Float(this.getDefaultOrientation()); + } else if (mode == 2) { + this.defaultOrientation = (Float)value; + } + break; + case 7: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "VIP only"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean((this.flags & isVIPOnly) != 0); + } else if (mode == 2) { + if ((Boolean)value) { + this.flags = this.flags | isVIPOnly; + } else { + this.flags = this.flags & ~isVIPOnly; + } + } + break; + case 8: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Visible to VIP only"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean((this.flags & isVIPViewOnly) != 0); + } else if (mode == 2) { + if ((Boolean)value) { + this.flags = this.flags | isVIPViewOnly; + } else { + this.flags = this.flags & ~isVIPViewOnly; + } + } + break; + case 9: + if (mode == 0) { + ret = Point3PropertyEditor.make(new Property(this, index, "Light Source Direction")); + } else if (mode == 1) { + ret = this.lightPosition; + } else if (mode == 2) { + this.setLightPosition((Point3)value); + } + break; + case 10: + if (mode == 0) { + ret = ColorPropertyEditor.make(new Property(this, index, "Light Color")); + } else if (mode == 1) { + ret = this.lightColor; + } else if (mode == 2) { + this.setLightColor((Color)value); + } + break; + case 11: + if (mode == 0) { + ret = IntegerPropertyEditor.make(new Property(this, index, "Time To Auto-Teleport (seconds, -1 = never)")); + } else if (mode == 1) { + ret = new Integer(this.teleportInterval); + } else if (mode == 2) { + this.teleportInterval = (Integer)value; + } + break; + case 12: + if (mode == 0) { + ret = StringPropertyEditor.make(new Property(this, index, "Auto-Teleport destination")); + } else if (mode == 1) { + ret = this.teleportChain; + } else if (mode == 2) { + this.teleportChain = new String((String)value); + } + break; + case 13: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Allow Teleporting"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.allowTeleport); + } else if (mode == 2) { + this.allowTeleport = (Boolean)value; + } + break; + default: + ret = super.properties(index, offset + 14, mode, value); + } + + return ret; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(7, classCookie); + super.saveState(s); + if (this.skyColor != null) { + s.saveBoolean(true); + s.saveInt(this.skyColor.getRGB()); + } else { + s.saveBoolean(false); + } + + if (this.groundColor != null) { + s.saveBoolean(true); + s.saveInt(this.groundColor.getRGB()); + } else { + s.saveBoolean(false); + } + + s.save(this.defaultPosition); + s.save(this.defaultOrientationAxis); + s.saveFloat(this.defaultOrientation); + s.save(this.lightPosition); + s.saveInt(this.lightColor.getRGB()); + s.save(this.environment); + s.save(this.infiniteBackground); + s.saveString(this.teleportChain); + s.saveInt(this.teleportInterval); + s.saveBoolean(this.allowTeleport); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 0: + r.setOldFlag(); + super.restoreState(r); + this.setName(r.restoreString()); + r.restore(); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + r.restoreMaybeNull(); + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + r.restoreVector(); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = new RoomEnvironment(); + break; + case 1: + r.setOldFlag(); + super.restoreState(r); + r.restore(); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + r.restoreMaybeNull(); + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = new RoomEnvironment(); + break; + case 2: + r.setOldFlag(); + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + r.restoreMaybeNull(); + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = new RoomEnvironment(); + break; + case 3: + r.setOldFlag(); + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + r.restoreMaybeNull(); + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = (RoomEnvironment)r.restore(); + break; + case 4: + r.setOldFlag(); + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = (RoomEnvironment)r.restore(); + break; + case 5: + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.setLightPosition((Point3)r.restore()); + this.setLightColor(new Color(r.restoreInt())); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = (RoomEnvironment)r.restore(); + break; + case 6: + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.setLightPosition((Point3)r.restore()); + this.setLightColor(new Color(r.restoreInt())); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = (RoomEnvironment)r.restore(); + this.teleportChain = r.restoreString(); + this.teleportInterval = r.restoreInt(); + this.roomLoadTime = Std.getFastTime() / 1000; + break; + case 7: + super.restoreState(r); + if (r.restoreBoolean()) { + this.skyColor = new Color(r.restoreInt()); + } + + if (r.restoreBoolean()) { + this.groundColor = new Color(r.restoreInt()); + } + + this.defaultPosition = (Point3)r.restore(); + this.defaultOrientationAxis = (Point3)r.restore(); + this.defaultOrientation = r.restoreFloat(); + this.setLightPosition((Point3)r.restore()); + this.setLightColor(new Color(r.restoreInt())); + this.environment = (RoomEnvironment)r.restore(); + this.infiniteBackground = (RoomEnvironment)r.restore(); + this.teleportChain = r.restoreString(); + this.teleportInterval = r.restoreInt(); + this.roomLoadTime = Std.getFastTime() / 1000; + this.allowTeleport = r.restoreBoolean(); + break; + default: + throw new TooNewException(); + } + + super.add(this.environment); + super.add(this.infiniteBackground); + } + + public void aboutToDraw() { + if (!this.hasClump() && this.getOwner() instanceof World) { + this.recursiveAddRwChildren(null); + } + } + + @Override + protected void addRwChildren(WObject parent) { + assert parent == null; + + this.createClump(); + this.createScene(); + this.newRwChildHelper(); + float red = this.lightColor.getRed() / 256.0F; + float green = this.lightColor.getGreen() / 256.0F; + float blue = this.lightColor.getBlue() / 256.0F; + this.lightid = addLight(this.sceneID, this.lightPosition.x, this.lightPosition.y, this.lightPosition.z, red, green, blue); + this.lightid2 = addLight(this.sceneID, -this.lightPosition.x, -this.lightPosition.y, -this.lightPosition.z, red * 0.5F, green * 0.5F, blue * 0.5F); + } + + @Override + public void recursiveAddRwChildren(WObject parent) { + super.recursiveAddRwChildren(parent); + this.environment.recursiveAddRwChildren(this); + this.infiniteBackground.recursiveAddRwChildren(this); + } + + public final float floorHeight(float x, float y) { + return this.floorHeight(x, y, 120.0F); + } + + public float floorHeight(float x, float y, float z) { + Transform inverse = this.getObjectToWorldMatrix().invert(); + Point3Temp p = Point3Temp.make(x, y, z).times(inverse); + inverse.recycle(); + x = p.x; + y = p.y; + z = p.z; + float height = 0.0F; + boolean patchFound = false; + Enumeration<Object> e = (Enumeration<Object>)this.getContents(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof FloorPatch && ((FloorPatch)o).inPatch(x, y)) { + float patchHeight = ((FloorPatch)o).floorHeight(x, y); + if (patchHeight <= z && (patchHeight > height || !patchFound)) { + patchFound = true; + height = ((FloorPatch)o).floorHeight(x, y); + } + } + } + + return height; + } + + public Point3 surfaceNormal(float x, float y, float z) { + Point3 normal = new Point3(0.0F, 0.0F, 1.0F); + FloorPatch patch = null; + float height = 0.0F; + boolean patchFound = false; + Enumeration<Object> e = (Enumeration<Object>)this.getContents(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof FloorPatch && ((FloorPatch)o).inPatch(x, y)) { + float patchHeight = ((FloorPatch)o).floorHeight(x, y); + if (patchHeight <= z && (patchHeight > height || !patchFound)) { + patchFound = true; + height = ((FloorPatch)o).floorHeight(x, y); + patch = (FloorPatch)o; + } + } + } + + if (patch != null) { + normal = patch.surfaceNormal(x, y); + } + + normal.vectorTimes(this.getObjectToWorldMatrix()); + return normal; + } + + public RoomEnvironment getInfiniteBackground() { + return this.infiniteBackground; + } + + @Override + public String toString() { + return this.getWorld() + "#" + this.getName(); + } +} |