package NET.worlds.scape; import NET.worlds.core.Std; import java.io.IOException; public class AnimateAction extends Action { int startTime; public int cycleTime = 1000; public String frameList = ""; protected int frameListCount = 0; protected Material[] frameMaterialArray = null; public int cycles = 0; public boolean infiniteLoop = false; protected int cycleNo; protected int currentFrameNo; private boolean running = false; private static Object classCookie = new Object(); public AnimateAction() { this.startAnimation(); } public void startAnimation() { this.cycleNo = 0; this.currentFrameNo = -1; this.startTime = Std.getRealTime(); } public void preprocessFrameList(String frameList) { this.frameMaterialArray = AnimatingDoor.namesToMaterialArray(this, frameList); this.frameListCount = this.frameMaterialArray == null ? 0 : this.frameMaterialArray.length; } @Override public void detach() { if (this.frameMaterialArray != null) { int i = this.frameMaterialArray.length; while (--i >= 0) { this.frameMaterialArray[i].setKeepLoaded(false); } this.frameMaterialArray = null; this.frameListCount = 0; } super.detach(); } @Override public Persister trigger(Event e, Persister seqID) { Object owner = this.getOwner(); if (!(owner instanceof Animatable)) { this.frameMaterialArray = null; this.frameListCount = 0; return null; } else { Animatable o = (Animatable)owner; if (!o.hasClump()) { this.frameMaterialArray = null; this.frameListCount = 0; return seqID; } else { if (this.frameMaterialArray == null) { this.preprocessFrameList(this.frameList); } if (seqID == null) { if (this.running && !this.infiniteLoop) { return null; } this.startAnimation(); } int nextFrameNo = 0; if (this.frameListCount != 0 && this.cycleTime > 0) { int runTime = Std.getRealTime() - this.startTime; long frameNo = (long)this.frameListCount * runTime / this.cycleTime; this.cycleNo = (int)(frameNo / this.frameListCount); nextFrameNo = (int)(frameNo - this.cycleNo * this.frameListCount); } else { this.cycleNo = 1000000000; } if (this.cycleNo >= this.cycles && !this.infiniteLoop) { nextFrameNo = this.frameListCount - 1; this.running = false; } else { this.running = true; } if (nextFrameNo != this.currentFrameNo) { this.currentFrameNo = nextFrameNo; if (o.hasClump() && this.currentFrameNo >= 0) { o.setMaterial(this.frameMaterialArray[this.currentFrameNo]); } } return this.running ? this : null; } } } @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 = IntegerPropertyEditor.make(new Property(this, index, "Cycle Time")); } else if (mode == 1) { ret = new Integer(this.cycleTime); } else if (mode == 2) { this.cycleTime = (Integer)value; } break; case 1: if (mode == 0) { ret = IntegerPropertyEditor.make(new Property(this, index, "Cycles")); } else if (mode == 1) { ret = new Integer(this.cycles); } else if (mode == 2) { this.cycles = (Integer)value; } break; case 2: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Infinite Loop"), "False", "True"); } else if (mode == 1) { ret = new Boolean(this.infiniteLoop); } else if (mode == 2) { this.infiniteLoop = (Boolean)value; } break; case 3: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Frame List")); } else if (mode == 1) { ret = new String(this.frameList); } else if (mode == 2) { this.frameList = ((String)value).toString().trim().toLowerCase(); this.preprocessFrameList(this.frameList); } break; default: ret = super.properties(index, offset + 4, mode, value); } return ret; } @Override public String toString() { String ret = super.toString() + "[cycleTime " + this.cycleTime + ", cycles " + this.cycles + ","; if (!this.infiniteLoop) { ret = ret + " not "; } return ret + "Infinite ]"; } @Override public void saveState(Saver s) throws IOException { s.saveVersion(3, classCookie); super.saveState(s); s.saveBoolean(this.infiniteLoop); s.saveInt(this.cycleTime); s.saveInt(this.cycles); s.saveString(this.frameList); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 1: super.restoreState(r); case 0: this.cycleTime = (int)r.restoreFloat(); this.cycles = r.restoreInt(); this.infiniteLoop = this.cycles == 0; this.frameList = r.restoreString(); break; case 2: super.restoreState(r); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.infiniteLoop = this.cycles == 0; this.frameList = r.restoreString(); break; case 3: super.restoreState(r); this.infiniteLoop = r.restoreBoolean(); this.cycleTime = r.restoreInt(); this.cycles = r.restoreInt(); this.frameList = r.restoreString(); break; default: throw new TooNewException(); } } }