package NET.worlds.scape; import NET.worlds.core.Std; import NET.worlds.network.URL; import java.io.IOException; import java.net.MalformedURLException; import java.util.StringTokenizer; import java.util.Vector; public class AnimatingDoor extends Portal implements FrameHandler { public String frameList = ""; protected transient Material[] frames = null; float perFrame = 100.0F; private URL openSound; private URL closeSound; private transient float state; private transient int lastUpdate; private transient boolean wasSameRoom; private transient int lastFrame = -1; private Point3 start = new Point3(-0.5F, -1.0F, 0.0F); private Point3 end = new Point3(1.5F, 0.0F, 1.0F); private static Object classCookie = new Object(); public AnimatingDoor() { this.flags |= 262208; } @Override public void detach() { if (this.frames != null) { int i = this.frames.length; while (--i >= 0) { this.frames[i].setKeepLoaded(false); } this.frames = null; } super.detach(); } @Override public boolean handle(FrameEvent e) { Pilot pilot = Pilot.getActive(); Room pilotRoom = pilot.getRoom(); boolean sameRoom = pilotRoom == this.getRoom(); boolean inRange = false; Point3Temp pos = pilot.getPosition(); if (sameRoom) { BoundBoxTemp bbt = BoundBoxTemp.make(Point3Temp.make(this.start).times(this), Point3Temp.make(this.end).times(this)); inRange = bbt.contains(pos); } Portal far = this.farSide(); if (far != null && far instanceof AnimatingDoor) { AnimatingDoor afar = (AnimatingDoor)far; if (!inRange) { Room farRoom = afar.getRoom(); if (farRoom == null) { this.animate(sameRoom, inRange); return true; } if (afar.getRoom() == pilotRoom) { if (!sameRoom) { return true; } BoundBoxTemp bbt = BoundBoxTemp.make(Point3Temp.make(afar.start).times(afar), Point3Temp.make(afar.end).times(afar)); inRange = bbt.contains(pos); } } afar.animate(sameRoom, inRange); } this.animate(sameRoom, inRange); return true; } private void animate(boolean sameRoom, boolean inRange) { int now = Std.getFastTime(); float oldState = this.state; if (this.frames == null) { this.frames = namesToMaterialArray(this, this.frameList); this.lastFrame = -1; } int numMovingFrames = this.frames.length - 2; boolean wasSameRoom = this.wasSameRoom; this.wasSameRoom = sameRoom; if (!sameRoom) { this.state = 0.0F; } else if (!wasSameRoom) { this.state = inRange ? 1.0F : 0.0F; } else if (this.state == 0.0F) { if (!inRange) { return; } this.state = 1.0E-4F; } else if (this.state == 1.0F) { if (inRange) { return; } this.playSound(this.closeSound); this.state = 0.999F; } else { if (this.state == 1.0E-4F && inRange) { if (this.active()) { this.playSound(this.openSound); this.state = 2.0E-4F; } else { this.lastUpdate = now; } } float totalTime = numMovingFrames * this.perFrame; if (totalTime > 0.0F && now != this.lastUpdate) { float distMoved = (now - this.lastUpdate) / totalTime; if (inRange) { if ((this.state += distMoved) >= 1.0F) { this.state = 1.0F; } } else if ((this.state -= distMoved) <= 0.0F) { this.state = 0.0F; } } } if (oldState != 0.0F && this.state == 0.0F) { this.flags |= 262144; this.reset(); } else if (oldState == 0.0F && this.state != 0.0F) { this.flags &= -262145; this.reset(); this.triggerLoad(); } this.lastUpdate = now; int frame = 0; if (numMovingFrames >= 0) { if (this.state <= 2.0E-4F) { frame = 0; } else if (this.state == 1.0F) { frame = numMovingFrames + 1; } else { frame = 1 + (int)(this.state * numMovingFrames); } } else if (numMovingFrames == -2) { return; } this.setFrame(frame); } private void setFrame(int frame) { if (frame != this.lastFrame && this.frames != null && this.frames.length > frame) { this.setMaterial(this.frames[frame]); this.lastFrame = frame; } } private void playSound(URL url) { if (url != null && this.getRoom() == Pilot.getActive().getRoom()) { WavSoundPlayer wavPlayer = new WavSoundPlayer(null); wavPlayer.open(1.0F, 0.0F, false, false); wavPlayer.start(url); } } public static Material[] namesToMaterialArray(SuperRoot base, String str) { Vector v = new Vector(); StringTokenizer st = new StringTokenizer(str); while (st.hasMoreTokens()) { v.addElement(st.nextToken()); } int count = v.size(); Material[] mats = new Material[count]; int i = count; while (--i >= 0) { String s = (String)v.elementAt(i); URL url; try { url = new URL(base, s); } catch (MalformedURLException var10) { url = URL.make("error:\"" + s + '"'); } mats[i] = new Material(url); mats[i].setKeepLoaded(true); } return mats; } @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 = StringPropertyEditor.make(new Property(this, index, "Frame List")); } else if (mode == 1) { ret = this.frameList; } else if (mode == 2) { this.frameList = ((String)value).toString().trim(); this.frames = null; } break; case 1: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "Start")); } else if (mode == 1) { ret = new Point3(this.start); } else if (mode == 2) { this.start = (Point3)value; } break; case 2: if (mode == 0) { ret = Point3PropertyEditor.make(new Property(this, index, "End")); } else if (mode == 1) { ret = new Point3(this.end); } else if (mode == 2) { this.end = (Point3)value; } break; case 3: if (mode == 0) { ret = FloatPropertyEditor.make(new Property(this, index, "Time Per Frame")); } else if (mode == 1) { ret = new Float(this.perFrame); } else if (mode == 2) { this.perFrame = (Float)value; } break; case 4: if (mode == 0) { ret = URLPropertyEditor.make(new Property(this, index, "Open Sound URL").allowSetNull(), "wav;mid;ram;ra;rm"); } else if (mode == 1) { ret = this.openSound; } else if (mode == 2) { this.openSound = (URL)value; } break; case 5: if (mode == 0) { ret = URLPropertyEditor.make(new Property(this, index, "Close Sound URL").allowSetNull(), "wav;mid;ram;ra;rm"); } else if (mode == 1) { ret = this.closeSound; } else if (mode == 2) { this.closeSound = (URL)value; } break; default: ret = super.properties(index, offset + 6, mode, value); } return ret; } @Override public void saveState(Saver s) throws IOException { this.setFrame(0); s.saveVersion(0, classCookie); int f = this.flags; this.flags |= 262144; super.saveState(s); this.flags = f; s.saveString(this.frameList); s.saveFloat(this.perFrame); s.save(this.start); s.save(this.end); URL.save(s, this.openSound); URL.save(s, this.closeSound); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 0: super.restoreState(r); this.frameList = r.restoreString(); this.perFrame = r.restoreFloat(); this.start = (Point3)r.restore(); this.end = (Point3)r.restore(); this.openSound = URL.restore(r); this.closeSound = URL.restore(r); return; default: throw new TooNewException(); } } }