protected boolean parsedOutIndividualSkill(MOB mob, String qual, Vector acodes) { if ((qual == null) || (qual.length() == 0) || (qual.equalsIgnoreCase("all"))) return false; if (qual.length() > 0) for (int i = 1; i < Ability.DOMAIN_DESCS.length; i++) if (Ability.DOMAIN_DESCS[i].replace('_', ' ').equalsIgnoreCase(qual)) return false; else if ((Ability.DOMAIN_DESCS[i].replace('_', ' ').indexOf('/') >= 0) && (Ability.DOMAIN_DESCS[i] .replace('_', ' ') .substring(Ability.DOMAIN_DESCS[i].indexOf('/') + 1) .equalsIgnoreCase(qual))) return false; final Ability A = CMClass.findAbility(qual); if ((A != null) && (CMLib.ableMapper().qualifiesByAnyCharClass(A.ID())) && (acodes.contains(Integer.valueOf(A.classificationCode() & Ability.ALL_ACODES)))) { final Ability A2 = mob.fetchAbility(A.ID()); if (A2 == null) mob.tell(L("You don't know '@x1'.", A.name())); else { int level = CMLib.ableMapper().qualifyingLevel(mob, A2); if (level < 0) level = 0; final StringBuffer line = new StringBuffer(""); line.append("\n\rLevel ^!" + level + "^?:\n\r"); line.append( "^N[^H" + CMStrings.padRight(Integer.toString(A2.proficiency()), 3) + "%^?]^N " + CMStrings.padRight("^<HELP^>" + A2.name() + "^</HELP^>", 19)); line.append("^?\n\r"); if (mob.session() != null) mob.session().wraplessPrintln(line.toString()); } return true; } return false; }
protected StringBuilder getAbilities( MOB viewerM, MOB ableM, Vector ofTypes, int mask, boolean addQualLine, int maxLevel) { final int COL_LEN1 = ListingLibrary.ColFixer.fixColWidth(3.0, viewerM); final int COL_LEN2 = ListingLibrary.ColFixer.fixColWidth(18.0, viewerM); final int COL_LEN3 = ListingLibrary.ColFixer.fixColWidth(19.0, viewerM); int highestLevel = 0; final int lowestLevel = ableM.phyStats().level() + 1; final StringBuilder msg = new StringBuilder(""); for (final Enumeration<Ability> a = ableM.allAbilities(); a.hasMoreElements(); ) { final Ability A = a.nextElement(); int level = CMLib.ableMapper().qualifyingLevel(ableM, A); if (level < 0) level = 0; if ((A != null) && (level > highestLevel) && (level < lowestLevel) && (ofTypes.contains(Integer.valueOf(A.classificationCode() & mask)))) highestLevel = level; } if ((maxLevel >= 0) && (maxLevel < highestLevel)) highestLevel = maxLevel; for (int l = 0; l <= highestLevel; l++) { final StringBuilder thisLine = new StringBuilder(""); int col = 0; for (final Enumeration<Ability> a = ableM.allAbilities(); a.hasMoreElements(); ) { final Ability A = a.nextElement(); int level = CMLib.ableMapper().qualifyingLevel(ableM, A); if (level < 0) level = 0; if ((A != null) && (level == l) && (ofTypes.contains(Integer.valueOf(A.classificationCode() & mask)))) { if (thisLine.length() == 0) thisLine.append("\n\rLevel ^!" + l + "^?:\n\r"); if ((++col) > 3) { thisLine.append("\n\r"); col = 1; } thisLine.append( "^N[^H" + CMStrings.padRight(Integer.toString(A.proficiency()), COL_LEN1) + "%^?]^N" + " " // +(A.isAutoInvoked()?"^H.^N":" ") + CMStrings.padRight( "^<HELP^>" + A.name() + "^</HELP^>", (col == 3) ? COL_LEN2 : COL_LEN3)); } } if (thisLine.length() > 0) msg.append(thisLine); } if (msg.length() == 0) msg.append(L("^!None!^?")); else if (addQualLine) msg.append( L( "\n\r\n\rUse QUALIFY to see additional skills you can GAIN.")); // ^H.^N = // passive/auto-invoked.")); return msg; }
@Override public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel) { String cmd = ""; if (commands.size() > 0) cmd = ((String) commands.firstElement()).toUpperCase(); if ((commands.size() < 2) || ((!cmd.equals("BUY") && (!cmd.equals("SELL"))))) { mob.tell( L( "You must specify BUY, SELL, an item, and possibly a ShopKeeper (unless it is implied).")); return false; } final Environmental shopkeeper = CMLib.english() .parseShopkeeper(mob, commands, CMStrings.capitalizeAndLower(cmd) + " what to whom?"); if (shopkeeper == null) return false; if (commands.size() == 0) { mob.tell(L("@x1 what?", CMStrings.capitalizeAndLower(cmd))); return false; } if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; final boolean success = proficiencyCheck(mob, 0, auto); if (success) { final CMMsg msg = CMClass.getMsg( mob, shopkeeper, this, CMMsg.MSG_SPEAK, auto ? "" : L("<S-NAME> haggle(s) with <T-NAMESELF>.")); if (mob.location().okMessage(mob, msg)) { mob.location().send(mob, msg); invoker = mob; mob.addEffect(this); mob.recoverCharStats(); commands.insertElementAt(CMStrings.capitalizeAndLower(cmd), 0); mob.doCommand(commands, Command.METAFLAG_FORCED); commands.addElement(shopkeeper.name()); mob.delEffect(this); mob.recoverCharStats(); } } else beneficialWordsFizzle( mob, shopkeeper, L("<S-NAME> haggle(s) with <T-NAMESELF>, but <S-IS-ARE> unconvincing.")); // return whether it worked return success; }
protected String mobHeader(Faction useFaction) { final StringBuffer str = new StringBuffer(); str.append("\n\r"); str.append(CMStrings.padRight(L("Name"), 20) + " "); str.append(CMStrings.padRight(L("Lvl"), 4) + " "); str.append(CMStrings.padRight(L("Att"), 5) + " "); str.append(CMStrings.padRight(L("Dmg"), 5) + " "); str.append(CMStrings.padRight(L("Armor"), 5) + " "); str.append(CMStrings.padRight(L("Speed"), 5) + " "); str.append(CMStrings.padRight(L("Rejuv"), 5) + " "); if (useFaction != null) str.append(CMStrings.padRight(useFaction.name(), 7) + " "); str.append(CMStrings.padRight(L("Money"), 5) + " "); str.append(CMStrings.padRight(L("Worn"), 5)); str.append("\n\r"); return str.toString(); }
protected String itemHeader() { final StringBuffer str = new StringBuffer(); str.append("\n\r"); str.append(CMStrings.padRight(L("Name"), 20) + " "); str.append(CMStrings.padRight(L("Type"), 10) + " "); str.append(CMStrings.padRight(L("Lvl"), 4) + " "); str.append(CMStrings.padRight(L("Att"), 5) + " "); str.append(CMStrings.padRight(L("Dmg"), 5) + " "); str.append(CMStrings.padRight(L("Armor"), 5) + " "); str.append(CMStrings.padRight(L("Value"), 5) + " "); str.append(CMStrings.padRight(L("Rejuv"), 5) + " "); str.append(CMStrings.padRight(L("Wght."), 4) + " "); str.append(CMStrings.padRight(L("Size"), 4)); str.append("\n\r"); return str.toString(); }
@Override public boolean invoke( MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) { if (commands.size() < 1) { mob.tell( L( "You must specify an item to fence, and possibly a ShopKeeper (unless it is implied).")); return false; } commands.add(0, "SELL"); // will be instantly deleted by parseshopkeeper final Environmental shopkeeper = CMLib.english().parseShopkeeper(mob, commands, L("Fence what to whom?")); if (shopkeeper == null) return false; if (commands.size() == 0) { mob.tell(L("Fence what?")); return false; } if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; final boolean success = proficiencyCheck(mob, 0, auto); if (success) { final CMMsg msg = CMClass.getMsg( mob, shopkeeper, this, CMMsg.MSG_SPEAK, auto ? "" : L("<S-NAME> fence(s) stolen loot to <T-NAMESELF>.")); if (mob.location().okMessage(mob, msg)) { mob.location().send(mob, msg); invoker = mob; addBackMap.clear(); mob.addEffect(this); mob.recoverCharStats(); commands.add(0, CMStrings.capitalizeAndLower("SELL")); mob.doCommand(commands, MUDCmdProcessor.METAFLAG_FORCED); commands.add(shopkeeper.name()); mob.delEffect(this); for (Item I : addBackMap.keySet()) { if (mob.isMine(I)) { I.addEffect(addBackMap.get(I)); } } addBackMap.clear(); mob.recoverCharStats(); } } else beneficialWordsFizzle( mob, shopkeeper, L( "<S-NAME> attempt(s) to fence stolen loot to <T-NAMESELF>, but make(s) <T-HIM-HER> too nervous.")); // return whether it worked return success; }
@Override public void executeMsg(final Environmental myHost, final CMMsg msg) { if ((System.currentTimeMillis() - lastClanCheck) > TimeManager.MILI_HOUR) { lastClanCheck = System.currentTimeMillis(); if ((clanID().length() > 0) && (CMLib.clans().getClan(clanID()) == null)) { destroy(); return; } } if (StdClanItem.stdExecuteMsg(this, msg)) { super.executeMsg(myHost, msg); if ((msg.amITarget(this)) && (clanID().length() > 0) && (msg.source().getClanRole(clanID()) != null)) { final Room R = msg.source().location(); if (R == null) return; if ((msg.targetMinor() == CMMsg.TYP_DROP) && (msg.trailerMsgs() == null)) { msg.addTrailerMsg(CMClass.getMsg(msg.source(), this, CMMsg.MSG_LOOK, null)); setRightfulOwner(R); } else if ((msg.targetMinor() == CMMsg.TYP_LOOK) || (msg.targetMinor() == CMMsg.TYP_EXAMINE)) { final LegalBehavior B = CMLib.law().getLegalBehavior(R); String s = ""; if (B != null) s = B.conquestInfo(CMLib.law().getLegalObject(R)); if (s.length() > 0) msg.source().tell(s); else msg.source().tell(L("This area is under the control of the Archons.")); return; } else if ((msg.targetMinor() == CMMsg.TYP_SPEAK) && (CMSecurity.isAllowed(msg.source(), R, CMSecurity.SecFlag.CMDROOMS)) && (msg.targetMessage() != null)) { final String msgStr = CMStrings.getSayFromMessage(msg.targetMessage().toUpperCase()); final String alert = "I HEREBY DECLARE THIS AREA"; final int msgIndex = msgStr.indexOf(alert); if (msgIndex >= 0) { final LegalBehavior B = CMLib.law().getLegalBehavior(R); if (B != null) B.setControlPoints(clanID(), B.controlPoints() + 1); } } } } }
@Override public void executeMsg(final Environmental myHost, final CMMsg msg) { final MOB mob = msg.source(); switch (msg.targetMinor()) { case CMMsg.TYP_WAND_USE: if (msg.amITarget(this) && ((msg.tool() == null) || (msg.tool() instanceof Physical))) waveIfAble(mob, (Physical) msg.tool(), msg.targetMessage()); break; case CMMsg.TYP_SPEAK: if ((msg.sourceMinor() == CMMsg.TYP_SPEAK) && (!amWearingAt(Wearable.IN_INVENTORY))) { boolean alreadyWanding = false; final List<CMMsg> trailers = msg.trailerMsgs(); if (trailers != null) for (final CMMsg msg2 : trailers) if (msg2.targetMinor() == CMMsg.TYP_WAND_USE) alreadyWanding = true; final String said = CMStrings.getSayFromMessage(msg.sourceMessage()); if ((!alreadyWanding) && (checkWave(mob, said))) msg.addTrailerMsg( CMClass.getMsg( msg.source(), this, msg.target(), CMMsg.NO_EFFECT, null, CMMsg.MASK_ALWAYS | CMMsg.TYP_WAND_USE, said, CMMsg.NO_EFFECT, null)); } break; default: break; } super.executeMsg(myHost, msg); }
public boolean dbMerge(MOB mob, String name, Modifiable dbM, Modifiable M, Set<String> ignores) throws java.io.IOException, CMException { if ((M instanceof Physical) && (dbM instanceof Physical)) { final Physical PM = (Physical) M; final Physical dbPM = (Physical) dbM; if (CMLib.flags().isCataloged(PM)) { mob.tell(L("^H**Warning: Changes will remove this object from the catalog.")); PM.basePhyStats() .setDisposition(CMath.unsetb(PM.basePhyStats().disposition(), PhyStats.IS_CATALOGED)); } if (CMLib.flags().isCataloged(dbPM)) dbPM.basePhyStats() .setDisposition(CMath.unsetb(dbPM.basePhyStats().disposition(), PhyStats.IS_CATALOGED)); PM.image(); dbPM.image(); } final String[] statCodes = dbM.getStatCodes(); int showFlag = -1; if (CMProps.getIntVar(CMProps.Int.EDITORTYPE) > 0) showFlag = -999; boolean ok = false; boolean didSomething = false; while (!ok) { int showNumber = 0; mob.tell(name); for (int i = 0; i < statCodes.length; i++) { final String statCode = M.getStatCodes()[i]; if (ignores.contains(statCode) || ((M instanceof MOB) && statCode.equalsIgnoreCase("INVENTORY"))) continue; final String promptStr = CMStrings.capitalizeAndLower(M.getStatCodes()[i]); final String dbVal = dbM.getStat(statCode); final String loVal = M.getStat(statCode); if (dbVal.equals(loVal)) continue; ++showNumber; if ((showFlag > 0) && (showFlag != showNumber)) continue; mob.tell( L( "^H@x1. @x2\n\rValue: ^W'@x3'\n\r^HDBVal: ^N'@x4'", "" + showNumber, promptStr, loVal, dbVal)); if ((showFlag != showNumber) && (showFlag > -999)) continue; final String res = mob.session() .choose( L("D)atabase Value, E)dit Value, or N)o Change, or Q)uit All: "), L("DENQ"), L("N")); if (res.trim().equalsIgnoreCase("N")) continue; if (res.trim().equalsIgnoreCase("Q")) throw new CMException("Cancelled by user."); didSomething = true; if (res.trim().equalsIgnoreCase("D")) { M.setStat(statCode, dbVal); continue; } M.setStat( statCode, CMLib.genEd().prompt(mob, M.getStat(statCode), ++showNumber, showFlag, promptStr)); } if (showNumber == 0) return didSomething; if (showFlag < -900) { ok = true; break; } if (showFlag > 0) { showFlag = -1; continue; } showFlag = CMath.s_int(mob.session().prompt(L("Edit which? "), "")); if (showFlag <= 0) { showFlag = -1; ok = true; } } return didSomething; }
@Override protected boolean autoGenInvoke( final MOB mob, List<String> commands, Physical givenTarget, final boolean auto, final int asLevel, int autoGenerate, boolean forceLevels, List<Item> crafted) { if (super.checkStop(mob, commands)) return true; if (super.checkInfo(mob, commands)) return true; final PairVector<EnhancedExpertise, Integer> enhancedTypes = enhancedTypes(mob, commands); randomRecipeFix(mob, addRecipes(mob, loadRecipes()), commands, autoGenerate); if (commands.size() == 0) { commonTell( mob, L( "Make what? Enter \"mleatherwork list\" for a list, \"mleatherworkd info <item>\", \"mleatherwork refit <item>\" to resize," + " \"mleatherwork learn <item>\", \"mleatherwork scan\", \"mleatherwork mend <item>\", or \"mleatherwork stop\" to cancel.")); return false; } if ((!auto) && (commands.size() > 0) && ((commands.get(0)).equalsIgnoreCase("bundle"))) { bundling = true; if (super.invoke(mob, commands, givenTarget, auto, asLevel)) return super.bundle(mob, commands); return false; } final List<List<String>> recipes = addRecipes(mob, loadRecipes()); final String str = commands.get(0); playSound = "scissor.wav"; String startStr = null; bundling = false; int multiplier = 4; int duration = 4; if (str.equalsIgnoreCase("list")) { String mask = CMParms.combine(commands, 1); boolean allFlag = false; if (mask.equalsIgnoreCase("all")) { allFlag = true; mask = ""; } final StringBuffer buf = new StringBuffer(""); int toggler = 1; final int toggleTop = 2; final int[] cols = { CMLib.lister().fixColWidth(30, mob.session()), CMLib.lister().fixColWidth(3, mob.session()), CMLib.lister().fixColWidth(3, mob.session()) }; for (int r = 0; r < toggleTop; r++) buf.append( (r > 0 ? " " : "") + CMStrings.padRight(L("Item"), cols[0]) + " " + CMStrings.padRight(L("Lvl"), cols[1]) + " " + CMStrings.padRight(L("Amt"), cols[2])); buf.append("\n\r"); for (int r = 0; r < recipes.size(); r++) { final List<String> V = recipes.get(r); if (V.size() > 0) { final String item = replacePercent(V.get(RCP_FINALNAME), ""); final int level = CMath.s_int(V.get(RCP_LEVEL)); final String wood = getComponentDescription(mob, V, RCP_WOOD); if (wood.length() > 5) { if (toggler > 1) buf.append("\n\r"); toggler = toggleTop; } if (((level <= xlevel(mob)) || allFlag) && ((mask.length() == 0) || mask.equalsIgnoreCase("all") || CMLib.english().containsString(item, mask))) { buf.append( CMStrings.padRight(item, cols[0]) + " " + CMStrings.padRight("" + (level), cols[1]) + " " + CMStrings.padRightPreserve("" + wood, cols[2]) + ((toggler != toggleTop) ? " " : "\n\r")); if (++toggler > toggleTop) toggler = 1; } } } if (toggler != 1) buf.append("\n\r"); commonTell(mob, buf.toString()); enhanceList(mob); return true; } else if (((commands.get(0))).equalsIgnoreCase("learn")) { return doLearnRecipe(mob, commands, givenTarget, auto, asLevel); } else if (str.equalsIgnoreCase("scan")) return publicScan(mob, commands); else if (str.equalsIgnoreCase("mend")) { buildingI = null; activity = CraftingActivity.CRAFTING; messedUp = false; final Vector<String> newCommands = CMParms.parse(CMParms.combine(commands, 1)); buildingI = getTarget(mob, mob.location(), givenTarget, newCommands, Wearable.FILTER_UNWORNONLY); if (!canMend(mob, buildingI, false)) return false; activity = CraftingActivity.MENDING; if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; startStr = L("<S-NAME> start(s) mending @x1.", buildingI.name()); displayText = L("You are mending @x1", buildingI.name()); verb = L("mending @x1", buildingI.name()); } else if (str.equalsIgnoreCase("refit")) { buildingI = null; activity = CraftingActivity.CRAFTING; messedUp = false; final Vector<String> newCommands = CMParms.parse(CMParms.combine(commands, 1)); buildingI = getTarget(mob, mob.location(), givenTarget, newCommands, Wearable.FILTER_UNWORNONLY); if (buildingI == null) return false; if ((buildingI.material() & RawMaterial.MATERIAL_MASK) != RawMaterial.MATERIAL_LEATHER) { commonTell(mob, L("That's not made of leather. That can't be refitted.")); return false; } if (!(buildingI instanceof Armor)) { commonTell(mob, L("You don't know how to refit that sort of thing.")); return false; } if (buildingI.phyStats().height() == 0) { commonTell(mob, L("@x1 is already the right size.", buildingI.name(mob))); return false; } activity = CraftingActivity.REFITTING; if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; startStr = L("<S-NAME> start(s) refitting @x1.", buildingI.name()); displayText = L("You are refitting @x1", buildingI.name()); verb = L("refitting @x1", buildingI.name()); } else { buildingI = null; activity = CraftingActivity.CRAFTING; messedUp = false; aborted = false; int amount = -1; if ((commands.size() > 1) && (CMath.isNumber(commands.get(commands.size() - 1)))) { amount = CMath.s_int(commands.get(commands.size() - 1)); commands.remove(commands.size() - 1); } final String recipeName = CMParms.combine(commands, 0); List<String> foundRecipe = null; final List<List<String>> matches = matchingRecipeNames(recipes, recipeName, true); for (int r = 0; r < matches.size(); r++) { final List<String> V = matches.get(r); if (V.size() > 0) { final String name = V.get(RCP_FINALNAME); final int level = CMath.s_int(V.get(RCP_LEVEL)); if (level <= xlevel(mob)) { final int x = name.indexOf(' '); final Stage stage = Stage.valueOf(name.substring(0, x)); multiplier = stage.multiplier; foundRecipe = V; break; } } } if (foundRecipe == null) { commonTell( mob, L( "You don't know how to make a '@x1'. Try \"mleatherwork list\" for a list.", recipeName)); return false; } final String woodRequiredStr = foundRecipe.get(RCP_WOOD); final int[] compData = new int[CF_TOTAL]; final List<Object> componentsFoundList = getAbilityComponents( mob, woodRequiredStr, "make " + CMLib.english().startWithAorAn(recipeName), autoGenerate, compData); if (componentsFoundList == null) return false; int woodRequired = CMath.s_int(woodRequiredStr); woodRequired = adjustWoodRequired(woodRequired, mob); if (amount > woodRequired) woodRequired = amount; final int[] pm = {RawMaterial.MATERIAL_LEATHER}; final int[] pm1 = {RawMaterial.MATERIAL_METAL, RawMaterial.MATERIAL_MITHRIL}; final String misctype = foundRecipe.get(RCP_MISCTYPE); bundling = misctype.equalsIgnoreCase("BUNDLE"); final int[][] data = fetchFoundResourceData( mob, woodRequired, "leather", pm, (multiplier == 6) ? 1 : 0, (multiplier == 6) ? "metal" : null, (multiplier == 6) ? pm1 : null, bundling, autoGenerate, enhancedTypes); if (data == null) return false; fixDataForComponents(data, componentsFoundList); woodRequired = data[0][FOUND_AMT]; if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; final int lostValue = autoGenerate > 0 ? 0 : CMLib.materials() .destroyResourcesValue( mob.location(), woodRequired, data[0][FOUND_CODE], data[1][FOUND_CODE], null) + CMLib.ableComponents().destroyAbilityComponents(componentsFoundList); buildingI = CMClass.getItem(foundRecipe.get(RCP_CLASSTYPE)); if (buildingI == null) { commonTell(mob, L("There's no such thing as a @x1!!!", foundRecipe.get(RCP_CLASSTYPE))); return false; } duration = getDuration(multiplier * CMath.s_int(foundRecipe.get(RCP_TICKS)), mob, 30, 4); buildingI.setMaterial(super.getBuildingMaterial(woodRequired, data, compData)); String itemName = (replacePercent( foundRecipe.get(RCP_FINALNAME), RawMaterial.CODES.NAME(data[0][FOUND_CODE]))) .toLowerCase(); if (bundling) itemName = "a " + woodRequired + "# " + itemName; else if (itemName.endsWith("s")) itemName = "some " + itemName; else itemName = CMLib.english().startWithAorAn(itemName); buildingI.setName(itemName); startStr = L("<S-NAME> start(s) making @x1.", buildingI.name()); displayText = L("You are making @x1", buildingI.name()); verb = L("making @x1", buildingI.name()); buildingI.setDisplayText(L("@x1 lies here", itemName)); buildingI.setDescription(itemName + ". "); buildingI .basePhyStats() .setWeight(getStandardWeight(woodRequired + compData[CF_AMOUNT], bundling)); buildingI.setBaseValue(CMath.s_int(foundRecipe.get(RCP_VALUE)) * multiplier); buildingI.setSecretIdentity(getBrand(mob)); final int hardness = RawMaterial.CODES.HARDNESS(buildingI.material()) - 2; buildingI.basePhyStats().setLevel(CMath.s_int(foundRecipe.get(RCP_LEVEL)) + hardness); final int capacity = CMath.s_int(foundRecipe.get(RCP_CAPACITY)); final long canContain = getContainerType(foundRecipe.get(RCP_CONTAINMASK)); int armordmg = CMath.s_int(foundRecipe.get(RCP_ARMORDMG)); if (armordmg != 0) armordmg = armordmg + (multiplier - 1); if (bundling) buildingI.setBaseValue(lostValue); final String spell = (foundRecipe.size() > RCP_SPELL) ? foundRecipe.get(RCP_SPELL).trim() : ""; addSpells(buildingI, spell); if (buildingI instanceof Weapon) { ((Weapon) buildingI) .basePhyStats() .setAttackAdjustment(baseYield() + abilityCode() + (hardness * 5) - 1); ((Weapon) buildingI).setWeaponClassification(Weapon.CLASS_FLAILED); setWeaponTypeClass((Weapon) buildingI, misctype, Weapon.TYPE_SLASHING); buildingI.basePhyStats().setDamage(armordmg + hardness); ((Weapon) buildingI).setRawProperLocationBitmap(Wearable.WORN_WIELD | Wearable.WORN_HELD); ((Weapon) buildingI).setRawLogicalAnd((capacity > 1)); } if ((buildingI instanceof Armor) && (!(buildingI instanceof FalseLimb))) { if ((capacity > 0) && (buildingI instanceof Container)) { ((Container) buildingI).setCapacity(capacity + woodRequired); ((Container) buildingI).setContainTypes(canContain); } ((Armor) buildingI).basePhyStats().setArmor(0); if (armordmg != 0) ((Armor) buildingI) .basePhyStats() .setArmor(armordmg + (baseYield() + abilityCode() - 1) + hardness); setWearLocation(buildingI, misctype, 0); } if (buildingI instanceof Drink) { if (CMLib.flags().isGettable(buildingI)) { ((Drink) buildingI).setLiquidRemaining(0); ((Drink) buildingI).setLiquidHeld(capacity * 50); ((Drink) buildingI).setThirstQuenched(250); if ((capacity * 50) < 250) ((Drink) buildingI).setThirstQuenched(capacity * 50); } } buildingI.recoverPhyStats(); buildingI.text(); buildingI.recoverPhyStats(); } messedUp = !proficiencyCheck(mob, 0, auto); if (bundling) { messedUp = false; duration = 1; verb = L("bundling @x1", RawMaterial.CODES.NAME(buildingI.material()).toLowerCase()); startStr = L("<S-NAME> start(s) @x1.", verb); displayText = L("You are @x1", verb); } if (autoGenerate > 0) { crafted.add(buildingI); return true; } final CMMsg msg = CMClass.getMsg(mob, buildingI, this, getActivityMessageType(), startStr); if (mob.location().okMessage(mob, msg)) { mob.location().send(mob, msg); buildingI = (Item) msg.target(); beneficialAffect(mob, mob, asLevel, duration); enhanceItem(mob, buildingI, enhancedTypes); } else if (bundling) { messedUp = false; aborted = false; unInvoke(); } return true; }
@Override public boolean execute(MOB mob, List<String> commands, int metaFlags) throws java.io.IOException { final StringBuffer head = new StringBuffer(""); final boolean isArchonLooker = CMSecurity.isASysOp(mob); head.append("^x["); head.append(CMStrings.padRight(L("Class"), 16) + " "); head.append(CMStrings.padRight(L("Race"), 8) + " "); head.append(CMStrings.padRight(L("Lvl"), 4) + " "); if (isArchonLooker) head.append(CMStrings.padRight(L("Last"), 18) + " "); head.append("] Character Name^.^?\n\r"); mob.tell( "^x[" + CMStrings.centerPreserve( L("The Administrators of @x1", CMProps.getVar(CMProps.Str.MUDNAME)), head.length() - 10) + "]^.^?"); final java.util.List<PlayerLibrary.ThinPlayer> allUsers = CMLib.database().getExtendedUserList(); String mask = CMProps.getVar(CMProps.Str.WIZLISTMASK); if (mask.length() == 0) mask = "-ANYCLASS +Archon"; final MaskingLibrary.CompiledZMask compiledMask = CMLib.masking().maskCompile(mask); for (final PlayerLibrary.ThinPlayer U : allUsers) { CharClass C; final MOB player = CMLib.players().getPlayer(U.name()); if (player != null) C = player.charStats().getCurrentClass(); else C = CMClass.getCharClass(U.charClass()); if (C == null) C = CMClass.findCharClass(U.charClass()); if (((player != null) && (CMLib.masking().maskCheck(compiledMask, player, true))) || (CMLib.masking().maskCheck(compiledMask, U))) { head.append("["); if (C != null) head.append(CMStrings.padRight(C.name(), 16) + " "); else head.append(CMStrings.padRight(L("Unknown"), 16) + " "); head.append(CMStrings.padRight(U.race(), 8) + " "); if ((C == null) || (!C.leveless())) head.append(CMStrings.padRight("" + U.level(), 4) + " "); else head.append(CMStrings.padRight(" ", 4) + " "); if (isArchonLooker) head.append(CMStrings.padRight(CMLib.time().date2String(U.last()), 18) + " "); head.append("] " + U.name()); head.append("\n\r"); } } mob.tell(head.toString()); return false; }
@Override public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel) { if (CMParms.combine(commands, 0).equalsIgnoreCase("auto")) { DATA.clear(); IPS.clear(); final Hashtable<String, List<MOB>> ipes = new Hashtable<String, List<MOB>>(); for (final Session S : CMLib.sessions().localOnlineIterable()) { if ((S.getAddress().length() > 0) && (S.mob() != null)) { List V = ipes.get(S.getAddress()); if (V == null) { V = new Vector(); ipes.put(S.getAddress(), V); } if (!V.contains(S.mob())) V.add(S.mob()); } } final StringBuffer rpt = new StringBuffer(""); for (final Enumeration e = ipes.keys(); e.hasMoreElements(); ) { final String addr = (String) e.nextElement(); final List<MOB> names = ipes.get(addr); if (names.size() > 1) { IPS.put(addr, names); rpt.append("Watch #" + (IPS.size()) + " added: "); for (int n = 0; n < names.size(); n++) { final MOB MN = names.get(n); if (MN.fetchEffect(ID()) == null) { final Ability A = (Ability) copyOf(); MN.addNonUninvokableEffect(A); A.setSavable(false); } rpt.append(MN.Name() + " "); } rpt.append("\n\r"); } } if (rpt.length() == 0) rpt.append("No users with duplicate IDs found. Try MULTIWATCH ADD name1 name2 ... "); mob.tell(rpt.toString()); return true; } else if (CMParms.combine(commands, 0).equalsIgnoreCase("stop")) { boolean foundLegacy = false; for (final Session S : CMLib.sessions().localOnlineIterable()) { if ((S != null) && (S.mob() != null) && (S.mob().fetchEffect(ID()) != null)) { foundLegacy = true; break; } } if ((DATA.size() == 0) && (IPS.size() == 0) && (!foundLegacy)) { mob.tell(L("Multiwatch is already off.")); return false; } for (final Enumeration<List<MOB>> e = IPS.elements(); e.hasMoreElements(); ) { final List<MOB> V = e.nextElement(); for (int v = 0; v < V.size(); v++) { final MOB M = V.get(v); final Ability A = M.fetchEffect(ID()); if (A != null) M.delEffect(A); } } for (final Session S : CMLib.sessions().localOnlineIterable()) { if ((S != null) && (S.mob() != null)) { final MOB M = S.mob(); final Ability A = M.fetchEffect(ID()); if (A != null) M.delEffect(A); } } mob.tell(L("Multiplay watcher is now turned off.")); DATA.clear(); IPS.clear(); return true; } else if ((commands.size() > 1) && ((String) commands.firstElement()).equalsIgnoreCase("add")) { final Vector V = new Vector(); for (int i = 1; i < commands.size(); i++) { final String name = (String) commands.elementAt(i); final MOB M = CMLib.players().getPlayer(name); if ((M.session() != null) && (CMLib.flags().isInTheGame(M, true))) V.addElement(M); else mob.tell(L("'@x1' is not online.", name)); } if (V.size() > 1) { for (int n = 0; n < V.size(); n++) { final MOB MN = (MOB) V.elementAt(n); if (MN.fetchEffect(ID()) == null) { final Ability A = (Ability) copyOf(); MN.addNonUninvokableEffect(A); A.setSavable(false); } } IPS.put("MANUAL" + (IPS.size() + 1), V); mob.tell(L("Manual Watch #@x1 added.", "" + IPS.size())); } return true; } else if ((commands.size() == 0) && (DATA.size() > 0) && (IPS.size() > 0)) { final StringBuffer report = new StringBuffer(""); for (final Enumeration<String> e = IPS.keys(); e.hasMoreElements(); ) { final String key = e.nextElement(); int sync = 0; final List<MOB> V = IPS.get(key); for (int v = 0; v < V.size(); v++) { final MOB M = V.get(v); final int data[] = DATA.get(M); if (data != null) sync += data[DATA_SYNCHROFOUND]; } report.append("^x" + key + "^?^., Syncs: " + sync + "\n\r"); report.append( CMStrings.padRight(L("Name"), 25) + CMStrings.padRight(L("Speech"), 15) + CMStrings.padRight(L("Socials"), 15) + CMStrings.padRight(L("CMD"), 10) + CMStrings.padRight(L("ORDERS"), 10) + "\n\r"); for (int v = 0; v < V.size(); v++) { final MOB M = V.get(v); int data[] = DATA.get(M); if (data == null) data = new int[DATA_TOTAL]; report.append(CMStrings.padRight(M.Name(), 25)); report.append( CMStrings.padRight( data[DATA_GOODSPEECH] + "/" + data[DATA_DIRSPEECH] + "/" + data[DATA_ANYSPEECH], 15)); report.append( CMStrings.padRight( data[DATA_GOODSOCIAL] + "/" + data[DATA_DIRSOCIAL] + "/" + data[DATA_ANYSOCIAL], 15)); report.append(CMStrings.padRight(data[DATA_TYPEDCOMMAND] + "", 10)); report.append(CMStrings.padRight(data[DATA_ORDER] + "", 10)); report.append("\n\r"); } report.append("\n\r"); } mob.tell(report.toString()); return true; } else { mob.tell(L("Try MULTIWATCH AUTO, MULTIWATCH STOP, or MULTIWATCH ADD name1 name2..")); return false; } }
@Override public void executeMsg(Environmental host, CMMsg msg) { super.executeMsg(host, msg); if ((affected instanceof Item) && (text().length() > 0)) { final Item I = (Item) affected; if ((msg.sourceMinor() == CMMsg.TYP_SPEAK) && (msg.target() == I) && ((msg.source() == I.owner()) || (I.owner() instanceof Room)) && (msg.sourceMessage() != null) && (CMLib.english() .containsString( CMStrings.getSayFromMessage(msg.sourceMessage()).toUpperCase(), "REFUGE"))) { final Room newRoom = this.getRefuge(I); if ((newRoom != null) && (newRoom != msg.source().location())) { final Set<MOB> h = properTargets(msg.source(), null, false); if (h == null) return; final Room thisRoom = msg.source().location(); final Ability thisA = this; msg.addTrailerRunnable( new Runnable() { @Override public void run() { for (final Object element : h) { final MOB follower = (MOB) element; final CMMsg enterMsg = CMClass.getMsg( follower, newRoom, thisA, CMMsg.MSG_ENTER, null, CMMsg.MSG_ENTER, null, CMMsg.MSG_ENTER, L( "<S-NAME> appears in a puff of smoke.@x1", CMLib.protocol().msp("appear.wav", 10))); final CMMsg leaveMsg = CMClass.getMsg( follower, thisRoom, thisA, CMMsg.MSG_LEAVE | CMMsg.MASK_MAGIC, L("<S-NAME> disappear(s) in a puff of smoke.")); if (thisRoom.okMessage(follower, leaveMsg) && newRoom.okMessage(follower, enterMsg)) { if (follower.isInCombat()) { CMLib.commands().postFlee(follower, ("NOWHERE")); follower.makePeace(); } thisRoom.send(follower, leaveMsg); newRoom.bringMobHere(follower, false); newRoom.send(follower, enterMsg); follower.tell(L("\n\r\n\r")); CMLib.commands().postLook(follower, true); } } } }); unInvoke(); } } } }
@Override public boolean invoke( final MOB mob, Vector commands, Physical givenTarget, final boolean auto, final int asLevel) { final Vector originalCommands = (Vector) commands.clone(); if (super.checkStop(mob, commands)) return true; fireRequired = true; final CraftParms parsedVars = super.parseAutoGenerate(auto, givenTarget, commands); givenTarget = parsedVars.givenTarget; final PairVector<Integer, Integer> enhancedTypes = enhancedTypes(mob, commands); randomRecipeFix(mob, addRecipes(mob, loadRecipes()), commands, parsedVars.autoGenerate); if (commands.size() == 0) { commonTell( mob, L( "Make what? Enter \"@x1 list\" for a list, \"@x2 learn <item>\" to gain recipes, or \"@x3 stop\" to cancel.", triggerStrings()[0].toLowerCase(), triggerStrings()[0].toLowerCase(), triggerStrings()[0].toLowerCase())); return false; } if ((!auto) && (commands.size() > 0) && (((String) commands.firstElement()).equalsIgnoreCase("bundle"))) { bundling = true; if (super.invoke(mob, commands, givenTarget, auto, asLevel)) return super.bundle(mob, commands); return false; } final List<List<String>> recipes = addRecipes(mob, loadRecipes()); final String str = (String) commands.elementAt(0); String startStr = null; bundling = false; int duration = 4; final int[] cols = { ListingLibrary.ColFixer.fixColWidth(16, mob.session()), ListingLibrary.ColFixer.fixColWidth(3, mob.session()) }; if (str.equalsIgnoreCase("list")) { String mask = CMParms.combine(commands, 1); boolean allFlag = false; if (mask.equalsIgnoreCase("all")) { allFlag = true; mask = ""; } final StringBuffer buf = new StringBuffer( L( "@x1 @x2 Metals required\n\r", CMStrings.padRight(L("Item"), cols[0]), CMStrings.padRight(L("Lvl"), cols[1]))); for (int r = 0; r < recipes.size(); r++) { final List<String> V = recipes.get(r); if (V.size() > 0) { final String item = replacePercent(V.get(RCP_FINALNAME), ""); final int level = CMath.s_int(V.get(RCP_LEVEL)); final String wood = getComponentDescription(mob, V, RCP_WOOD); if (((level <= xlevel(mob)) || allFlag) && ((mask.length() == 0) || mask.equalsIgnoreCase("all") || CMLib.english().containsString(item, mask))) buf.append( CMStrings.padRight(item, cols[0]) + " " + CMStrings.padRight("" + level, cols[1]) + " " + wood + "\n\r"); } } commonTell(mob, buf.toString()); enhanceList(mob); return true; } else if ((commands.firstElement() instanceof String) && (((String) commands.firstElement())).equalsIgnoreCase("learn")) { return doLearnRecipe(mob, commands, givenTarget, auto, asLevel); } activity = CraftingActivity.CRAFTING; buildingI = null; messedUp = false; String statue = null; if ((commands.size() > 1) && ((String) commands.lastElement()).startsWith("STATUE=")) { statue = (((String) commands.lastElement()).substring(7)).trim(); if (statue.length() == 0) statue = null; else commands.removeElementAt(commands.size() - 1); } int amount = -1; if ((commands.size() > 1) && (CMath.isNumber((String) commands.lastElement()))) { amount = CMath.s_int((String) commands.lastElement()); commands.removeElementAt(commands.size() - 1); } final String recipeName = CMParms.combine(commands, 0); List<String> foundRecipe = null; final List<List<String>> matches = matchingRecipeNames(recipes, recipeName, true); for (int r = 0; r < matches.size(); r++) { final List<String> V = matches.get(r); if (V.size() > 0) { final int level = CMath.s_int(V.get(RCP_LEVEL)); if ((parsedVars.autoGenerate > 0) || (level <= xlevel(mob))) { foundRecipe = V; break; } } } if (foundRecipe == null) { commonTell( mob, L( "You don't know how to make a '@x1'. Try \"@x2 list\" for a list.", recipeName, triggerStrings[0].toLowerCase())); return false; } final String woodRequiredStr = foundRecipe.get(RCP_WOOD); final List<Object> componentsFoundList = getAbilityComponents( mob, woodRequiredStr, "make " + CMLib.english().startWithAorAn(recipeName), parsedVars.autoGenerate); if (componentsFoundList == null) return false; int woodRequired = CMath.s_int(woodRequiredStr); woodRequired = adjustWoodRequired(woodRequired, mob); if (amount > woodRequired) woodRequired = amount; final String misctype = foundRecipe.get(RCP_MISCTYPE); final int[] pm = {RawMaterial.MATERIAL_METAL, RawMaterial.MATERIAL_MITHRIL}; bundling = misctype.equalsIgnoreCase("BUNDLE"); final int[][] data = fetchFoundResourceData( mob, woodRequired, "metal", pm, 0, null, null, bundling, parsedVars.autoGenerate, enhancedTypes); if (data == null) return false; fixDataForComponents(data, componentsFoundList); woodRequired = data[0][FOUND_AMT]; if (!bundling) { fireRequired = true; final Item fire = getRequiredFire(mob, parsedVars.autoGenerate); if (fire == null) return false; } else fireRequired = false; final Session session = mob.session(); if ((misctype.equalsIgnoreCase("statue")) && (session != null) && ((statue == null) || (statue.trim().length() == 0))) { final Ability me = this; final Physical target = givenTarget; session.prompt( new InputCallback(InputCallback.Type.PROMPT, "", 0) { @Override public void showPrompt() { session.promptPrint(L("What is a statue this of?\n\r: ")); } @Override public void timedOut() {} @Override public void callBack() { final String of = this.input; if ((of.trim().length() == 0) || (of.indexOf('<') >= 0)) return; final Vector newCommands = (Vector) originalCommands.clone(); newCommands.add("STATUE=" + of); me.invoke(mob, newCommands, target, auto, asLevel); } }); return false; } if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false; final int lostValue = parsedVars.autoGenerate > 0 ? 0 : CMLib.materials() .destroyResourcesValue( mob.location(), data[0][FOUND_AMT], data[0][FOUND_CODE], 0, null) + CMLib.ableMapper().destroyAbilityComponents(componentsFoundList); buildingI = CMClass.getItem(foundRecipe.get(RCP_CLASSTYPE)); if (buildingI == null) { commonTell(mob, L("There's no such thing as a @x1!!!", foundRecipe.get(RCP_CLASSTYPE))); return false; } duration = getDuration( CMath.s_int(foundRecipe.get(RCP_TICKS)), mob, CMath.s_int(foundRecipe.get(RCP_LEVEL)), 4); String itemName = replacePercent(foundRecipe.get(RCP_FINALNAME), RawMaterial.CODES.NAME(data[0][FOUND_CODE])) .toLowerCase(); if (bundling) itemName = "a " + woodRequired + "# " + itemName; else itemName = CMLib.english().startWithAorAn(itemName); buildingI.setName(itemName); startStr = L("<S-NAME> start(s) smithing @x1.", buildingI.name()); displayText = L("You are smithing @x1", buildingI.name()); verb = L("smithing @x1", buildingI.name()); playSound = "tinktinktink2.wav"; buildingI.setDisplayText(L("@x1 lies here", itemName)); buildingI.setDescription(itemName + ". "); buildingI.basePhyStats().setWeight(getStandardWeight(woodRequired, bundling)); buildingI.setBaseValue( CMath.s_int(foundRecipe.get(RCP_VALUE)) + (woodRequired * (RawMaterial.CODES.VALUE(data[0][FOUND_CODE])))); buildingI.setMaterial(data[0][FOUND_CODE]); buildingI.basePhyStats().setLevel(CMath.s_int(foundRecipe.get(RCP_LEVEL))); buildingI.setSecretIdentity(getBrand(mob)); final int capacity = CMath.s_int(foundRecipe.get(RCP_CAPACITY)); final String spell = (foundRecipe.size() > RCP_SPELL) ? foundRecipe.get(RCP_SPELL).trim() : ""; addSpells(buildingI, spell); if ((misctype.equalsIgnoreCase("statue")) && (statue != null) && (statue.trim().length() > 0)) { buildingI.setName(L("@x1 of @x2", itemName, statue.trim())); buildingI.setDisplayText(L("@x1 of @x2 is here", itemName, statue.trim())); buildingI.setDescription(L("@x1 of @x2. ", itemName, statue.trim())); } else if (buildingI instanceof Rideable) { setRideBasis((Rideable) buildingI, misctype); if (capacity == 0) ((Rideable) buildingI).setRiderCapacity(1); else if (capacity < 5) ((Rideable) buildingI).setRiderCapacity(capacity); } else if (buildingI instanceof Container) { ((Container) buildingI).setCapacity(capacity + woodRequired); if (misctype.equalsIgnoreCase("LID")) ((Container) buildingI).setDoorsNLocks(true, false, true, false, false, false); else if (misctype.equalsIgnoreCase("LOCK")) { ((Container) buildingI).setDoorsNLocks(true, false, true, true, false, true); ((Container) buildingI).setKeyName(Double.toString(Math.random())); } else ((Container) buildingI).setContainTypes(getContainerType(misctype)); } if (buildingI instanceof Drink) { if (CMLib.flags().isGettable(buildingI)) { ((Drink) buildingI).setLiquidHeld(capacity * 50); ((Drink) buildingI).setThirstQuenched(250); if ((capacity * 50) < 250) ((Drink) buildingI).setThirstQuenched(capacity * 50); ((Drink) buildingI).setLiquidRemaining(0); } } if (bundling) buildingI.setBaseValue(lostValue); buildingI.recoverPhyStats(); buildingI.text(); buildingI.recoverPhyStats(); messedUp = !proficiencyCheck(mob, 0, auto); if (bundling) { messedUp = false; duration = 1; verb = L("bundling @x1", RawMaterial.CODES.NAME(buildingI.material()).toLowerCase()); startStr = L("<S-NAME> start(s) @x1.", verb); displayText = L("You are @x1", verb); } if (parsedVars.autoGenerate > 0) { commands.addElement(buildingI); return true; } final CMMsg msg = CMClass.getMsg(mob, buildingI, this, getActivityMessageType(), startStr); if (mob.location().okMessage(mob, msg)) { mob.location().send(mob, msg); buildingI = (Item) msg.target(); beneficialAffect(mob, mob, asLevel, duration); enhanceItem(mob, buildingI, enhancedTypes); } else if (bundling) { messedUp = false; aborted = false; unInvoke(); } return true; }
protected static boolean tryMerge( MOB mob, Room room, Environmental E, List things, List<String> changes, List<String> onfields, List<String> ignore, boolean noisy) { boolean didAnything = false; final List<String> efields = new Vector(); List<String> allMyFields = new Vector(); final String[] EFIELDS = E.getStatCodes(); for (int i = 0; i < EFIELDS.length; i++) if (!efields.contains(EFIELDS[i])) efields.add(EFIELDS[i]); efields.add("REJUV"); allMyFields = new XVector<String>(efields); for (int v = 0; v < ignore.size(); v++) if (efields.contains(ignore.get(v))) efields.remove(ignore.get(v)); for (int v = 0; v < changes.size(); v++) if (efields.contains(changes.get(v))) efields.remove(changes.get(v)); if (noisy) mergedebugtell(mob, "AllMy-" + CMParms.toStringList(allMyFields)); if (noisy) mergedebugtell(mob, "efields-" + CMParms.toStringList(efields)); for (int t = 0; t < things.size(); t++) { final Environmental E2 = (Environmental) things.get(t); if (noisy) mergedebugtell( mob, E.name() + "/" + E2.name() + "/" + CMClass.classID(E) + "/" + CMClass.classID(E2)); if (CMClass.classID(E).equals(CMClass.classID(E2))) { Vector fieldsToCheck = null; if (onfields.size() > 0) { fieldsToCheck = new Vector(); for (int v = 0; v < onfields.size(); v++) if (efields.contains(onfields.get(v))) fieldsToCheck.add(onfields.get(v)); } else fieldsToCheck = new XVector<String>(efields); boolean checkedOut = fieldsToCheck.size() > 0; if (noisy) mergedebugtell(mob, "fieldsToCheck-" + CMParms.toStringList(fieldsToCheck)); if (checkedOut) for (int i = 0; i < fieldsToCheck.size(); i++) { final String field = (String) fieldsToCheck.get(i); if (noisy) mergedebugtell( mob, field + "/" + getStat(E, field) + "/" + getStat(E2, field) + "/" + getStat(E, field).equals(getStat(E2, field))); if (!getStat(E, field).equals(getStat(E2, field))) { checkedOut = false; break; } } if (checkedOut) { List<String> fieldsToChange = null; if (changes.size() == 0) fieldsToChange = new XVector<String>(allMyFields); else { fieldsToChange = new Vector(); for (int v = 0; v < changes.size(); v++) if (allMyFields.contains(changes.get(v))) fieldsToChange.add(changes.get(v)); } if (noisy) mergedebugtell(mob, "fieldsToChange-" + CMParms.toStringList(fieldsToChange)); for (int i = 0; i < fieldsToChange.size(); i++) { final String field = fieldsToChange.get(i); if (noisy) mergedebugtell( mob, E.name() + " wants to change " + field + " value " + getStat(E, field) + " to " + getStat(E2, field) + "/" + (!getStat(E, field).equals(getStat(E2, field)))); if (!getStat(E, field).equals(getStat(E2, field))) { setStat(E, field, getStat(E2, field)); Log.sysOut( "Merge", "The " + CMStrings.capitalizeAndLower(field) + " field on " + E.Name() + " in " + room.roomID() + " was changed to " + getStat(E2, field) + "."); didAnything = true; } } } } } if (didAnything) { if (E instanceof Physical) ((Physical) E).recoverPhyStats(); if (E instanceof MOB) { ((MOB) E).recoverCharStats(); ((MOB) E).recoverMaxState(); } E.text(); } return didAnything; }
/** * A, well, Race * * @author Bo Zimmerman */ public interface Race extends Tickable, StatsAffecting, MsgListener, CMObject, Modifiable { /** * Return a nice, displayable name for this race * * @return the races name */ @Override public String name(); /** * Which racial category this race falls in. * * @return racial category */ public String racialCategory(); /** * Returns one or a combination of the Area.THEME_* constants from the Area interface. This bitmap * then describes the types of areas, skills, and classes which can interact. This bitmap is also * used to to tell whether the race is available for selection by users at char creation time, * whether they can change to this race via spells, or whether the race is utterly unavailable to * them. * * @see com.planet_ink.coffee_mud.Areas.interfaces.Area * @return the availability/theme of this race */ public int availabilityCode(); /** * After a mob is set or changed to a new race, this method should be called to finalize or * initialize any settings from this race. The verify flag is almost always true, unless the mob * is a new player being created, in which case false is sent. * * @param mob the mob or player being set to this race * @param verifyOnly true flag unless this is a new player character */ public void startRacing(MOB mob, boolean verifyOnly); /** * Will initialize a player or mobs height and weight based on this races parameters. * * @see com.planet_ink.coffee_mud.Common.interfaces.PhyStats * @param stats the PhyStats object to change * @param gender the mobs gender 'M' or 'F' */ public void setHeightWeight(PhyStats stats, char gender); /** * The minimum height of males of this race. * * @return minimum height of males in inches */ public int shortestMale(); /** * The minimum height of females of this race. * * @return minimum height of females in inches */ public int shortestFemale(); /** * The amount from 0-this to add to the minimum height to achieve a random height. * * @return a range of inches to add to the mimiumum height */ public int heightVariance(); /** * The lightest weight for a member of this race * * @return the lightest weight for something of this race */ public int lightestWeight(); /** * The amount from 0-this to add to the minumum weight to achieve a random weight. * * @return a range of pounds to add to the minimum weight */ public int weightVariance(); /** * Returns an integer array equal in size and index to the Race.AGE_* constants in the Race * interface. Each value in the index represents the first mudyear age of that age category. * * @see Race * @return an integer array mapping ages to age categories */ public int[] getAgingChart(); /** * A bitmap showing which on locations a member of this race can not wear clothing, even if the * members have one or more of the required limbs. The bitmap is made from Wearable.WORN_* * constant values. * * @see com.planet_ink.coffee_mud.Items.interfaces.Item * @return the illegal wear location bitmap */ public long forbiddenWornBits(); /** * Returns an array indexed by body part codes as defined by the BODY_* constants in the Race * interface. Each value is either -1 to show that the body part does not apply, 0 to show that * the body part is not found on this race, and 1 or more to show how many of that part this race * normally has. * * @return an array of body parts */ public int[] bodyMask(); /** * Converts this race to a generic race (if it isn't already) and returns it. Returns itself if * its already generic. * * @return the generic race. */ public Race makeGenRace(); /** * Converts this race to a generic race (if it isn't already) and mixes its attributes with the * race passed it. A new race ID and a new race name must also be provided. * * @param race the race to use as a baseline * @param newRaceID the id of the new race * @param newRaceName the name of the new race * @return the generic race. */ public Race mixRace(Race race, String newRaceID, String newRaceName); /** * Returns a vector of Item objects representing the standard clothing, weapons, or other objects * commonly given to players of this race just starting out. * * @param myChar one who will receive the objects * @return a vector of Item objects */ public List<Item> outfit(MOB myChar); /** * Returns a description of the given mobs description, by consulting the mobs * curState().getHitPoints method. * * @see com.planet_ink.coffee_mud.MOBS.interfaces.MOB#curState() * @see com.planet_ink.coffee_mud.Common.interfaces.CharState#getHitPoints() * @param viewer the mob observing the health of this one * @param mob the mob whose health to check * @return a string describing his health */ public String healthText(MOB viewer, MOB mob); /** * Returns the list of ability IDs of skills that this race is flatly and quietly immune to, * whether malicious or not -- it just won't happen. * * @return the list of Ability IDs. */ public String[] abilityImmunities(); /** * Sends back a generic mob name appropriate to a mob of this race, at the given gender and * age-group. * * @param gender the gender of the mob * @param age the age category * @return a good name */ public String makeMobName(char gender, int age); /** * Returns a Weapon object representing what a member of this race fights with when unarmed. This * method may change what it returns on every call to mix things up a bit. * * @see com.planet_ink.coffee_mud.Items.interfaces.Weapon * @return a Weapon object representing claws or teeth, etc.. */ public Weapon myNaturalWeapon(); /** * Returns resource codes of what this race can breathe as an atmosphere. The list is guarenteed * sorted. If the list is empty, the race can breathe anything at all. * * @see com.planet_ink.coffee_mud.Items.interfaces.RawMaterial * @return a list of resource codes that this race can breathe */ public int[] getBreathables(); /** * Returns a list of RawMaterial objects (usually GenFoodResource, GenLiquidResource, or * GenResource items) representing what is left over of a member of this race after they've been * butchered and cut up. * * @see com.planet_ink.coffee_mud.Items.interfaces.RawMaterial * @return a list of rawmaterial objects */ public List<RawMaterial> myResources(); /** * Returns the corpse of a member of this race, populates it with the equipment of the given mob, * and places it in the given room. If the destroyBodyAfterUse returns true, it will also populate * the body with the contents of the myResources method. * * @see #myResources() * @param mob the mob to use as a template for the body * @param room the room to place the corpse in * @return the corpse generated and placed in the room */ public DeadBody getCorpseContainer(MOB mob, Room room); /** * Whether this race object represents a Generic Race, or one which is modifiable by builders at * run-time. * * @return whether this race is modifiable at run-time. */ public boolean isGeneric(); /** * Whether this race is usually rideable; helps determine the appropriate java class to use. * * @return whether this race is generally rideable */ public boolean useRideClass(); /** * If this race is modifiable at run time, this method will return an xml document describing the * several attributes of this race. * * @see #isGeneric() * @see #setRacialParms(String) * @return an xml document describing this race */ public String racialParms(); /** * If this race is modifiable at run time, this method will use the given xml document describing * the several attributes of this race to populate this races fields and attributes. * * @see #isGeneric() * @see #racialParms() * @param parms an xml document describing this race */ public void setRacialParms(String parms); /** * Returns the string describing what folks see when a member of this race enters a room. Should * give an idea of the gate or walking style of this race. * * @return what people see what this race enters a room */ public String arriveStr(); /** * Returns the string describing what folks see when a member of this race leaves a room. Should * give an idea of the gate or walking style of this race. * * @return what people see what this race leaves a room */ public String leaveStr(); /** * This method is called whenever a player gains a level while a member of this race. If there are * any special things which need to be done to a player who gains a level, they can be done in * this method. By default, it doesn't do anything. * * @param mob the mob to level up * @param gainedAbilityIDs the set of abilities/skill IDs gained during this leveling process */ public void level(MOB mob, List<String> gainedAbilityIDs); /** * Whenever a player or mob of this race gains experience, this method gets a chance to modify the * amount before the gain actually occurs. * * @param host the player or mob whose race object this is * @param mob the player or mob gaining experience * @param victim if applicable, the mob or player who died to give the exp * @param amount the amount of exp on track for gaining * @return the adjusted amount of experience to gain */ public int adjustExperienceGain(MOB host, MOB mob, MOB victim, int amount); /** * Returns true if the given race is actually the same as the current race. Usually just * ID().equals(ID()), or if either is human. Passing the race to itself in this method is a good * way to check for general fertility. * * @param R the race to check * @return true if its the same as this one, false otherwise */ public boolean canBreedWith(Race R); /** * Whether this race can be associated with a character class. * * @see com.planet_ink.coffee_mud.CharClasses.interfaces.CharClass * @return whether this race can have a class */ public boolean classless(); /** * Whether players of this race can be associated with an experience level. * * @return whether players of this race can have a level */ public boolean leveless(); /** * Whether players of this race can gain or lose experience points. * * @return whether players of this race can gain or lose experience points */ public boolean expless(); /** * Return a vector of skills, spells, and other ability ids granted to the given mob when they are * created as this race. * * @see com.planet_ink.coffee_mud.Abilities.interfaces.Ability * @return a pairvector of the Ability names, and profficiencies */ public PairVector<String, Integer> culturalAbilities(); /** * Return a vector of skills, spells, and other abilities granted to the given mob of the given * mobs level. * * @see com.planet_ink.coffee_mud.Abilities.interfaces.Ability * @param mob the mob to grant the abilities to * @return a vector of the Ability objects */ public SearchIDList<Ability> racialAbilities(MOB mob); /** * Return a vector of skills, spells, and other abilities granted to the given mob of the given * mobs level. This method is not functionally used because it doesn't quite work correctly yet. * * @see com.planet_ink.coffee_mud.Abilities.interfaces.Ability * @see com.planet_ink.coffee_mud.Races.interfaces.Race#numRacialEffects(MOB) * @param mob the mob to grant the abilities to * @return a vector of the Ability objects */ public ChameleonList<Ability> racialEffects(MOB mob); /** * Returns the number of racial effects elligible to the given lob. Must faster and more efficient * than getting the whole list and checking its size. * * @param mob the mob to grant the abilities to * @return number of entries in the ability object vector */ public int numRacialEffects(MOB mob); /** * Apply any affects of the given mob at the given age to the given base and/or current char * stats. * * @see com.planet_ink.coffee_mud.Common.interfaces.CharState * @param mob the mob to apply changes to * @param baseStats permanent charstats changes * @param charStats temporary charstats changes */ public void agingAffects(MOB mob, CharStats baseStats, CharStats charStats); /** * Returns a list of the stat adjustments made by this race * * @return a list of the stat adjustments made by this race */ public String getStatAdjDesc(); /** * Returns the adjustment to practices made by this race (or nothing) * * @return the adjustment to practices made by this race (or nothing) */ public String getPracAdjDesc(); /** * Returns the adjustment to trains made by this race (or nothing) * * @return the adjustment to trains made by this race (or nothing) */ public String getTrainAdjDesc(); /** * Returns the list of modifications to senses done by this race or nothing. * * @return the list of modifications to senses done by this race */ public String getSensesChgDesc(); /** * Returns the list of modifications to disposition done by this race or nothing. * * @return the list of modifications to disposition done by this race */ public String getDispositionChgDesc(); /** * Returns the list of racial abilities granted to those of this race or nothing. * * @return the list of racial abilities granted to those of this race */ public String getAbilitiesDesc(); /** * Returns the list of racial languages granted to those of this race or nothing. * * @return the list of racial languages granted to those of this race */ public String getLanguagesDesc(); /** Age constant for an infant */ public static final int AGE_INFANT = 0; /** Age constant for a toddler */ public static final int AGE_TODDLER = 1; /** Age constant for a child */ public static final int AGE_CHILD = 2; /** Age constant for a yound adultt */ public static final int AGE_YOUNGADULT = 3; /** Age constant for the mature adult */ public static final int AGE_MATURE = 4; /** Age constant for the middle aged adult */ public static final int AGE_MIDDLEAGED = 5; /** Age constant for the old */ public static final int AGE_OLD = 6; /** Age constant for the very old */ public static final int AGE_VENERABLE = 7; /** Age constant for the very very old */ public static final int AGE_ANCIENT = 8; /** Constant string list for the names of the age constants, in their order of value */ public static final String[] AGE_DESCS = CMLib.lang() .sessionTranslation( new String[] { "Infant", "Toddler", "Child", "Young adult", "Adult", "Mature", "Old", "Venerable", "Ancient" }); /** Age in Years constant for an immortal thing */ public static final int YEARS_AGE_LIVES_FOREVER = Integer.MAX_VALUE; /** body part constant representing antenea */ public static final int BODY_ANTENEA = 0; /** body part constant representing eyes */ public static final int BODY_EYE = 1; /** body part constant representing ears */ public static final int BODY_EAR = 2; /** body part constant representing head */ public static final int BODY_HEAD = 3; /** body part constant representing neck */ public static final int BODY_NECK = 4; /** body part constant representing arm */ public static final int BODY_ARM = 5; /** body part constant representing hand */ public static final int BODY_HAND = 6; /** body part constant representing torso */ public static final int BODY_TORSO = 7; /** body part constant representing legs */ public static final int BODY_LEG = 8; /** body part constant representing feet */ public static final int BODY_FOOT = 9; /** body part constant representing noses */ public static final int BODY_NOSE = 10; /** body part constant representing gills */ public static final int BODY_GILL = 11; /** body part constant representing mouth */ public static final int BODY_MOUTH = 12; /** body part constant representing waists */ public static final int BODY_WAIST = 13; /** body part constant representing tails */ public static final int BODY_TAIL = 14; /** body part constant representing wings */ public static final int BODY_WING = 15; /** the number of body part constants */ public static final int BODY_PARTS = 16; /** constant string list naming each of the BODY_* constants in the order of their value */ public static final String[] BODYPARTSTR = { "ANTENEA", "EYE", "EAR", "HEAD", "NECK", "ARM", "HAND", "TORSO", "LEG", "FOOT", "NOSE", "GILL", "MOUTH", "WAIST", "TAIL", "WING" }; /** constant hash of BODYPARTSTR */ public static final Map<Object, Integer> BODYPARTHASH = CMStrings.makeNumericHash(BODYPARTSTR); /** constant used to set and check the classless flag on generic races */ public static final int GENFLAG_NOCLASS = 1; /** constant used to set and check the levelless flag on generic races */ public static final int GENFLAG_NOLEVELS = 2; /** constant used to set and check the expless flag on generic races */ public static final int GENFLAG_NOEXP = 4; /** constant used to set and check the charming flag on generic races */ public static final int GENFLAG_NOCHARM = 8; /** constant used to set and check the fertility flag on generic races */ public static final int GENFLAG_NOFERTILE = 16; /** constant string list naming each of the GENFLAG_* constants in the order of their value */ public static final String[] GENFLAG_DESCS = { "CLASSLESS", "LEVELLESS", "EXPLESS", "CHARMLESS", "CHILDLESS" }; public static final Map<String, Integer> BODYPARTHASH_RL_LOWER = new SHashtable<String, Integer>( new Enumeration<Pair<String, Integer>>() { private int index = 0; private final Stack<Pair<String, Integer>> others = new Stack<Pair<String, Integer>>(); @Override public boolean hasMoreElements() { return (others.size() > 0) || (index < BODYPARTSTR.length); } @Override public Pair<String, Integer> nextElement() { if (!hasMoreElements()) throw new NoSuchElementException(); if (others.size() > 0) return others.pop(); others.push( new Pair<String, Integer>( BODYPARTSTR[index].toLowerCase(), Integer.valueOf(index))); others.push( new Pair<String, Integer>( "left " + BODYPARTSTR[index].toLowerCase(), Integer.valueOf(index))); others.push( new Pair<String, Integer>( "right " + BODYPARTSTR[index].toLowerCase(), Integer.valueOf(index))); index++; return others.pop(); } }); /** array mapping worn locations to body parts, indexed by body parts. */ public static final long[] BODY_WEARVECTOR = { Wearable.WORN_HEAD, // ANTENEA, having any of these removes that pos Wearable.WORN_EYES, // EYES, having any of these adds this position Wearable.WORN_EARS, // EARS, gains a wear position here for every 2 Wearable.WORN_HEAD, // HEAD, gains a wear position here for every 1 Wearable.WORN_NECK, // NECK, gains a wear position here for every 1 Wearable.WORN_ARMS, // ARMS, gains a wear position here for every 2 Wearable.WORN_HANDS, // HANDS, gains a wear position here for every 1 Wearable.WORN_TORSO, // TORSO, gains a wear position here for every 1 Wearable.WORN_LEGS, // LEGS, gains a wear position here for every 2 Wearable.WORN_FEET, // FEET, gains a wear position here for every 2 Wearable.WORN_HEAD, // NOSE, No applicable wear position for this body part Wearable.WORN_HEAD, // GILLS, No applicable wear position for this body part Wearable.WORN_MOUTH, // MOUTH, gains a wear position here for every 1 Wearable.WORN_WAIST, // WAIST, gains a wear position here for every 1 Wearable.WORN_BACK, // TAIL, having any of these removes that pos Wearable.WORN_BACK, // WINGS, having any of these removes that pos }; /** * 2 dimentional array, indexed first by body_ part constant, with each row having two values: the * first being the Wearable.WORN_ location which is affected by having or losing this body part, * and then the number of such body parts necessary to gain or lose one such wear location. A * value of -1 means N/A */ public static final long[][] BODY_WEARGRID = { {Wearable.WORN_HEAD, -1}, // ANTENEA, having any of these removes that pos {Wearable.WORN_EYES, 2}, // EYES, having any of these adds this position {Wearable.WORN_EARS, 2}, // EARS, gains a wear position here for every 2 {Wearable.WORN_HEAD, 1}, // HEAD, gains a wear position here for every 1 {Wearable.WORN_NECK, 1}, // NECK, gains a wear position here for every 1 {Wearable.WORN_ARMS, 2}, // ARMS, gains a wear position here for every 2 { Wearable.WORN_WIELD | Wearable.WORN_HELD | Wearable.WORN_HANDS | Wearable.WORN_LEFT_FINGER | Wearable.WORN_LEFT_WRIST | Wearable.WORN_RIGHT_FINGER | Wearable.WORN_RIGHT_WRIST, 1 }, // HANDS, gains a wear position here for every 1 // lots of exceptions apply to the above {Wearable.WORN_TORSO | Wearable.WORN_BACK, 1}, // TORSO, gains a wear position here for every 1 {Wearable.WORN_LEGS, 2}, // LEGS, gains a wear position here for every 2 {Wearable.WORN_FEET, 2}, // FEET, gains a wear position here for every 2 {-1, -1}, // NOSE, No applicable wear position for this body part {-1, -1}, // GILLS, No applicable wear position for this body part {Wearable.WORN_MOUTH, 1}, // MOUTH, gains a wear position here for every 1 {Wearable.WORN_WAIST, 1}, // WAIST, gains a wear position here for every 1 {-1, -1}, // TAIL, having any of these removes that pos {Wearable.WORN_BACK, -1}, // WINGS, having any of these removes that pos }; }
public StringBuffer deviations(MOB mob, String rest) { final Vector<String> V = CMParms.parse(rest); if ((V.size() == 0) || ((!V.get(0).equalsIgnoreCase("mobs")) && (!V.get(0).equalsIgnoreCase("items")) && (!V.get(0).equalsIgnoreCase("both")))) return new StringBuffer( "You must specify whether you want deviations on MOBS, ITEMS, or BOTH."); final String type = V.get(0).toLowerCase(); if (V.size() == 1) return new StringBuffer( "You must also specify a mob or item name, or the word room, or the word area."); final Room mobR = mob.location(); Faction useFaction = null; for (final Enumeration<Faction> e = CMLib.factions().factions(); e.hasMoreElements(); ) { final Faction F = e.nextElement(); if (F.showInSpecialReported()) useFaction = F; } final String where = V.get(1).toLowerCase(); final Environmental E = mobR.fetchFromMOBRoomFavorsItems(mob, null, where, Wearable.FILTER_ANY); final Vector<Environmental> check = new Vector<Environmental>(); if (where.equalsIgnoreCase("room")) fillCheckDeviations(mobR, type, check); else if (where.equalsIgnoreCase("area")) { for (final Enumeration<Room> r = mobR.getArea().getFilledCompleteMap(); r.hasMoreElements(); ) { final Room R = r.nextElement(); fillCheckDeviations(R, type, check); } } else if (where.equalsIgnoreCase("world")) { for (final Enumeration<Room> r = CMLib.map().roomsFilled(); r.hasMoreElements(); ) { final Room R = r.nextElement(); fillCheckDeviations(R, type, check); } } else if (E == null) return new StringBuffer("'" + where + "' is an unknown item or mob name."); else if (type.equals("items") && (!(E instanceof Weapon)) && (!(E instanceof Armor))) return new StringBuffer("'" + where + "' is not a weapon or armor item."); else if (type.equals("mobs") && (!(E instanceof MOB))) return new StringBuffer("'" + where + "' is not a MOB."); else if ((!(E instanceof Weapon)) && (!(E instanceof Armor)) && (!(E instanceof MOB))) return new StringBuffer("'" + where + "' is not a MOB, or Weapon, or Item."); else check.add(E); final StringBuffer str = new StringBuffer(""); str.append(L("Deviations Report:\n\r")); final StringBuffer itemResults = new StringBuffer(); final StringBuffer mobResults = new StringBuffer(); for (int c = 0; c < check.size(); c++) { if (check.get(c) instanceof Item) { final Item I = (Item) check.get(c); Weapon W = null; if (I instanceof Weapon) W = (Weapon) I; final Map<String, String> vals = CMLib.itemBuilder() .timsItemAdjustments( I, I.phyStats().level(), I.material(), I.rawLogicalAnd() ? 2 : 1, (W == null) ? 0 : W.weaponClassification(), I.maxRange(), I.rawProperLocationBitmap()); itemResults.append(CMStrings.padRight(I.name(), 20) + " "); itemResults.append(CMStrings.padRight(I.ID(), 10) + " "); itemResults.append(CMStrings.padRight("" + I.phyStats().level(), 4) + " "); itemResults.append( CMStrings.padRight( "" + getDeviation(I.basePhyStats().attackAdjustment(), vals, "ATTACK"), 5) + " "); itemResults.append( CMStrings.padRight("" + getDeviation(I.basePhyStats().damage(), vals, "DAMAGE"), 5) + " "); itemResults.append( CMStrings.padRight("" + getDeviation(I.basePhyStats().damage(), vals, "ARMOR"), 5) + " "); itemResults.append( CMStrings.padRight("" + getDeviation(I.baseGoldValue(), vals, "VALUE"), 5) + " "); itemResults.append( CMStrings.padRight( "" + ((I.phyStats().rejuv() == PhyStats.NO_REJUV) ? " MAX" : "" + I.phyStats().rejuv()), 5) + " "); if (I instanceof Weapon) itemResults.append(CMStrings.padRight("" + I.basePhyStats().weight(), 4)); else itemResults.append( CMStrings.padRight("" + getDeviation(I.basePhyStats().weight(), vals, "WEIGHT"), 4) + " "); if (I instanceof Armor) itemResults.append(CMStrings.padRight("" + ((Armor) I).phyStats().height(), 4)); else itemResults.append(CMStrings.padRight(" - ", 4) + " "); itemResults.append("\n\r"); } else { final MOB M = (MOB) check.get(c); mobResults.append(CMStrings.padRight(M.name(), 20) + " "); mobResults.append(CMStrings.padRight("" + M.phyStats().level(), 4) + " "); mobResults.append( CMStrings.padRight( "" + getDeviation( M.basePhyStats().attackAdjustment(), CMLib.leveler().getLevelAttack(M)), 5) + " "); mobResults.append( CMStrings.padRight( "" + getDeviation( M.basePhyStats().damage(), (int) Math.round( CMath.div( CMLib.leveler().getLevelMOBDamage(M), M.basePhyStats().speed()))), 5) + " "); mobResults.append( CMStrings.padRight( "" + getDeviation( M.basePhyStats().armor(), CMLib.leveler().getLevelMOBArmor(M)), 5) + " "); mobResults.append( CMStrings.padRight( "" + getDeviation( M.basePhyStats().speed(), CMLib.leveler().getLevelMOBSpeed(M)), 5) + " "); mobResults.append( CMStrings.padRight( "" + ((M.phyStats().rejuv() == PhyStats.NO_REJUV) ? " MAX" : "" + M.phyStats().rejuv()), 5) + " "); if (useFaction != null) mobResults.append( CMStrings.padRight( "" + (M.fetchFaction(useFaction.factionID()) == Integer.MAX_VALUE ? "N/A" : "" + M.fetchFaction(useFaction.factionID())), 7) + " "); double value = CMLib.beanCounter().getTotalAbsoluteNativeValue(M); double[] range = CMLib.leveler().getLevelMoneyRange(M); if (value < range[0]) mobResults.append(CMStrings.padRight("" + getDeviation(value, range[0]), 5) + " "); else if (value > range[1]) mobResults.append(CMStrings.padRight("" + getDeviation(value, range[1]), 5) + " "); else mobResults.append(CMStrings.padRight("0%", 5) + " "); int reallyWornCount = 0; for (int j = 0; j < M.numItems(); j++) { final Item Iw = M.getItem(j); if (!(Iw.amWearingAt(Wearable.IN_INVENTORY))) reallyWornCount++; } mobResults.append(CMStrings.padRight("" + reallyWornCount, 5) + " "); mobResults.append("\n\r"); } } if (itemResults.length() > 0) str.append(itemHeader() + itemResults.toString()); if (mobResults.length() > 0) str.append(mobHeader(useFaction) + mobResults.toString()); return str; }