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);
return;
}
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.isVnumInUse(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 CreaturePrototype) && fid != CreaturePrototype.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);
}
CreaturePrototype cp = (CreaturePrototype) role;
cp.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 CreaturePrototype) && fid != CreaturePrototype.HIT_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 {
((CreaturePrototype) role).setHPDice(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 CreaturePrototype)) {
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);
}
CreaturePrototype cr = (CreaturePrototype) role.getRole(CreaturePrototype.class);
cr.setInventoryPrototype(sp);
return "[" + vnum + "/" + sp.getSpaceName() + "]";
}
public String getFuncDesc() {
return "sets fields with type of references to prototypes";
}
}
}