summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/Room.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/Room.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/Room.java')
-rw-r--r--NET/worlds/scape/Room.java996
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();
+ }
+}