package NET.worlds.scape; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; public class RollingAttribute extends Attribute { RollBehavior rb = new RollBehavior(); public float initialKickVel = 200.0F; private Point3 kp = new Point3(); private float kv = 0.0F; private Point3 kd = new Point3(); private static Object classCookie = new Object(); public RollingAttribute(int attrID) { super(attrID); this.rb.linearDamp = 0.95F; this.rb.rollFactor = 1.0F; this.rb.setNotifyAttribute(this); } public RollingAttribute() { this.rb.linearDamp = 0.8F; this.rb.setNotifyAttribute(this); } public void set(Point3Temp p, float v, Point3Temp d) { if (this.kp.x != p.x || this.kp.y != p.y || this.kp.x != p.z) { this.kp.x = p.x; this.kp.y = p.y; this.kp.z = p.z; this.kv = v; this.kd.x = d.x; this.kd.y = d.y; this.kd.z = d.z; ((WObject)this.getOwner().getOwner()).moveTo(this.kp); this.rb.linearVel = this.kv; this.rb.setDir(this.kd); this.noteChange(); } } public void notifyStopped() { WObject ball = (WObject)((Sharer)this.getOwner()).getOwner(); Point3Temp pos = ball.getPosition(); this.set(pos, 0.0F, Point3Temp.make(0.0F, 0.0F, 0.0F)); } public void get(Point3Temp p, float v, Point3Temp d) { p.x = this.kp.x; p.y = this.kp.y; p.z = this.kp.z; v = this.kv; d.x = this.kd.x; d.y = this.kd.y; d.z = this.kd.z; } @Override protected void noteAddingTo(SuperRoot owner) { WObject parent = (WObject)owner.getOwner(); parent.addHandler(this.rb); } public boolean handle(BumpEventTemp b) { if (b.target == b.receiver && !(this.rb.linearVel > 0.0F)) { if (this.rb.linearVel == 0.0F) { Point3Temp pos = b.target.getWorldPosition(); WObject kicker = (WObject)b.source; float alpha = kicker.getYaw(); Point3Temp kpos = kicker.getWorldPosition(); double dx = kpos.x - pos.x; double dy = kpos.y - pos.y; Math.atan2(dx, dy); float kickang = (float)((360.0F - alpha + 90.0F) * Math.PI / 180.0); Point3Temp kickdir = Point3Temp.make((float)Math.cos(kickang), (float)Math.sin(kickang), 0.0F); pos.x = pos.x + kickdir.x; pos.y = pos.y + kickdir.y; this.set(pos, this.initialKickVel, kickdir); } } else { if (b.target instanceof Camera) { double dx = this.rb.dir.x; double dy = this.rb.dir.y; Math.atan2(dx, dy); double theta = dy + 60.0 * Math.random() - 30.0; double var12 = dx * Math.cos(theta * Math.PI / 180.0); dy = dx * Math.sin(theta * Math.PI / 180.0); this.rb.dir.x = (float)var12; this.rb.dir.y = (float)dy; } this.rb.processBumpEvent(b); if (b.target instanceof Camera || b.source instanceof Camera) { Point3Temp pos = ((WObject)((Sharer)this.getOwner()).getOwner()).getWorldPosition(); this.set(pos, this.rb.linearVel, this.rb.dir); } } return true; } @Override public void generateNetData(DataOutputStream s) throws IOException { s.writeFloat(this.kp.x); s.writeFloat(this.kp.y); s.writeFloat(this.kp.z); s.writeFloat(this.kv); s.writeFloat(this.kd.x); s.writeFloat(this.kd.y); s.writeFloat(this.kd.z); } @Override public void setFromNetData(DataInputStream ds, int len) throws IOException { Point3Temp pos = Point3Temp.make(); float vel = 0.0F; Point3Temp dir = Point3Temp.make(); pos.x = ds.readFloat(); pos.y = ds.readFloat(); pos.z = ds.readFloat(); vel = ds.readFloat(); dir.x = ds.readFloat(); dir.y = ds.readFloat(); dir.z = ds.readFloat(); this.set(pos, vel, dir); } @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 = FloatPropertyEditor.make(new Property(this, index, "Roll Factor")); } else if (mode == 1) { ret = new Float(this.rb.rollFactor); } else if (mode == 2) { this.rb.rollFactor = (Float)value; } break; case 1: if (mode == 0) { ret = FloatPropertyEditor.make(new Property(this, index, "Initial Kick Velocity")); } else if (mode == 1) { ret = new Float(this.initialKickVel); } else if (mode == 2) { this.initialKickVel = (Float)value; } break; default: ret = super.properties(index, offset + 2, mode, value); } return ret; } @Override public void saveState(Saver s) throws IOException { s.saveVersion(1, classCookie); super.saveState(s); s.saveFloat(this.initialKickVel); s.saveFloat(this.rb.rollFactor); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 0: super.restoreState(r); this.initialKickVel = r.restoreFloat(); float threshold = r.restoreFloat(); break; case 1: super.restoreState(r); this.initialKickVel = r.restoreFloat(); this.rb.rollFactor = r.restoreFloat(); break; default: throw new TooNewException(); } } @Override public String toString() { return super.toString() + " [From " + this.kp + " with velocity " + this.kv + " toward " + this.kd + "] "; } }