summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/Drone.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/Drone.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/Drone.java')
-rw-r--r--NET/worlds/scape/Drone.java864
1 files changed, 864 insertions, 0 deletions
diff --git a/NET/worlds/scape/Drone.java b/NET/worlds/scape/Drone.java
new file mode 100644
index 0000000..d930b61
--- /dev/null
+++ b/NET/worlds/scape/Drone.java
@@ -0,0 +1,864 @@
+package NET.worlds.scape;
+
+import NET.worlds.console.BBAppearDroneCommand;
+import NET.worlds.console.BBDisappearDroneCommand;
+import NET.worlds.console.BBDroneBitmapCommand;
+import NET.worlds.console.BBDroneDeltaPosCommand;
+import NET.worlds.console.BBMoveDroneCommand;
+import NET.worlds.console.BlackBox;
+import NET.worlds.console.Console;
+import NET.worlds.console.FriendsListPart;
+import NET.worlds.console.Main;
+import NET.worlds.console.MainCallback;
+import NET.worlds.console.MuteListPart;
+import NET.worlds.core.IniFile;
+import NET.worlds.core.ServerTableManager;
+import NET.worlds.core.Std;
+import NET.worlds.network.FilthFilter;
+import NET.worlds.network.Galaxy;
+import NET.worlds.network.InfiniteWaitException;
+import NET.worlds.network.NetworkObject;
+import NET.worlds.network.ObjID;
+import NET.worlds.network.OldPropertyList;
+import NET.worlds.network.PacketTooLargeException;
+import NET.worlds.network.PropertyList;
+import NET.worlds.network.URL;
+import NET.worlds.network.WorldServer;
+import NET.worlds.network.net2Property;
+import NET.worlds.network.netProperty;
+import NET.worlds.network.propReqCmd;
+import java.awt.Color;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public abstract class Drone extends WObject implements NetworkObject, WobLoaded, MouseDownHandler, FrameHandler {
+ private int _last_FrameTime;
+ private int _last_PosTime;
+ private int _vel_x;
+ private int _vel_y;
+ private int _vel_z;
+ private int _vel_yaw;
+ private int _last_x;
+ private int _last_y;
+ private int _last_z;
+ private int _last_yaw;
+ private int _x;
+ private int _y;
+ private int _z;
+ private int _yaw;
+ private boolean inited = false;
+ protected WObject tag;
+ protected WObject tagbg;
+ private Console console;
+ private float tagHeight;
+ private Shape sleepBox;
+ static boolean showNametags = IniFile.gamma().getIniInt("SHOWNAMETAGS", 1) == 1;
+ private static String[] employeeAccounts = ServerTableManager.instance().getTable("employeeAccounts");
+ private static Hashtable<String, String> employeeHash = null;
+ public static Vector<Drone> usableDrones = new Vector<Drone>();
+ private int lastUsed;
+ protected WorldServer _server;
+ private String sleepMode;
+ private static Object classCookie = new Object();
+ private static Object classCookieInterpolatedDrone = new Object();
+
+ static {
+ Main.register(new Drone.Flusher());
+ }
+
+ public Drone(ObjID id, WorldServer serv) {
+ if (serv != null) {
+ assert id != null;
+
+ this.attachToServer(serv.getLongID(id), serv);
+ }
+ }
+
+ protected Drone(String longID, WorldServer serv) {
+ assert longID != null;
+
+ if (serv != null) {
+ this.attachToServer(longID, serv);
+ }
+ }
+
+ private void attachToServer(String longID, WorldServer serv) {
+ if (serv != null) {
+ assert Main.isMainThread();
+
+ String nameWas = null;
+ if (this.tag != null) {
+ nameWas = this.getLongID();
+ }
+
+ this.getSharer().createDynamicFromNet();
+ this.setName(longID);
+ String nameIs = this.getLongID();
+ this._server = serv;
+ this._server.incRefCnt(this);
+ this._server.regObject(nameIs, this);
+
+ try {
+ this._server.sendNetworkMsg(new propReqCmd(new ObjID(this.getLongID())));
+ } catch (InfiniteWaitException var6) {
+ } catch (PacketTooLargeException var7) {
+ assert false;
+ }
+
+ if (nameIs.equals(nameWas)) {
+ this.avatarHeightChangedTo(189.0F);
+ } else {
+ this.makeTag(false);
+ }
+
+ Main.register(new Drone.MakeSleepBox());
+ }
+ }
+
+ private static void flushUnusedDrones() {
+ synchronized (usableDrones) {
+ int now = Std.getFastTime();
+ int i = usableDrones.size();
+
+ while (--i >= 0) {
+ Drone d = usableDrones.elementAt(i);
+ if (now > d.lastUsed + 2000) {
+ usableDrones.removeElementAt(i);
+ d.discard();
+ }
+ }
+ }
+ }
+
+ public static boolean isEmployeeAccount(String name) {
+ if (employeeHash == null) {
+ employeeHash = new Hashtable<String, String>();
+
+ for (int i = 0; i < employeeAccounts.length; i++) {
+ employeeHash.put(employeeAccounts[i], employeeAccounts[i]);
+ }
+ }
+
+ return employeeHash.get(name) != null;
+ }
+
+ public void makeTag(boolean force) {
+ this.tagHeight = 195.0F;
+ if (this.tag != null) {
+ this.tagHeight = this.tag.getPosition().z;
+ this.tag.detach();
+ this.tag = null;
+ }
+
+ if (this.tagbg != null) {
+ this.tagbg.detach();
+ this.tagbg = null;
+ }
+
+ if ((this._server != null || force) && !(this instanceof MutedDrone) && showNametags) {
+ String unfilteredName = this.getLongID();
+ String name = FilthFilter.get().filterName(unfilteredName);
+ if (name != null && !name.equals("")) {
+ Texture[] tagText = new Texture[1];
+ boolean hw = RenderWare.get3DHardwareInUse();
+ boolean isHost = name.toLowerCase().startsWith(Console.message("host")) || name.toLowerCase().startsWith("host");
+ if (isHost) {
+ name = Console.message("host-upper") + name.substring(4);
+ }
+
+ boolean isSpecialGuest = name.toLowerCase().startsWith(Console.message("guest-")) || name.toLowerCase().startsWith("guest-");
+ if (isSpecialGuest) {
+ name = Console.message("guest-upper") + name.substring(5);
+ }
+
+ boolean isEmployee = isEmployeeAccount(name);
+ Color bgColor;
+ if (isSpecialGuest) {
+ bgColor = Color.pink;
+ } else if (isHost) {
+ bgColor = Color.yellow;
+ } else if (isEmployee) {
+ bgColor = Color.cyan;
+ } else {
+ bgColor = Color.lightGray;
+ }
+
+ tagText[0] = new StringTexture(name, Console.message("TagFont"), 48, Color.black, hw ? new Color(254, 254, 254) : bgColor);
+ int height = 14;
+ int width = name.length() * 10;
+ Hologram h = new Hologram(width, height, tagText);
+ h.setViewplaneAligned(true);
+ h.raise(this.tagHeight);
+ h.setScaleDist(300.0F);
+ this.tag = h;
+ this.tag.setVisible(true);
+ this.tag.setBumpable(false);
+ this.tag.setLocalShadowed(false);
+ this.tag.setShadowedLocally(true);
+ this.add(this.tag);
+ if (hw) {
+ Texture[] bgText = new Texture[]{new StringTexture(name, Console.message("TagFont"), 48, Color.black, bgColor)};
+ Hologram h2 = new Hologram(width, height, bgText);
+ h2.setViewplaneAligned(true);
+ h2.raise(this.tagHeight);
+ h2.setScaleDist(300.0F);
+ h2.setMaterial(new Material(0.75F, 0.0F, 0.0F, Color.white, null, 0.5F, false, false));
+ this.tagbg = h2;
+ this.tagbg.setVisible(true);
+ this.tagbg.setBumpable(false);
+ this.tagbg.setLocalShadowed(false);
+ this.tagbg.setShadowedLocally(true);
+ this.add(this.tagbg);
+ }
+ }
+ }
+ }
+
+ protected void avatarHeightChangedTo(float h) {
+ if (this.tag != null) {
+ this.tag.raise(h + 1.0F + 5.0F - this.tag.getPosition().z);
+ }
+
+ if (this.tagbg != null) {
+ this.tagbg.raise(h + 1.0F + 5.0F - this.tagbg.getPosition().z);
+ }
+ }
+
+ public void detachFromServer(boolean reuse) {
+ assert Main.isMainThread();
+
+ if (this._server != null) {
+ this._server.delObject(new ObjID(this.getLongID()));
+ this._server.decRefCnt(this);
+ this._server = null;
+ }
+
+ if (reuse) {
+ this.lastUsed = Std.getFastTime();
+ synchronized (usableDrones) {
+ usableDrones.addElement(this);
+ }
+ }
+ }
+
+ public static Drone make(ObjID id, WorldServer serv) {
+ synchronized (usableDrones) {
+ if (!usableDrones.isEmpty() && id != null && serv != null) {
+ String name = "!" + serv.getLongID(id);
+
+ int i;
+ for (i = usableDrones.size() - 1; i > 0; i--) {
+ Drone d = usableDrones.elementAt(i);
+ if (d.getName().equals(name)) {
+ break;
+ }
+ }
+
+ Drone d = usableDrones.elementAt(i);
+ if (!d.getName().equals(name) && usableDrones.size() < 5) {
+ return new HoloDrone(id, serv);
+ } else {
+ usableDrones.removeElementAt(i);
+ d.attachToServer(serv.getLongID(id), serv);
+ return d;
+ }
+ } else {
+ return new HoloDrone(id, serv);
+ }
+ }
+ }
+
+ public Drone() {
+ }
+
+ @Override
+ public boolean handle(MouseDownEvent event) {
+ if (this._server != null && (event.key & 1) == 1) {
+ FriendsListPart.droneClick(this, event);
+ }
+
+ return true;
+ }
+
+ public float animate(String action) {
+ if (action.equalsIgnoreCase("_hdb")) {
+ new Drone.BounceNametag();
+ }
+
+ return 0.0F;
+ }
+
+ public Vector<String> getAnimationList() {
+ return new Vector<String>();
+ }
+
+ public void muteStateChanged() {
+ this.setAvatarNow(this.getCurrentURL());
+ }
+
+ public boolean shouldBeMuted() {
+ return MuteListPart.isMuted(this._server, this.getLongID());
+ }
+
+ private World getOwnerWorld() {
+ WObject o = (WObject)this.getOwner();
+ Room room = o == null ? null : o.getRoom();
+ return room == null ? null : room.getWorld();
+ }
+
+ public boolean shouldBeForcedHuman() {
+ World w = this.getOwnerWorld();
+ return w != null && w.getForceHuman();
+ }
+
+ public URL getCurrentURL() {
+ return this instanceof PosableDrone ? ((PosableDrone)this).getPosableShapeURL() : this.getSourceURL();
+ }
+
+ public Drone setAvatarNow(URL url) {
+ if (url == null) {
+ return this;
+ } else {
+ if (this.shouldBeForcedHuman()) {
+ url = PosableShape.getHuman(url);
+ if (Console.getActive() != null) {
+ Console.getActive().pendingPilot = url.toString();
+ }
+ }
+
+ url = PosableShape.getPermitted(url, this.getWorld());
+ boolean muted = this.shouldBeMuted();
+ if (url.equals(this.getCurrentURL()) && muted == (this instanceof MutedDrone)) {
+ return this;
+ } else if (!url.endsWith(".rwx") && !url.endsWith(".rwg") && !url.endsWith(".mov")) {
+ String s = url.getInternal();
+ if (s.endsWith(".pilot")) {
+ s = s.substring(0, s.length() - 6) + ".drone";
+ } else if (!s.endsWith(".drone")) {
+ s = s + ".drone";
+ }
+
+ url = URL.make(s);
+ if (url.equals(this.getSourceURL())) {
+ return this;
+ } else {
+ new WobLoader(url, this);
+ return this;
+ }
+ } else {
+ WObject o = (WObject)this.getOwner();
+ if (o == null) {
+ return this;
+ } else {
+ WorldServer serv = this._server;
+ String longID = this.getLongID();
+ this.detachFromServer(false);
+ this.detach();
+ Drone d;
+ if (muted) {
+ d = new MutedDrone(new ObjID(longID), serv, url);
+ } else if (url.endsWith(".mov")) {
+ d = new HoloDrone(new ObjID(longID), serv);
+ d.setAvatarNow(url);
+ } else {
+ d = new PosableDrone(new ObjID(longID), serv, url);
+ }
+
+ if (serv != null) {
+ d.transferFrom(this);
+ d.addTo(o.getRoom());
+ } else {
+ d.makeIdentity().post(this);
+ d.setName(this.getLongID());
+ o.add(d);
+ }
+
+ return d;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void wobLoaded(WobLoader loader, SuperRoot w) {
+ if (w instanceof Drone) {
+ assert w != null;
+
+ Drone d = (Drone)w;
+ d.setName(this.getLongID());
+ if (this._server == null) {
+ WObject o = (WObject)this.getOwner();
+ this.detach();
+ d.makeIdentity().post(this);
+ o.add(d);
+ } else {
+ WorldServer serv = this._server;
+ String longID = this.getLongID();
+ this.detachFromServer(false);
+ Room r = this.getRoom();
+ this.detach();
+ d.addTo(r);
+ d.attachToServer(longID, serv);
+ d.transferFrom(this);
+ }
+ }
+ }
+
+ public void addTo(Room r) {
+ if (r != null) {
+ Console c = r.getWorld().getConsole();
+ if (this.console == null) {
+ this.console = c;
+ if (c != null) {
+ Pilot.copySoul(c.getDroneSoulTemplate(), this);
+ }
+ }
+
+ r.add(this);
+ }
+ }
+
+ @Override
+ public void add(WObject w) {
+ super.add(w);
+ }
+
+ @Override
+ protected void noteUnadding(SuperRoot child) {
+ if (child instanceof WObject) {
+ WObject w = (WObject)child;
+ if (w.isDynamic()) {
+ w.setVisible(true);
+ }
+ }
+
+ super.noteUnadding(child);
+ }
+
+ public void setSleepMode(String mode) {
+ if (!mode.equals(this.sleepMode)) {
+ this.sleepMode = mode;
+ Main.register(new Drone.MakeSleepBox());
+ }
+ }
+
+ private void handleVAR_ASLEEP(String s) {
+ if (s != null && s.length() > 2 && s.charAt(0) == 0) {
+ s = s.substring(2);
+ }
+
+ this.setSleepMode(s);
+ }
+
+ public Drone handleVAR_BITMAP(String s) {
+ if (s.equals("")) {
+ return this;
+ } else {
+ BlackBox.getInstance().submitEvent(new BBDroneBitmapCommand(this.getName(), s));
+ if (s.charAt(0) == 0) {
+ s = s.substring(2);
+ }
+
+ try {
+ return this.setAvatarNow(new URL(URL.getAvatar(), s));
+ } catch (MalformedURLException var3) {
+ Console.println(Console.message("Invalid-av") + s);
+ return this;
+ }
+ }
+ }
+
+ public Point3Temp getVelocity() {
+ return Point3Temp.make(this._vel_x, this._vel_y, this._vel_z);
+ }
+
+ public int getYawRate() {
+ return this._vel_yaw;
+ }
+
+ @Override
+ public boolean handle(FrameEvent fe) {
+ if (this._server == null) {
+ return true;
+ } else {
+ int timeNow = fe.time;
+ this.interpolate(timeNow, this._server.getUpdateTime(), this);
+ return true;
+ }
+ }
+
+ public void interpolate(int timeNow, int updateTime, Transform target) {
+ if (this.inited) {
+ if (timeNow - this._last_PosTime > updateTime) {
+ this._last_PosTime = timeNow;
+ this._vel_x = this._last_x - this._x;
+ this._vel_y = this._last_y - this._y;
+ this._vel_z = this._last_z - this._z;
+ this._vel_yaw = ((this._last_yaw - this._yaw) % 360 + 360) % 360;
+
+ assert this._vel_yaw >= 0;
+
+ if (this._vel_yaw > 180) {
+ this._vel_yaw -= 360;
+ }
+ }
+
+ double timeDiff = (double)(timeNow - this._last_FrameTime) / updateTime;
+ if (timeNow - this._last_FrameTime > updateTime) {
+ timeDiff = 0.0;
+ }
+
+ this._x = this._x + (int)(timeDiff * this._vel_x);
+ this._y = this._y + (int)(timeDiff * this._vel_y);
+ this._z = this._z + (int)(timeDiff * this._vel_z);
+ this._yaw = this._yaw + (int)(timeDiff * this._vel_yaw) % 360;
+ target.makeIdentity().moveBy(this._x, this._y, this._z).yaw(this._yaw);
+ this._last_FrameTime = timeNow;
+ }
+ }
+
+ public void reset(short x, short y, short z, short yaw) {
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._yaw = yaw;
+ this._vel_x = this._vel_y = this._vel_z = 0;
+ this._vel_yaw = 0;
+ this._last_x = this._x;
+ this._last_y = this._y;
+ this._last_z = this._z;
+ this._last_yaw = this._yaw;
+ this._last_PosTime = this._last_FrameTime = Std.getRealTime();
+ this.inited = true;
+ }
+
+ protected void transferFrom(Drone i) {
+ this.makeIdentity().post(i);
+ this._x = i._x;
+ this._y = i._y;
+ this._z = i._z;
+ this._yaw = i._yaw;
+ this._vel_x = i._vel_x;
+ this._vel_y = i._vel_y;
+ this._vel_z = i._vel_z;
+ this._vel_yaw = i._vel_yaw;
+ this._last_x = i._last_x;
+ this._last_y = i._last_y;
+ this._last_z = i._last_z;
+ this._last_yaw = i._last_yaw;
+ this._last_PosTime = i._last_PosTime;
+ this._last_FrameTime = i._last_FrameTime;
+ this.inited = true;
+ }
+
+ public void appear(Room rm, short x, short y, short z, short yaw) {
+ assert rm != null;
+
+ BlackBox.getInstance().submitEvent(new BBAppearDroneCommand(rm.toString(), this.getName(), x, y, z, yaw));
+ if (this.getRoom() != rm) {
+ this.detach();
+ rm.add(this);
+ }
+
+ this.makeIdentity().moveBy(x, y, z).yaw(yaw);
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._yaw = yaw;
+ this._vel_x = this._vel_y = this._vel_z = 0;
+ this._vel_yaw = 0;
+ this._last_x = x;
+ this._last_y = y;
+ this._last_z = z;
+ this._last_yaw = yaw;
+ this._last_PosTime = this._last_FrameTime = Std.getRealTime();
+ URL u = this.getCurrentURL();
+ if (u != null) {
+ this.setAvatarNow(u);
+ }
+
+ this.inited = true;
+ }
+
+ public void disappear() {
+ BlackBox.getInstance().submitEvent(new BBDisappearDroneCommand(this.getName()));
+ this.detachFromServer(true);
+ this.detach();
+ }
+
+ public void longLoc(short x, short y, short z, short yaw) {
+ if (!(this.getOwner() instanceof Pilot)) {
+ BlackBox.getInstance().submitEvent(new BBMoveDroneCommand(this.getName(), x, y, z, yaw));
+ }
+
+ this._last_x = x;
+ this._last_y = y;
+ this._last_z = z;
+ this._last_yaw = yaw;
+ this._vel_x = this._last_x - this._x;
+ this._vel_y = this._last_y - this._y;
+ this._vel_z = this._last_z - this._z;
+ this._vel_yaw = ((this._last_yaw - this._yaw) % 360 + 360) % 360;
+
+ assert this._vel_yaw >= 0;
+
+ if (this._vel_yaw > 180) {
+ this._vel_yaw -= 360;
+ }
+
+ this._last_PosTime = Std.getRealTime();
+ this.inited = true;
+ }
+
+ @Override
+ public void property(OldPropertyList propList) {
+ int end = propList.size();
+
+ for (int i = 0; i < end; i++) {
+ netProperty tmpProp = propList.elementAt(i);
+ switch (tmpProp.property()) {
+ case 5:
+ this.handleVAR_BITMAP(tmpProp.value());
+ break;
+ case 23:
+ this.handleVAR_ASLEEP(tmpProp.value());
+ break;
+ default:
+ byte[] data = new byte[tmpProp.value().length()];
+ tmpProp.value().getBytes(0, tmpProp.value().length(), data, 0);
+ this.getSharer().setFromNetData(tmpProp.property(), data);
+ }
+ }
+ }
+
+ @Override
+ public void propertyUpdate(PropertyList propList) {
+ int end = propList.size();
+
+ for (int i = 0; i < end; i++) {
+ net2Property tmpProp = propList.elementAt(i);
+ switch (tmpProp.property()) {
+ case 5:
+ this.handleVAR_BITMAP(tmpProp.value());
+ break;
+ case 23:
+ this.handleVAR_ASLEEP(tmpProp.value());
+ break;
+ default:
+ this.getSharer().setFromNetData(tmpProp.property(), tmpProp.data());
+ }
+ }
+ }
+
+ public void roomChange(Room newRoom, short x, short y, short z, short yaw) {
+ this.detach();
+ if (newRoom != null) {
+ this.appear(newRoom, x, y, z, yaw);
+ }
+ }
+
+ public void shortLoc(byte dx, byte dy, byte dyaw) {
+ if (!(this.getOwner() instanceof Pilot)) {
+ BlackBox.getInstance().submitEvent(new BBDroneDeltaPosCommand(this.getName(), dx, dy, dyaw));
+ }
+
+ this._last_x += dx;
+ this._last_y += dy;
+ this._last_yaw += dyaw;
+ this._last_yaw %= 360;
+ this._vel_x = this._last_x - this._x;
+ this._vel_y = this._last_y - this._y;
+ this._vel_z = 0;
+ this._vel_yaw = ((this._last_yaw - this._yaw) % 360 + 360) % 360;
+
+ assert this._vel_yaw >= 0;
+
+ if (this._vel_yaw > 180) {
+ this._vel_yaw -= 360;
+ }
+
+ this._last_PosTime = Std.getRealTime();
+ }
+
+ public void teleport(WorldServer serv, byte exitType, byte entryType, Room newRoom, short x, short y, short z, short yaw) {
+ assert serv.getObject(new ObjID(this.getLongID())) == this;
+
+ Room curRoom = this.getRoom();
+ switch (exitType) {
+ default:
+ if (curRoom != null) {
+ assert curRoom != null;
+
+ this.detach();
+ }
+ case 0:
+ switch (entryType) {
+ case 0:
+ this.detachFromServer(true);
+ this.detach();
+ break;
+ default:
+ if (newRoom == null) {
+ this.detach();
+ } else {
+ assert newRoom != null;
+
+ this.appear(newRoom, x, y, z, yaw);
+ }
+ }
+ }
+ }
+
+ @Override
+ public WorldServer getServer() {
+ return this._server;
+ }
+
+ @Override
+ public String getLongID() {
+ String name = this.getName();
+ if (name.startsWith("!")) {
+ name = name.substring(1);
+ }
+
+ return name;
+ }
+
+ @Override
+ public void register() {
+ assert false;
+ }
+
+ @Override
+ public void galaxyDisconnected() {
+ assert false;
+ }
+
+ @Override
+ public void reacquireServer(WorldServer oldServ) {
+ assert false;
+ }
+
+ @Override
+ public void changeChannel(Galaxy g, String oldChannel, String newChannel) {
+ assert false;
+ }
+
+ @Override
+ public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException {
+ Object ret = null;
+ int var10000 = index - offset;
+ return super.properties(index, offset + 0, mode, value);
+ }
+
+ @Override
+ public void saveState(Saver s) throws IOException {
+ if (this.console != null) {
+ System.out.println("Warning: saving drone " + this.getName() + " WITH soul, which won't restore correctly!");
+ }
+
+ s.saveVersion(0, classCookieInterpolatedDrone);
+ s.saveVersion(0, classCookie);
+ super.saveState(s);
+ }
+
+ public void restoreStateDrone(Restorer r) throws IOException, TooNewException {
+ r.restoreVersion(classCookieInterpolatedDrone);
+ switch (r.restoreVersion(classCookie)) {
+ case 0:
+ super.restoreState(r);
+ Enumeration e = this.getContents();
+
+ while (e.hasMoreElements()) {
+ WObject w = (WObject)e.nextElement();
+ if (w instanceof Hologram) {
+ Hologram h = (Hologram)w;
+ if (h.getMovieName() == null) {
+ this.tag = h;
+ }
+ }
+ }
+
+ return;
+ default:
+ throw new TooNewException();
+ }
+ }
+
+ @Override
+ public void restoreState(Restorer r) throws IOException, TooNewException {
+ this.restoreStateDrone(r);
+ }
+
+ class BounceNametag implements MainCallback {
+ int start;
+ WObject origTag;
+ WObject origTagbg;
+
+ BounceNametag() {
+ if (Drone.this.tag != null) {
+ this.start = Std.getFastTime();
+ this.origTag = Drone.this.tag;
+ this.origTagbg = Drone.this.tagbg;
+ Main.register(this);
+ }
+ }
+
+ @Override
+ public void mainCallback() {
+ int now = Std.getFastTime();
+ float h = Drone.this.tagHeight;
+ if (now > this.start + 6000 || this.origTag != Drone.this.tag || this.origTagbg != Drone.this.tagbg) {
+ Main.unregister(this);
+ } else if (now < this.start + 1500) {
+ h = Drone.this.tagHeight + 200.0F * ((now - this.start) / 1500.0F);
+ } else {
+ float t = (now - this.start) / 1500.0F;
+ h = (float)(200.0 * Math.pow(1.414F, t) * Math.cos(t * 3.14159F));
+ }
+
+ this.origTag.setZ(h);
+ if (this.origTagbg != null) {
+ this.origTagbg.setZ(h);
+ }
+ }
+ }
+
+ static class Flusher implements MainCallback {
+ int lastTime;
+
+ @Override
+ public void mainCallback() {
+ int now = Std.getFastTime();
+ if (now > this.lastTime + 1000) {
+ Drone.flushUnusedDrones();
+ this.lastTime = now;
+ }
+ }
+ }
+
+ class MakeSleepBox implements MainCallback {
+ @Override
+ public void mainCallback() {
+ if (Drone.this.sleepMode != null && Drone.this.sleepMode.equals(Console.message("asleep")) && !(Drone.this instanceof MutedDrone)) {
+ if (Drone.this.sleepBox == null) {
+ Drone.this.sleepBox = new Shape();
+ Drone.this.sleepBox.setURL(URL.make("home:idle.rwg"));
+ Drone.this.sleepBox.setBumpable(false);
+ Drone.this.sleepBox.scale(100.0F);
+ Drone.this.sleepBox.spin(0.0F, 1.0F, 1.0F, 180.0F);
+ Drone.this.sleepBox.raise(189.0F);
+ Drone.this.add(Drone.this.sleepBox);
+ }
+ } else if (Drone.this.sleepBox != null) {
+ Drone.this.sleepBox.detach();
+ Drone.this.sleepBox = null;
+ }
+
+ Main.unregister(this);
+ }
+ }
+}