package NET.worlds.console; import NET.worlds.scape.FrameEvent; import NET.worlds.scape.FrameHandler; import NET.worlds.scape.Material; import NET.worlds.scape.Point3; import NET.worlds.scape.Point3Temp; import NET.worlds.scape.Portal; import NET.worlds.scape.Rect; import NET.worlds.scape.Restorer; import NET.worlds.scape.Room; import NET.worlds.scape.RoomEnvironment; import NET.worlds.scape.Saver; import NET.worlds.scape.TooNewException; import NET.worlds.scape.WObject; import NET.worlds.scape.World; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; public class Staircase extends Room implements FrameHandler { public Portal bottom; public Portal top; private float dzdx; private float dzdy; private Vector seenThings = new Vector(); private Vector seenStarts = new Vector(); private static Object classCookie = new Object(); public Staircase( World world, String name, float x1, float y1, float z1, float x2, float y2, float z2, float ceilingz, int numsteps, Material riser, Material tread, Material left, Material right, Material head, Material ceiling ) { super(world, name); float dx = (x2 - x1) / numsteps; float dy = (y2 - y1) / numsteps; float dz = (z2 - z1) / numsteps; this.dzdx = dz / dx; this.dzdy = dz / dy; assert dz >= 0.0F; float bottomtopz = z1 + ceilingz - z2; RoomEnvironment env = this.getEnvironment(); env.add(Rect.ceiling(x1, y1, ceilingz, x2, y2, ceiling)); if (dx > 0.0F) { if (dy > 0.0F) { env.add(new Rect(x1 - 0.1F, y1, z1, x1 - 0.1F, y2, ceilingz, left)); env.add(new Rect(x2 + 0.1F, y2, z1, x2 + 0.1F, y1, ceilingz, right)); env.add(new Rect(x2, y1, bottomtopz, x1, y1, ceilingz, head)); this.bottom = new Portal(x2, y1, z1, x1, y1, bottomtopz); this.top = new Portal(x1, y2, z2, x2, y2, ceilingz); for (int i = 0; i < numsteps; i++) { Rect w = new Rect(x1, y1 + i * dy, z1 + i * dz, x2, y1 + i * dy, z1 + (i + 1) * dz, riser); w.setTileSize(dz, dz); env.add(w); } for (int i = 0; i < numsteps; i++) { Rect w = Rect.floor(x1, y1 + i * dy, z1 + (i + 1) * dz, x2, y1 + (i + 1) * dy, tread); w.setTileSize(Math.abs(dy), Math.abs(dy)); env.add(w); } this.dzdx = 0.0F; } else { env.add(new Rect(x1, y1 - 0.1F, z1, x2, y1 - 0.1F, ceilingz, left)); env.add(new Rect(x2, y2 + 0.1F, z1, x1, y2 + 0.1F, ceilingz, right)); env.add(new Rect(x1, y2, bottomtopz, x1, y1, ceilingz, head)); this.bottom = new Portal(x1, y2, z1, x1, y1, bottomtopz); this.top = new Portal(x2, y1, z2, x2, y2, ceilingz); for (int i = 0; i < numsteps; i++) { Rect w = new Rect(x1 + i * dx, y1, z1 + i * dz, x1 + i * dx, y2, z1 + (i + 1) * dz, riser); w.setTileSize(dz, dz); env.add(w); } for (int i = 0; i < numsteps; i++) { Rect w = Rect.floor(x1 + i * dx, y2, z1 + (i + 1) * dz, x1 + (i + 1) * dx, y1, tread); w.setTileSize(Math.abs(dx), Math.abs(dx)); env.add(w); } this.dzdy = 0.0F; } } else if (dy > 0.0F) { env.add(new Rect(x1, y1 - 0.1F, z1, x2, y1 - 0.1F, ceilingz, left)); env.add(new Rect(x2, y2 + 0.1F, z1, x1, y2 + 0.1F, ceilingz, right)); env.add(new Rect(x1, y2, bottomtopz, x1, y1, ceilingz, head)); this.bottom = new Portal(x1, y2, z1, x1, y1, bottomtopz); this.top = new Portal(x2, y1, z2, x2, y2, ceilingz); for (int i = 0; i < numsteps; i++) { Rect w = new Rect(x1 + i * dx, y1, z1 + i * dz, x1 + i * dx, y2, z1 + (i + 1) * dz, riser); w.setTileSize(dz, dz); env.add(w); } for (int i = 0; i < numsteps; i++) { Rect w = Rect.floor(x1 + (i + 1) * dx, y1, z1 + (i + 1) * dz, x1 + i * dx, y2, tread); w.setTileSize(Math.abs(dx), Math.abs(dx)); env.add(w); } this.dzdy = 0.0F; } else { env.add(new Rect(x1 + 0.1F, y1, z1, x1 + 0.1F, y2, ceilingz, left)); env.add(new Rect(x2 - 0.1F, y2, z1, x2 - 0.1F, y1, ceilingz, right)); env.add(new Rect(x2, y1, bottomtopz, x1, y1, ceilingz, head)); this.bottom = new Portal(x2, y1, z1, x1, y1, bottomtopz); this.top = new Portal(x1, y2, z2, x2, y2, ceilingz); for (int i = 0; i < numsteps; i++) { Rect w = new Rect(x1, y1 + i * dy, z1 + i * dz, x2, y1 + i * dy, z1 + (i + 1) * dz, riser); w.setTileSize(dz, dz); env.add(w); } for (int i = 0; i < numsteps; i++) { Rect w = Rect.floor(x2, y1 + (i + 1) * dy, z1 + (i + 1) * dz, x1, y1 + i * dy, tread); w.setTileSize(Math.abs(dy), Math.abs(dy)); env.add(w); } this.dzdx = 0.0F; } env.add(this.bottom); env.add(this.top); } public Staircase() { } @Override public boolean handle(FrameEvent e) { Enumeration stuff = (Enumeration)this.getContents(); while (stuff.hasMoreElements()) { WObject thing = stuff.nextElement(); int i = this.seenThings.indexOf(thing); if (i == -1) { this.seenThings.addElement(thing); Point3Temp startpos = thing.getPosition(); Point3Temp topctr = Point3Temp.make(this.top.getScaleX(), 0.0F, this.top.getScaleZ()).times(0.5F).times(this.top.getObjectToWorldMatrix()); Point3Temp bottomctr = Point3Temp.make(this.bottom.getScaleX(), 0.0F, this.bottom.getScaleZ()) .times(0.5F) .times(this.bottom.getObjectToWorldMatrix()); if (topctr.x == bottomctr.x) { float t = (startpos.y - bottomctr.y) / (topctr.y - bottomctr.y); if (t < 0.5F) { startpos.y = bottomctr.y; } else { startpos.y = topctr.y; } this.dzdx = 0.0F; } else if (topctr.y == bottomctr.y) { float t = (startpos.x - bottomctr.x) / (topctr.x - bottomctr.x); if (t < 0.5F) { startpos.x = bottomctr.x; } else { startpos.x = topctr.x; } this.dzdy = 0.0F; } else { assert false; } this.seenStarts.addElement(new Point3(startpos)); i = this.seenThings.size() - 1; assert i == this.seenStarts.size() - 1; } Point3Temp oldpos = this.seenStarts.elementAt(i); Point3Temp pos = thing.getPosition(); float deltaz = this.dzdx * (pos.x - oldpos.x) + this.dzdy * (pos.y - oldpos.y) + oldpos.z - pos.z; if (deltaz != 0.0F) { thing.raise(deltaz); } } return true; } @Override public void saveState(Saver s) throws IOException { s.saveVersion(0, classCookie); super.saveState(s); s.saveFloat(this.dzdx); s.saveFloat(this.dzdy); s.save(this.bottom); s.save(this.top); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { Stair s = new Stair(); r.replace(this, s); int version = r.restoreVersion(classCookie); if (version != 0) { throw new TooNewException(); } else { s.superRestoreState(r); float dzdx = r.restoreFloat(); float dzdy = r.restoreFloat(); s.bottom = (Portal)r.restore(); s.top = (Portal)r.restore(); Point3Temp tllc = s.top.getPosition(); Point3Temp bllc = s.bottom.getPosition(); s.setRise(tllc.z - bllc.z); if (dzdx == 0.0F) { if (dzdy > 0.0F) { s.setLengthwise(1); s.setLength(tllc.y - bllc.y); } else { s.setLengthwise(3); s.setLength(bllc.y - tllc.y); } } else { assert dzdy == 0.0F; if (dzdx > 0.0F) { s.setLengthwise(0); s.setLength(tllc.x - bllc.x); } else { s.setLengthwise(2); s.setLength(bllc.x - tllc.x); } } } } }