package net.sourceforge.pain.logic.event.console.command.builder; import net.sourceforge.pain.*; import net.sourceforge.pain.data.*; import net.sourceforge.pain.data.prototype.*; import net.sourceforge.pain.data.type.*; import net.sourceforge.pain.db.*; import net.sourceforge.pain.logic.fn.*; import net.sourceforge.pain.network.console.*; import net.sourceforge.pain.util.*; import java.util.*; /** * PAiN Date: 05.06.2003 Time: 1:40:02 */ public final class BC_Set extends BuilderCommand { public static final Map funcMap = new HashMap(); static { funcMap.put("race", new RaceSetFunc()); funcMap.put("dice", new DiceSetFunc()); funcMap.put("target_list", new TargetListSetFunc()); funcMap.put("proto", new ProtoSetFunc()); } public void processBuilderCommand(BuilderShell p, String args) throws Exception { Prototype role = p.builder.getEditedRole(); if (args == null || args.trim().length() == 0) { showHelp(p.console); return; } if (role == null) { MessageOutFn.outln(p.console, "No active role found!"); } else { int space = args.indexOf(' '); if (space < 1) { showHelp(p.console); return; } final String fieldName = args.substring(0, space).trim(); String fieldValue = args.substring(space + 1, args.length()); if (role.getClass() == PrototypeInfo.class && fieldName.equals("vnum")) { processSetVnum(p.console, (PrototypeInfo) role, fieldValue); return; } DbClass clazz = role.getDbClass(); int fid = -1; for (int i = 2; i < clazz.getNumberOfFields(); i++) { String name = clazz.getFieldName(i); if (fieldName.equalsIgnoreCase(name)) { fid = i; break; } } if (fid == -1) { MessageOutFn.outln(p.console, "Field not found:" + fieldName); return; } final String setTo; switch (clazz.getFieldType(fid)) { case DbType.BOOLEAN: boolean bool = "true".equalsIgnoreCase(fieldValue.trim()); role.setBoolean(fid, bool); setTo = "" + bool; break; case DbType.BYTE: byte bt = Byte.parseByte(fieldValue.trim()); role.setByte(fid, bt); setTo = "" + bt; break; case DbType.CHAR: char ch = fieldValue.charAt(0); role.setChar(fid, ch); setTo = "" + ch; break; case DbType.DOUBLE: double d = Double.parseDouble(fieldValue.trim()); role.setDouble(fid, d); setTo = "" + d; break; case DbType.FLOAT: float ft = Float.parseFloat(fieldValue.trim()); role.setFloat(fid, ft); setTo = "" + ft; break; case DbType.INT: int i = Integer.parseInt(fieldValue.trim()); role.setInt(fid, i); setTo = "" + i; break; case DbType.LONG: long l = Long.parseLong(fieldValue.trim()); role.setLong(fid, l); setTo = "" + l; break; case DbType.SHORT: short sh = Short.parseShort(fieldValue.trim()); role.setShort(fid, sh); setTo = "" + sh; break; case DbType.STRING: role.setString(fid, fieldValue); setTo = fieldValue; break; default: if (fieldValue.startsWith("@")) { space = fieldValue.indexOf(' '); if (space == -1 || space > fieldValue.length() - 2) { MessageOutFn.outln(p.console, "invalid func :" + fieldValue); return; } final String funcName = fieldValue.substring(1, space).trim(); fieldValue = fieldValue.substring(space + 1); SetFunc setFunc = (SetFunc) funcMap.get(funcName); if (setFunc == null) { MessageOutFn.outln(p.console, "Function not found:" + funcName); showSpecialFunctionsNames(p.console); } try { setTo = setFunc.apply(role, fid, fieldValue); } catch (SetFuncException e) { MessageOutFn.outln(p.console, "{RError:{x" + e.getMessage()); return; } } else { MessageOutFn.outln(p.console, "Can't set value for this type(use special functions):" + DbType.name(fid)); showSpecialFunctionsNames(p.console); return; } } MessageOutFn.outln(p.console, "Value of the field '" + fieldName + "' has been set to '{w" + setTo + "{x'"); } } private void showSpecialFunctionsNames(Console console) { for (Iterator it = funcMap.keySet().iterator(); it.hasNext();) { String funcName = (String) it.next(); SetFunc setFunc = (SetFunc) funcMap.get(funcName); MessageOutFn.outln(console, funcName + " : " + setFunc.getFuncDesc()); } } private void processSetVnum(Console console, PrototypeInfo info, String vnum) { if (info.getVnum().equals(vnum)) { MessageOutFn.outln(console, "Vnum stays the same:" + vnum); return; } PrototypesRegistry prototypesRegistry = Core.getWorld().getPrototypesRegistry(); if (prototypesRegistry.isUsedVnum(vnum)) { MessageOutFn.outln(console, "Vnum is already in use:" + vnum); } else { prototypesRegistry.unregisterPrototype(info); info.setVnum(vnum); prototypesRegistry.registerPrototype(info); MessageOutFn.outln(console, "Vnum changed to {w" + vnum + "{x"); } } public void showHelp(Console console) { MessageOutFn.outln(console, "Builder command SET inits fields values for the currently edited prototype"); MessageOutFn.outln(console, "Only primitives and strings could be setted directly"); MessageOutFn.outln(console, "Available functions for other types: "); showSpecialFunctionsNames(console); MessageOutFn.outln(console, "Usage: set <field_name> [@func_name] <value>"); } /** * TODO: change interface name and make it global * all SetFunc code is very raw in this version and will be clarified and enchanced in next release * but it works:) */ private static interface SetFunc { /** * Sets the specified value to the field of the role. * Parse this values, checks it validity. * @param role * @param fid * @param value * @return String represensation of setted value */ public String apply(Role role, int fid, String value) throws SetFuncException; public String getFuncDesc(); } public static final class SetFuncException extends IllegalArgumentException { public SetFuncException(String message) { super(message); } } private static final class RaceSetFunc implements SetFunc { public String apply(Role role, int fid, String value) throws SetFuncException { if (!(role instanceof LifeFormPrototype) && fid != LifeFormPrototype.RACE) { throw new SetFuncException("Illegal role or field:" + role.getClass().getName() + " fid:" + fid); } String lvalue = value.toLowerCase(); Race r = null; for (Iterator it = Core.getWorld().getRaces().iterator(); it.hasNext();) { r = (Race) it.next(); if (r.getName().toLowerCase().equals(lvalue)) { break; } r = null; } if (r == null) { throw new SetFuncException("Race not found!:" + value); } LifeFormPrototype lfp = (LifeFormPrototype) role; lfp.setRace(r); return r.getName(); } public String getFuncDesc() { return "sets race type field"; } } private static final class TargetListSetFunc implements SetFunc { public String apply(Role role, int fid, String value) throws SetFuncException { if (!(role instanceof InteractivePrototype) && fid != InteractivePrototype.TARGET_LIST) { throw new SetFuncException("Illegal role or field:" + role.getClass().getName() + " fid:" + fid); } String lvalue = value.toLowerCase(); String[] list = new String[0]; for (StringTokenizer st = new StringTokenizer(lvalue, " \t"); st.hasMoreTokens();) { list = TargetList.addNameToList(list, list.length, st.nextToken()); } if (list.length == 0) { throw new SetFuncException("illegal target list value:" + lvalue); } Log.debug("target list:" + value); InteractivePrototype ip = (InteractivePrototype) role; ip.setTargetList(list); return TargetList.string(list); } public String getFuncDesc() { return "sets targetList type field for Interactive roles"; } } private static final class DiceSetFunc implements SetFunc { public String apply(Role role, int fid, String value) throws SetFuncException { if ((!(role instanceof MobilePrototype) && fid != MobilePrototype.MOVE_POINTS_DICE) || !(role instanceof LifeFormPrototype) && fid != LifeFormPrototype.LIFE_POINTS_DICE) { throw new SetFuncException("Illegal role or field:" + role.getClass().getName() + " fid:" + fid); } Dice dice = new Dice(value.toLowerCase().trim()); if (role instanceof MobilePrototype) { ((MobilePrototype) role).setMovePointsDice(dice); } else { ((LifeFormPrototype) role).setLifePointsDice(dice); } return dice.toString(); } public String getFuncDesc() { return "sets Dice type field"; } } private static final class ProtoSetFunc implements SetFunc { public String apply(Role role, int fid, String value) throws SetFuncException { if (!(role instanceof EquippedPrototype)) { throw new SetFuncException("Illegal role or field:" + role.getClass().getName() + " fid:" + fid); } String vnum = value; PrototypeInfo p = Core.getWorld().getPrototypesRegistry().getPrototypeByVnum(vnum); if (p == null) { throw new SetFuncException("Prototype not found:" + value); } SpacePrototype sp = (SpacePrototype) p.getRole(SpacePrototype.class); if (sp == null) { throw new SetFuncException("Not a space prototype:" + value); } EquippedPrototype eq = (EquippedPrototype) role.getRole(EquippedPrototype.class); eq.setInventoryPrototype(sp); return "[" + vnum + "/" + sp.getSpaceName() + "]"; } public String getFuncDesc() { return "sets fields with type of references to prototypes"; } } }