@Override public void executeMsg(final Environmental myHost, final CMMsg msg) { super.executeMsg(myHost, msg); if ((myHost == null) || (!(myHost instanceof MOB))) return; final MOB mob = (MOB) myHost; if (msg.amISource(mob)) { if (((msg.sourceMinor() == CMMsg.TYP_LOOK) || (msg.sourceMinor() == CMMsg.TYP_EXAMINE)) && (msg.target() instanceof Wand) && (mob.charStats().getClassLevel(this) >= 30)) { final String message = "<O-NAME> has " + ((Wand) msg.target()).usesRemaining() + " charges remaining."; msg.addTrailerMsg( CMClass.getMsg( mob, null, msg.target(), CMMsg.MSG_OK_VISUAL, CMMsg.NO_EFFECT, CMMsg.NO_EFFECT, message)); } else if (msg.tool() != null) { if (msg.tool().ID().equals("Skill_Spellcraft")) { if ((msg.tool().text().length() > 0) && (msg.target() instanceof MOB)) { Ability A = ((MOB) msg.target()).fetchAbility(msg.tool().text()); if (A == null) return; final Ability myA = mob.fetchAbility(A.ID()); if (myA != null) { if ((!A.isSavable()) && ((A.classificationCode() & Ability.ALL_ACODES) == Ability.ACODE_SPELL) && (CMLib.ableMapper().lowestQualifyingLevel(A.ID()) < 30)) addAbilityToSpellcraftList(mob, A); } else if (CMLib.ableMapper().lowestQualifyingLevel(A.ID()) < 30) { final Vector<Ability> otherChoices = new Vector<Ability>(); for (int a = 0; a < mob.numAbilities(); a++) { final Ability A2 = mob.fetchAbility(a); if ((A2 != null) && (!A2.isSavable()) && ((A2.classificationCode() & Ability.ALL_ACODES) == Ability.ACODE_SPELL)) otherChoices.addElement(A2); } A = (Ability) A.copyOf(); A.setProficiency(0); A.setSavable(false); if (otherChoices.size() > (mob.charStats().getClassLevel(this) / 3)) { final Ability A2 = otherChoices.elementAt(CMLib.dice().roll(1, otherChoices.size(), -1)); clearAbilityFromSpellcraftList(mob, A2); } addAbilityToSpellcraftList(mob, A); } } } else if (msg.tool().ID().equals("Spell_Scribe") || msg.tool().ID().equals("Spell_EnchantWand") || msg.tool().ID().equals("Spell_MagicItem") || msg.tool().ID().equals("Spell_StoreSpell") || msg.tool().ID().equals("Spell_WardArea")) { final Ability A = mob.fetchAbility(msg.tool().text()); if ((A != null) && (!A.isSavable())) clearAbilityFromSpellcraftList(mob, A); } else if (msg.tool() instanceof Ability) { final Ability A = mob.fetchAbility(msg.tool().ID()); if ((A != null) && (!A.isSavable()) && ((A.classificationCode() & Ability.ALL_ACODES) == Ability.ACODE_SPELL)) clearAbilityFromSpellcraftList(mob, A); } } } }
@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; } }