package NET.worlds.scape; import NET.worlds.console.Console; import NET.worlds.network.URL; import java.io.IOException; public class WearAction extends Action { char limb = 'B'; String val = ""; private static String allowedLimbChars = "PBLMORUVIJKXYZabcdefHQE"; private static Object classCookie = new Object(); @Override public Persister trigger(Event e, Persister seqID) { Object owner = this.getOwner(); if (owner != null) { setAvLimb(this.limb, this.val); } return null; } public static void setAvLimb(char limb, String v) { String str = PosableShape.getCurrentAvCustomizable(); if (str != null) { int pos = str.indexOf(".", 7); String bodyType = str.substring(7, pos).toLowerCase(); int matStart; int matEnd; if (limb == 'H' || limb == 'E') { int head = str.lastIndexOf("NS"); if (head < 0) { return; } if (v == null) { v = bodyType; if (limb == 'E') { limb = 'H'; if (head >= 0 && str.charAt(head + 5) == 'G') { v = PosableShape.readName(str, head + 6).toLowerCase(); } } } int face = str.lastIndexOf("DgT"); int faceEnd = -1; if (face < head) { if (limb == 'E') { Console.println("Can't change the face of this type of head."); return; } face = -1; } else { faceEnd = face + 2; int i; while ((i = PosableShape.skipMat(str, faceEnd)) != faceEnd) { faceEnd = i; } } URL urlVal = PosableShape.getAvURL(v); if (urlVal == null) { return; } String val = urlVal.getAbsolute(); if (val == null) { return; } if (limb == 'H') { int newHead = val.lastIndexOf("NS"); if (newHead < 0) { return; } String geom = ""; pos = str.indexOf(".0E", 7); if (!v.equalsIgnoreCase(str.substring(7, pos))) { geom = "G" + PosableShape.getBodyType(v); } matStart = head + 5; matEnd = str.length(); v = geom + val.substring(newHead + 5); } else { int newFace = val.lastIndexOf("Dg"); if (newFace < 0) { return; } int newEnd = newFace + 2; int i; while ((i = PosableShape.skipMat(val, newEnd)) != newEnd) { newEnd = i; } matStart = face; matEnd = faceEnd; v = val.substring(newFace, newEnd); } } else if (limb == 'Q') { int sInd = str.lastIndexOf("NS"); if (sInd < 0) { Console.println("Can't customize this avatar."); return; } matStart = sInd + 2; matEnd = sInd + 5; if (v == null) { v = "000"; } } else if (limb == 'f') { int facex = str.lastIndexOf("Dg"); if (facex > 0) { int end = facex + 2; int i; while ((i = PosableShape.skipMat(str, end)) != end) { end = i; } int len = str.length() - 4; String valx = ""; while (i < len) { char c = str.charAt(i); if (c == 'Q') { valx = valx + c; i++; } else if (c >= '0' && c <= '9') { valx = valx + c; i++; } else { int j = PosableShape.skipMat(str, i); if (i != j) { valx = valx + "f"; i = j; } else { i++; } } } if (v != null) { str = str.substring(0, end) + valx + ".rwg"; } else { URL origURL = PosableShape.getAvURL(bodyType); String origStr = ""; if (origURL != null) { origStr = origURL.getInternal(); } int origFace = origStr.lastIndexOf("Dg"); if (origFace > 0) { int origEnd = origFace + 2; int k; while ((k = PosableShape.skipMat(origStr, origEnd)) != origEnd) { origEnd = k; } str = str.substring(0, end) + origStr.substring(origEnd); } } } matStart = PosableShape.getMatPosition(str, limb); if (matStart < 0) { return; } matEnd = PosableShape.skipMat(str, matStart); if (v == null) { URL origURLx = PosableShape.getAvURL(bodyType); if (origURLx == null) { return; } String origStrx = origURLx.getInternal(); int origMat = PosableShape.getMatPosition(origStrx, limb); if (origMat < 0) { return; } int origMatEnd = PosableShape.skipMat(origStrx, origMat); v = origStrx.substring(origMat, origMatEnd); } } else { matStart = PosableShape.getMatPosition(str, limb); if (matStart < 0) { return; } matEnd = PosableShape.skipMat(str, matStart); if (v == null) { URL origURLxx = PosableShape.getAvURL(bodyType); if (origURLxx == null) { return; } String origStrx = origURLxx.getInternal(); int origMat = PosableShape.getMatPosition(origStrx, limb); if (origMat < 0) { return; } int origMatEnd = PosableShape.skipMat(origStrx, origMat); v = origStrx.substring(origMat, origMatEnd); } } Console co = Console.getActive(); if (co != null) { co.setAvatar(URL.make(str.substring(0, matStart) + v + str.substring(matEnd))); } } } public static String makeMatString(int r, int g, int b) { StringBuffer sb = new StringBuffer("C"); sb.append(toBase64(r)); sb.append(toBase64(g)); sb.append(toBase64(b)); return sb.toString(); } public static char toBase64(int i) { return PosableShape.base64.charAt(i); } @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, "Limb")); } else if (mode == 1) { ret = new String("" + this.limb); } else if (mode == 2) { String s = (String)value; if (s.length() == 1 && allowedLimbChars.indexOf(s.charAt(0)) >= 0) { this.limb = s.charAt(0); this.val = null; } else { Console.println("Limb must one of " + allowedLimbChars); } } break; case 1: if (mode == 0) { ret = StringPropertyEditor.make(new Property(this, index, "Value").allowSetNull()); } else if (mode == 1) { ret = this.val; } else if (mode == 2) { String v = (String)value; if (v != null) { if (this.limb != 'H' && this.limb != 'E') { if (this.limb == 'Q') { if (v.length() != 3) { Console.println("Head size must be three letters, usually all the same."); return ret; } for (int i = 0; i < 3; i++) { char c = v.charAt(i); if (c != '0' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) { Console.println("Head size letters must each be one of z-a9A-Z."); return ret; } } } else if (v.length() < 1) { v = null; } else if (v.charAt(0) != 'C' && v.charAt(0) != 'T') { Console.println("Material must be C_X, CXYZ, or Ttexname."); return ret; } } else if (PosableShape.readName(v, 0).length() != v.length()) { Console.println("Head and face must be set to all-lowercase name of body type."); return ret; } } this.val = v; } 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.saveString(this.val); s.saveString("" + this.limb); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 0: super.restoreState(r); int red = r.restoreInt(); int green = r.restoreInt(); int blue = r.restoreInt(); String v = r.restoreString(); if (v == null) { this.val = makeMatString(red, green, blue); } else { char c; if (v.length() == 1 && (c = v.charAt(0)) >= 'A' && c <= 'Z') { this.val = "C_" + v; } else { this.val = "T" + v; } } this.limb = r.restoreString().charAt(0); break; case 1: super.restoreState(r); this.val = r.restoreString(); this.limb = r.restoreString().charAt(0); break; default: throw new TooNewException(); } } }