예제 #1
0
  public void recursiveDropMOB(MOB mob, Room room, Item thisContainer, boolean bodyFlag) {
    // caller is responsible for recovering any env
    // stat changes!

    if (CMLib.flags().isHidden(thisContainer))
      thisContainer
          .baseEnvStats()
          .setDisposition(
              thisContainer.baseEnvStats().disposition()
                  & ((int) EnvStats.ALLMASK - EnvStats.IS_HIDDEN));
    mob.delInventory(thisContainer);
    thisContainer.unWear();
    if (!bodyFlag) bodyFlag = (thisContainer instanceof DeadBody);
    if (bodyFlag) {
      room.addItem(thisContainer);
      thisContainer.setExpirationDate(0);
    } else room.addItemRefuse(thisContainer, CMProps.getIntVar(CMProps.SYSTEMI_EXPIRE_PLAYER_DROP));
    thisContainer.recoverEnvStats();
    boolean nothingDone = true;
    do {
      nothingDone = true;
      for (int i = 0; i < mob.inventorySize(); i++) {
        Item thisItem = mob.fetchInventory(i);
        if ((thisItem != null) && (thisItem.container() == thisContainer)) {
          recursiveDropMOB(mob, room, thisItem, bodyFlag);
          nothingDone = false;
          break;
        }
      }
    } while (!nothingDone);
  }
예제 #2
0
 @Override
 public void setPermanentStat(int abilityCode, int value) {
   setStat(abilityCode, value);
   if (CharStats.CODES.isBASE(abilityCode))
     setStat(
         CharStats.CODES.toMAXBASE(abilityCode),
         value - CMProps.getIntVar(CMProps.Int.BASEMAXSTAT));
 }
예제 #3
0
  @Override
  public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel) {
    Item target = null;
    if ((commands.size() == 0) && (!auto) && (givenTarget == null))
      target = Prayer_Sacrifice.getBody(mob.location());
    if (target == null)
      target = getTarget(mob, mob.location(), givenTarget, commands, Wearable.FILTER_UNWORNONLY);
    if (target == null) return false;

    if ((!(target instanceof DeadBody))
        || (target.rawSecretIdentity().toUpperCase().indexOf("FAKE") >= 0)) {
      mob.tell(L("You may only desecrate the dead."));
      return false;
    }
    if ((((DeadBody) target).isPlayerCorpse())
        && (!((DeadBody) target).getMobName().equals(mob.Name()))
        && (((DeadBody) target).hasContent())) {
      mob.tell(L("You are not allowed to desecrate a players corpse."));
      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,
              target,
              this,
              verbalCastCode(mob, target, auto),
              auto
                  ? L("<T-NAME> feel(s) desecrated!")
                  : L("^S<S-NAME> desecrate(s) <T-NAMESELF> before @x1.^?", hisHerDiety(mob)));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        if (CMLib.flags().isEvil(mob)) {
          double exp = 5.0;
          final int levelLimit = CMProps.getIntVar(CMProps.Int.EXPRATE);
          final int levelDiff = (mob.phyStats().level()) - target.phyStats().level();
          if (levelDiff > levelLimit) exp = 0.0;
          if (exp > 0.0)
            CMLib.leveler()
                .postExperience(
                    mob, null, null, (int) Math.round(exp) + super.getXPCOSTLevel(mob), false);
        }
        target.destroy();
        mob.location().recoverRoomStats();
      }
    } else
      beneficialWordsFizzle(
          mob, target, L("<S-NAME> attempt(s) to desecrate <T-NAMESELF>, but fail(s)."));

    // return whether it worked
    return success;
  }
예제 #4
0
  public void startCharacter(MOB mob, boolean isBorrowedClass, boolean verifyOnly) {
    if (!loaded()) {
      setLoaded(true);
      LinkedList<CharClass> charClassesOrder = new LinkedList<CharClass>();
      HashSet<String> names = new HashSet<String>();
      for (Enumeration<CharClass> c = CMClass.charClasses(); c.hasMoreElements(); ) {
        CharClass C = c.nextElement();
        if (C.baseClass().equals(C.ID())
            && (!C.baseClass().equalsIgnoreCase("Archon"))
            && (!C.baseClass().equalsIgnoreCase("PlayerClass"))
            && (!C.baseClass().equalsIgnoreCase("Qualifier"))
            && (!C.baseClass().equalsIgnoreCase("StdCharClass"))) {
          names.add(C.ID());
          charClassesOrder.add(C);
        }
      }
      for (Enumeration<CharClass> c = CMClass.charClasses(); c.hasMoreElements(); ) {
        CharClass C = c.nextElement();
        if (!names.contains(C.ID()) && names.contains(C.baseClass())) charClassesOrder.add(C);
      }
      for (Enumeration<CharClass> c = CMClass.charClasses(); c.hasMoreElements(); ) {
        CharClass C = c.nextElement();
        if (C.baseClass().equals("Commoner") && (!names.contains(C.ID()))) charClassesOrder.add(C);
      }

      for (CharClass C : charClassesOrder) {
        LinkedList<List<String>> prevSets = new LinkedList<List<String>>();
        for (int lvl = 1; lvl < CMProps.getIntVar(CMProps.Int.LASTPLAYERLEVEL); lvl++) {
          List<String> curSet = CMLib.ableMapper().getLevelListings(C.ID(), false, lvl);
          for (String ID : curSet) {
            String defaultParam = CMLib.ableMapper().getDefaultParm(C.ID(), true, ID);
            if (CMLib.ableMapper().getQualifyingLevel(ID(), false, ID) < 0) {
              Ability A = CMClass.getAbility(ID);
              if (A == null) {
                Log.errOut("Unknonwn class: " + ID);
                continue;
              }
              List<String> reqSet = makeRequirements(prevSets, A);
              if (reqSet.size() > 0) reqSet = new XVector<String>(CMParms.toStringList(reqSet));
              int level = 0;
              if (!this.leveless() && (!CMSecurity.isDisabled(DisFlag.LEVELS)))
                level = CMLib.ableMapper().lowestQualifyingLevel(A.ID());
              if (level < 0) level = 0;
              CMLib.ableMapper()
                  .addCharAbilityMapping(ID(), 0, ID, 0, defaultParam, false, false, reqSet, "");
            }
          }
          if (curSet.size() > 0) prevSets.add(curSet);
        }
      }
    }
    super.startCharacter(mob, false, verifyOnly);
  }
예제 #5
0
 @Override
 public Trap setTrap(MOB mob, Physical P, int trapBonus, int qualifyingClassLevel, boolean perm) {
   if (P == null) return null;
   final Trap T = (Trap) copyOf();
   T.setInvoker(mob);
   P.addEffect(T);
   CMLib.threads()
       .startTickDown(
           T,
           Tickable.TICKID_TRAP_DESTRUCTION,
           CMProps.getIntVar(CMProps.Int.TICKSPERMUDDAY) + (2 * getXLEVELLevel(mob)));
   return T;
 }
예제 #6
0
 @Override
 public void setRacialStat(final int abilityCode, final int racialMax) {
   if ((!CharStats.CODES.isBASE(abilityCode)) || (getStat(abilityCode) == VALUE_ALLSTATS_DEFAULT))
     setPermanentStat(abilityCode, racialMax);
   else {
     final int baseMax = CMProps.getIntVar(CMProps.Int.BASEMAXSTAT);
     int currMax = getStat(CharStats.CODES.toMAXBASE(abilityCode)) + baseMax;
     if (currMax <= 0) currMax = 1;
     int curStat = getStat(abilityCode);
     if (curStat > currMax * 7) {
       final String errorMsg =
           "Detected mob with "
               + curStat
               + "/"
               + currMax
               + " "
               + CharStats.CODES.ABBR(abilityCode);
       @SuppressWarnings({"unchecked", "rawtypes"})
       Set<String> errs = (Set) Resources.getResource("SYSTEM_DEFCHARSTATS_ERRORS");
       if (errs == null) {
         errs = new TreeSet<String>();
         Resources.submitResource("SYSTEM_DEFCHARSTATS_ERRORS", errs);
       }
       if (!errs.contains(errorMsg)) {
         errs.add(errorMsg);
         final StringBuilder str = new StringBuilder(errorMsg);
         // ByteArrayOutputStream stream=new ByteArrayOutputStream();
         // new Exception().printStackTrace(new PrintStream(stream));
         // str.append("\n\r"+new String(stream.toByteArray()));
         Log.errOut("DefCharStats", str.toString());
       }
       curStat = currMax * 7;
     }
     final int pctOfMax = Math.round(((float) curStat / (float) currMax) * racialMax);
     final int stdMaxAdj =
         Math.round((((float) (currMax - VALUE_ALLSTATS_DEFAULT)) / (float) currMax) * racialMax);
     final int racialStat = pctOfMax + stdMaxAdj;
     setStat(abilityCode, ((racialStat < 1) && (racialMax > 0)) ? 1 : racialStat);
     setStat(CharStats.CODES.toMAXBASE(abilityCode), racialMax - baseMax);
   }
 }
예제 #7
0
파일: Merge.java 프로젝트: kingdavid127/MUD
  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;
  }
예제 #8
0
파일: Look.java 프로젝트: renokun/CoffeeMud
  @Override
  public boolean execute(MOB mob, Vector commands, int metaFlags) throws java.io.IOException {
    final Room R = mob.location();
    boolean quiet = false;
    if ((commands != null)
        && (commands.size() > 1)
        && (((String) commands.lastElement()).equalsIgnoreCase("UNOBTRUSIVELY"))) {
      commands.remove(commands.size() - 1);
      quiet = true;
    }
    final String textMsg = "<S-NAME> look(s) ";
    if (R == null) return false;
    if ((commands != null) && (commands.size() > 1)) {
      Environmental thisThang = null;

      if ((commands.size() > 2) && (((String) commands.get(1)).equalsIgnoreCase("at")))
        commands.remove(1);
      else if ((commands.size() > 2) && (((String) commands.get(1)).equalsIgnoreCase("to")))
        commands.remove(1);
      final String ID = CMParms.combine(commands, 1);

      if ((ID.toUpperCase().startsWith("EXIT") && (commands.size() == 2))
          && (CMProps.getIntVar(CMProps.Int.EXVIEW) != 1)) {
        final CMMsg exitMsg = CMClass.getMsg(mob, R, null, CMMsg.MSG_LOOK_EXITS, null);
        if ((CMProps.getIntVar(CMProps.Int.EXVIEW) >= 2) != mob.isAttribute(MOB.Attrib.BRIEF))
          exitMsg.setValue(CMMsg.MASK_OPTIMIZE);
        if (R.okMessage(mob, exitMsg)) R.send(mob, exitMsg);
        return false;
      }
      if (ID.equalsIgnoreCase("SELF") || ID.equalsIgnoreCase("ME")) thisThang = mob;

      if (thisThang == null) thisThang = R.fetchFromMOBRoomFavorsItems(mob, null, ID, noCoinFilter);
      if (thisThang == null)
        thisThang = R.fetchFromMOBRoomFavorsItems(mob, null, ID, Wearable.FILTER_ANY);
      if ((thisThang == null)
          && (commands.size() > 2)
          && (((String) commands.get(1)).equalsIgnoreCase("in"))) {
        commands.remove(1);
        final String ID2 = CMParms.combine(commands, 1);
        thisThang = R.fetchFromMOBRoomFavorsItems(mob, null, ID2, Wearable.FILTER_ANY);
        if ((thisThang != null)
            && ((!(thisThang instanceof Container)) || (((Container) thisThang).capacity() == 0))) {
          mob.tell(L("That's not a container."));
          return false;
        }
      }
      int dirCode = -1;
      Environmental lookingTool = null;
      if (thisThang == null) {
        dirCode = Directions.getGoodDirectionCode(ID);
        if (dirCode >= 0) {
          final Room room = R.getRoomInDir(dirCode);
          final Exit exit = R.getExitInDir(dirCode);
          if ((room != null) && (exit != null)) {
            thisThang = exit;
            lookingTool = room;
          } else {
            mob.tell(L("You don't see anything that way."));
            return false;
          }
        }
      }
      if (thisThang != null) {
        String name = "at <T-NAMESELF>";
        if ((thisThang instanceof Room) || (thisThang instanceof Exit)) {
          if (thisThang == R) name = "around";
          else if (dirCode >= 0)
            name =
                ((R instanceof BoardableShip) || (R.getArea() instanceof BoardableShip))
                    ? Directions.getShipDirectionName(dirCode)
                    : Directions.getDirectionName(dirCode);
        }
        final CMMsg msg =
            CMClass.getMsg(mob, thisThang, lookingTool, CMMsg.MSG_LOOK, textMsg + name + ".");
        if ((thisThang instanceof Room)
            && (mob.isAttribute(MOB.Attrib.AUTOEXITS))
            && (CMProps.getIntVar(CMProps.Int.EXVIEW) != 1)) {
          final CMMsg exitMsg =
              CMClass.getMsg(mob, thisThang, lookingTool, CMMsg.MSG_LOOK_EXITS, null);
          if ((CMProps.getIntVar(CMProps.Int.EXVIEW) >= 2) != mob.isAttribute(MOB.Attrib.BRIEF))
            exitMsg.setValue(CMMsg.MASK_OPTIMIZE);
          msg.addTrailerMsg(exitMsg);
        }
        if (R.okMessage(mob, msg)) R.send(mob, msg);
      } else mob.tell(L("You don't see that here!"));
    } else {
      if ((commands != null) && (commands.size() > 0))
        if (((String) commands.get(0)).toUpperCase().startsWith("E")) {
          mob.tell(L("Examine what?"));
          return false;
        }

      final CMMsg msg =
          CMClass.getMsg(
              mob,
              R,
              null,
              CMMsg.MSG_LOOK,
              (quiet ? null : textMsg + "around."),
              CMMsg.MSG_LOOK,
              (quiet ? null : textMsg + "at you."),
              CMMsg.MSG_LOOK,
              (quiet ? null : textMsg + "around."));
      if ((mob.isAttribute(MOB.Attrib.AUTOEXITS))
          && (CMProps.getIntVar(CMProps.Int.EXVIEW) != 1)
          && (CMLib.flags().canBeSeenBy(R, mob))) {
        final CMMsg exitMsg = CMClass.getMsg(mob, R, null, CMMsg.MSG_LOOK_EXITS, null);
        if ((CMProps.getIntVar(CMProps.Int.EXVIEW) >= 2) != mob.isAttribute(MOB.Attrib.BRIEF))
          exitMsg.setValue(CMMsg.MASK_OPTIMIZE);
        msg.addTrailerMsg(exitMsg);
      }
      if (R.okMessage(mob, msg)) R.send(mob, msg);
    }
    return false;
  }
예제 #9
0
  public boolean invoke(
      MOB mob, Vector commands, Environmental givenTarget, boolean auto, int asLevel) {
    if (type.length() == 0) return false;
    if ((mob.getClanID() == null)
        || (mob.getClanID().equalsIgnoreCase(""))
        || (mob.getClanRole() == 0)) {
      mob.tell("You aren't even a member of a clan.");
      return false;
    }
    Clan C = CMLib.clans().getClan(mob.getClanID());
    if (C == null) {
      mob.tell("You aren't even a member of a clan.");
      return false;
    }
    if (C.allowedToDoThis(mob, Clan.FUNC_CLANENCHANT) != 1) {
      mob.tell("You are not authorized to draw from the power of your " + C.typeName() + ".");
      return false;
    }
    String ClanName = C.clanID();
    String ClanType = C.typeName();

    // Invoking will be like:
    //   CAST [CLANEQSPELL] ITEM QUANTITY
    //   -2   -1            0    1
    if (commands.size() < 1) {
      mob.tell("Enchant which spell onto what?");
      return false;
    }
    if (commands.size() < 2) {
      mob.tell("Use how much clan enchantment power?");
      return false;
    }
    Environmental target =
        mob.location()
            .fetchFromMOBRoomFavorsItems(
                mob, null, (String) commands.elementAt(0), Item.WORNREQ_UNWORNONLY);
    if ((target == null) || (!CMLib.flags().canBeSeenBy(target, mob))) {
      mob.tell("You don't see '" + ((String) commands.elementAt(0)) + "' here.");
      return false;
    }
    // Add clan power check start
    int points = CMath.s_int((String) commands.elementAt(1));
    if (points <= 0) {
      mob.tell("You need to use at least 1 enchantment point.");
      return false;
    }
    long exp = points * CMProps.getIntVar(CMProps.SYSTEMI_CLANENCHCOST);
    if ((C.getExp() < exp) || (exp < 0)) {
      mob.tell(
          "You need "
              + exp
              + " to do that, but your "
              + C.typeName()
              + " has only "
              + C.getExp()
              + " experience points.");
      return false;
    }

    // Add clan power check end
    if (target.fetchEffect("Prop_ClanEquipment") != null) {
      mob.tell(target.name() + " is already clan enchanted.");
      return false;
    }

    // lose all the mana!
    if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false;

    boolean success = proficiencyCheck(mob, 0, auto);

    C.setExp(C.getExp() - exp);
    C.update();

    if (success) {
      CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              this,
              verbalCastCode(mob, target, auto),
              "^S<S-NAME> move(s) <S-HIS-HER> fingers around <T-NAMESELF>, encanting intensely.^?");
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        Ability A = CMClass.getAbility("Prop_ClanEquipment");
        StringBuffer str = new StringBuffer("");
        str.append(type); // Type of Enchantment
        str.append(" ");
        str.append("" + points); // Power of Enchantment
        str.append(" \"");
        str.append(ClanName); // Clan Name
        str.append("\" \"");
        str.append(ClanType); // Clan Type
        str.append("\"");
        A.setMiscText(str.toString());
        target.addEffect(A);
      }
    } else
      beneficialWordsFizzle(
          mob,
          target,
          "<S-NAME> move(s) <S-HIS-HER> fingers around <T-NAMESELF>, encanting intensely, and looking very frustrated.");
    return success;
  }
예제 #10
0
  @Override
  public boolean invoke(
      MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) {
    final Physical target = getAnyTarget(mob, commands, givenTarget, Wearable.FILTER_ANY, true);
    if (target == null) return false;

    if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false;

    int type = verbalCastCode(mob, target, auto);
    if ((target instanceof MOB)
        && (CMath.bset(type, CMMsg.MASK_MALICIOUS))
        && (((MOB) target).charStats().getStat(CharStats.STAT_AGE) > 0)) {
      final MOB mobt = (MOB) target;
      if (mobt.charStats().ageCategory() <= Race.AGE_CHILD)
        type = CMath.unsetb(type, CMMsg.MASK_MALICIOUS);
      else if ((mobt.getLiegeID().equals(mob.Name())) || (mobt.amFollowing() == mob))
        type = CMath.unsetb(type, CMMsg.MASK_MALICIOUS);
      else if ((mobt.charStats().ageCategory() <= Race.AGE_MATURE)
          && (mobt.getLiegeID().length() > 0)) type = CMath.unsetb(type, CMMsg.MASK_MALICIOUS);
    }

    if ((target instanceof Item)
        || ((target instanceof MOB)
            && (((MOB) target).isMonster())
            && (CMLib.flags().isAnimalIntelligence((MOB) target))
            && (CMLib.law().doesHavePriviledgesHere(mob, mob.location())))) {
      type = CMath.unsetb(type, CMMsg.MASK_MALICIOUS);
    }

    boolean success = proficiencyCheck(mob, 0, auto);
    if (success) {
      final CMMsg msg =
          CMClass.getMsg(
              mob, target, this, type, auto ? "" : L("^S<S-NAME> chant(s) to <T-NAMESELF>.^?"));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        final Ability A = target.fetchEffect("Age");
        if ((!(target instanceof MOB)) && (!(target instanceof CagedAnimal)) && (A == null)) {
          if (target instanceof Food) {
            mob.tell(L("@x1 rots away!", target.name(mob)));
            ((Item) target).destroy();
          } else if (target instanceof Item) {
            switch (((Item) target).material() & RawMaterial.MATERIAL_MASK) {
              case RawMaterial.MATERIAL_CLOTH:
              case RawMaterial.MATERIAL_FLESH:
              case RawMaterial.MATERIAL_LEATHER:
              case RawMaterial.MATERIAL_PAPER:
              case RawMaterial.MATERIAL_VEGETATION:
              case RawMaterial.MATERIAL_WOODEN:
                {
                  mob.location()
                      .showHappens(CMMsg.MSG_OK_VISUAL, L("@x1 rots away!", target.name()));
                  if (target instanceof Container) ((Container) target).emptyPlease(false);
                  ((Item) target).destroy();
                  break;
                }
              default:
                mob.location()
                    .showHappens(
                        CMMsg.MSG_OK_VISUAL,
                        L("@x1 ages, but nothing happens to it.", target.name()));
                break;
            }
          } else
            mob.location()
                .showHappens(
                    CMMsg.MSG_OK_VISUAL, L("@x1 ages, but nothing happens to it.", target.name()));
          success = false;
        } else if ((target instanceof MOB) && ((A == null) || (A.displayText().length() == 0))) {
          final MOB M = (MOB) target;
          mob.location().show(M, null, CMMsg.MSG_OK_VISUAL, L("<S-NAME> age(s) a bit."));
          if (M.baseCharStats().getStat(CharStats.STAT_AGE) <= 0)
            M.setAgeMinutes(M.getAgeMinutes() + (M.getAgeMinutes() / 10));
          else if ((M.playerStats() != null) && (M.playerStats().getBirthday() != null)) {
            final TimeClock C = CMLib.time().localClock(M.getStartRoom());
            final double aging = CMath.mul(M.baseCharStats().getStat(CharStats.STAT_AGE), .10);
            int years = (int) Math.round(Math.floor(aging));
            final int monthsInYear = C.getMonthsInYear();
            int months = (int) Math.round(CMath.mul(aging - Math.floor(aging), monthsInYear));
            if ((years <= 0) && (months == 0)) months++;
            M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_YEAR] -= years;
            M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_MONTH] -= months;
            if (M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_MONTH] < 1) {
              M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_YEAR]--;
              years++;
              M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_MONTH] =
                  monthsInYear + M.playerStats().getBirthday()[PlayerStats.BIRTHDEX_MONTH];
            }
            M.baseCharStats()
                .setStat(CharStats.STAT_AGE, M.baseCharStats().getStat(CharStats.STAT_AGE) + years);
          }
          M.recoverPhyStats();
          M.recoverCharStats();
        } else if (A != null) {
          final long start = CMath.s_long(A.text());
          long age = System.currentTimeMillis() - start;
          final long millisPerMudday =
              CMProps.getIntVar(CMProps.Int.TICKSPERMUDDAY) * CMProps.getTickMillis();
          if (age < millisPerMudday) age = millisPerMudday;
          final long millisPerMonth = CMLib.time().globalClock().getDaysInMonth() * millisPerMudday;
          final long millisPerYear = CMLib.time().globalClock().getMonthsInYear() * millisPerMonth;
          long ageBy = age / 10;
          if (ageBy < millisPerMonth) ageBy = millisPerMonth + 1;
          else if (ageBy < millisPerYear) ageBy = millisPerYear + 1;
          A.setMiscText("" + (start - ageBy));
          if (target instanceof MOB)
            mob.location()
                .show((MOB) target, null, CMMsg.MSG_OK_VISUAL, L("<S-NAME> age(s) a bit."));
          else mob.location().showHappens(CMMsg.MSG_OK_VISUAL, L("@x1 ages a bit.", target.name()));
          target.recoverPhyStats();
        } else
          return beneficialWordsFizzle(
              mob, target, L("<S-NAME> chant(s) to <T-NAMESELF>, but the magic fades."));
      }
    } else if (CMath.bset(type, CMMsg.MASK_MALICIOUS))
      return maliciousFizzle(
          mob, target, L("<S-NAME> chant(s) to <T-NAMESELF>, but the magic fades."));
    else
      return beneficialWordsFizzle(
          mob, target, L("<S-NAME> chant(s) to <T-NAMESELF>, but the magic fades."));

    // return whether it worked
    return success;
  }
예제 #11
0
  public static int updateLotWithThisData(
      Room R,
      LandTitle T,
      boolean resetRoomName,
      boolean clearAllItems,
      List optPlayerList,
      int lastNumItems) {
    boolean updateItems = false;
    boolean updateExits = false;
    boolean updateRoom = false;
    synchronized (("SYNC" + R.roomID()).intern()) {
      R = CMLib.map().getRoom(R);
      if (T.getOwnerName().length() == 0) {
        Item I = null;
        for (int i = R.numItems() - 1; i >= 0; i--) {
          I = R.getItem(i);
          if ((I == null) || (I.Name().equalsIgnoreCase("id"))) continue;
          CMLib.catalog().updateCatalogIntegrity(I);
          if (clearAllItems) {
            I.destroy();
            updateItems = true;
          } else {
            if (I.expirationDate() == 0) {
              long now = System.currentTimeMillis();
              now += (TimeManager.MILI_MINUTE * CMProps.getIntVar(CMProps.Int.EXPIRE_PLAYER_DROP));
              I.setExpirationDate(now);
            }
            if ((I.phyStats().rejuv() != PhyStats.NO_REJUV) && (I.phyStats().rejuv() != 0)) {
              I.basePhyStats().setRejuv(PhyStats.NO_REJUV);
              I.recoverPhyStats();
            }
          }
        }
        Ability A = null;
        if (clearAllItems)
          for (final Enumeration<Ability> a = R.effects(); a.hasMoreElements(); ) {
            A = a.nextElement();
            if (((A != null)
                && ((A.classificationCode() & Ability.ALL_ACODES) != Ability.ACODE_PROPERTY))) {
              A.unInvoke();
              R.delEffect(A);
              updateRoom = true;
            }
          }
        for (int d = Directions.NUM_DIRECTIONS() - 1; d >= 0; d--) {
          final Room R2 = R.rawDoors()[d];
          Exit E = R.getRawExit(d);
          if ((E != null) && (E.hasALock()) && (E.isGeneric())) {
            E.setKeyName("");
            E.setDoorsNLocks(E.hasADoor(), E.isOpen(), E.defaultsClosed(), false, false, false);
            updateExits = true;
            if (R2 != null) {
              E = R2.getRawExit(Directions.getOpDirectionCode(d));
              if ((E != null) && (E.hasALock()) && (E.isGeneric())) {
                E.setKeyName("");
                E.setDoorsNLocks(E.hasADoor(), E.isOpen(), E.defaultsClosed(), false, false, false);
                CMLib.database().DBUpdateExits(R2);
                R2.getArea().fillInAreaRoom(R2);
              }
            }
          }
        }
        if (updateExits) {
          CMLib.database().DBUpdateExits(R);
          R.getArea().fillInAreaRoom(R);
        }
        if (updateItems) CMLib.database().DBUpdateItems(R);
        if (updateRoom) CMLib.database().DBUpdateRoom(R);
        colorForSale(R, T.rentalProperty(), resetRoomName);
        return -1;
      }

      if ((lastNumItems < 0)
          && (!CMSecurity.isDisabled(CMSecurity.DisFlag.PROPERTYOWNERCHECKS))
          && (optPlayerList != null)) {
        boolean playerExists = (CMLib.players().getPlayer(T.getOwnerName()) != null);
        if (!playerExists) playerExists = (CMLib.clans().getClan(T.getOwnerName()) != null);
        if (!playerExists) playerExists = optPlayerList.contains(T.getOwnerName());
        if (!playerExists)
          for (int i = 0; i < optPlayerList.size(); i++)
            if (((String) optPlayerList.get(i)).equalsIgnoreCase(T.getOwnerName())) {
              playerExists = true;
              break;
            }
        if (!playerExists) {
          T.setOwnerName("");
          T.updateLot(null);
          return -1;
        }
      }

      int x = R.description().indexOf(SALESTR);
      if (x >= 0) {
        R.setDescription(R.description().substring(0, x));
        CMLib.database().DBUpdateRoom(R);
      }
      x = R.description().indexOf(RENTSTR);
      if (x >= 0) {
        R.setDescription(R.description().substring(0, x));
        CMLib.database().DBUpdateRoom(R);
      }

      // this works on the priciple that
      // 1. if an item has ONLY been removed, the lastNumItems will be != current # items
      // 2. if an item has ONLY been added, the dispossessiontime will be != null
      // 3. if an item has been added AND removed, the dispossession time will be != null on the
      // added
      if ((lastNumItems >= 0) && (R.numItems() != lastNumItems)) updateItems = true;

      for (int i = 0; i < R.numItems(); i++) {
        final Item I = R.getItem(i);
        if ((I.expirationDate() != 0)
            && ((I.isSavable()) || (I.Name().equalsIgnoreCase("id")))
            && ((!(I instanceof DeadBody)) || (((DeadBody) I).isPlayerCorpse()))) {
          I.setExpirationDate(0);
          updateItems = true;
        }

        if ((I.phyStats().rejuv() != Integer.MAX_VALUE) && (I.phyStats().rejuv() != 0)) {
          I.basePhyStats().setRejuv(PhyStats.NO_REJUV);
          I.recoverPhyStats();
          updateItems = true;
        }
      }
      lastNumItems = R.numItems();
      if ((!CMSecurity.isSaveFlag(CMSecurity.SaveFlag.NOPROPERTYITEMS)) && (updateItems))
        CMLib.database().DBUpdateItems(R);
    }
    return lastNumItems;
  }
예제 #12
0
 public double actionsCost(MOB mob, Vector cmds) {
   return CMath.div(CMProps.getIntVar(CMProps.SYSTEMI_DEFCMDTIME), 100.0);
 }
  @Override
  public boolean invoke(
      MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) {
    final MOB target = this.getTarget(mob, commands, givenTarget);
    if (target == null) return false;
    if ((mob.getWorshipCharID().length() == 0)
        || (CMLib.map().getDeity(mob.getWorshipCharID()) == null)) {
      if (!auto) mob.tell(L("You must worship a god to use this prayer."));
      return false;
    }
    final Deity D = CMLib.map().getDeity(mob.getWorshipCharID());
    if ((target.getWorshipCharID().length() > 0)
        && (CMLib.map().getDeity(target.getWorshipCharID()) != null)) {
      if (!auto)
        mob.tell(
            L(
                "@x1 worships @x2, and may not be converted with this prayer.",
                target.name(mob),
                target.getWorshipCharID()));
      return false;
    }
    if ((CMLib.flags().isAnimalIntelligence(target)
        || CMLib.flags().isGolem(target)
        || (D == null))) {
      if (!auto) mob.tell(L("@x1 can not be converted with this prayer.", target.name(mob)));
      return false;
    }
    if (!auto) {
      if (convertStack.contains(target)) {
        final Long L = (Long) convertStack.elementAt(convertStack.indexOf(target), 2);
        if ((System.currentTimeMillis() - L.longValue()) > CMProps.getMillisPerMudHour() * 5)
          convertStack.removeElement(target);
      }
      if (convertStack.contains(target)) {
        mob.tell(L("@x1 must wait to be undeniably faithful again.", target.name(mob)));
        return false;
      }
    }

    if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false;

    int levelDiff =
        target.phyStats().level() - (mob.phyStats().level() + (2 * getXLEVELLevel(mob)));
    if (levelDiff < 0) levelDiff = 0;
    final boolean success = proficiencyCheck(mob, -(levelDiff * 25), auto);
    int type = verbalCastCode(mob, target, auto);
    int mal = CMMsg.MASK_MALICIOUS;
    if (auto) {
      type = CMath.unsetb(type, CMMsg.MASK_MALICIOUS);
      mal = 0;
    }
    if (success) {
      final CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              this,
              type,
              auto ? "" : L("^S<S-NAME> @x1 for <T-NAMESELF> to BELIEVE!^?", prayWord(mob)));
      final CMMsg msg2 =
          CMClass.getMsg(target, D, this, CMMsg.MSG_SERVE, L("<S-NAME> BELIEVE(S) !!!"));
      final CMMsg msg3 =
          CMClass.getMsg(
              mob,
              target,
              this,
              CMMsg.MSK_CAST_VERBAL | mal | CMMsg.TYP_MIND | (auto ? CMMsg.MASK_ALWAYS : 0),
              null);
      if ((mob.location().okMessage(mob, msg))
          && (mob.location().okMessage(mob, msg3))
          && (mob.location().okMessage(mob, msg2))) {
        mob.location().send(mob, msg);
        mob.location().send(mob, msg3);
        if ((msg.value() <= 0) && (msg3.value() <= 0)) {
          target.location().send(target, msg2);
          target.setWorshipCharID(godName);
          if (mob != target) CMLib.leveler().postExperience(mob, target, null, 25, false);
          godName = mob.getWorshipCharID();
          beneficialAffect(mob, target, asLevel, CMProps.getIntVar(CMProps.Int.TICKSPERMUDMONTH));
          convertStack.addElement(target, Long.valueOf(System.currentTimeMillis()));
        }
      }
    } else
      beneficialWordsFizzle(
          mob,
          target,
          auto ? "" : L("<S-NAME> @x1 for <T-NAMESELF>, but nothing happens.", prayWord(mob)));

    // return whether it worked
    return success;
  }
예제 #14
0
파일: Email.java 프로젝트: bbailey/ewok
  public boolean execute(MOB mob, Vector commands, int metaFlags) throws java.io.IOException {
    if (mob.session() == null) return true;
    PlayerStats pstats = mob.playerStats();
    if (pstats == null) return true;

    if ((commands != null)
        && (commands.size() > 1)
        && (commands.elementAt(1) instanceof String)
        && (CMProps.getVar(CMProps.SYSTEM_MAILBOX).length() > 0)) {
      String name = CMParms.combine(commands, 1);
      if (name.equalsIgnoreCase("BOX")) {
        String journalName = CMProps.getVar(CMProps.SYSTEM_MAILBOX);
        Vector<JournalsLibrary.JournalEntry> msgs = CMLib.database().DBReadJournalMsgs(journalName);
        while ((mob.session() != null) && (!mob.session().killFlag())) {
          Vector mymsgs = new Vector();
          StringBuffer messages =
              new StringBuffer(
                  "^X" + CMStrings.padCenter(mob.Name() + "'s MailBox", 48) + "^?^.\n\r");
          messages.append(
              "^X### "
                  + CMStrings.padRight("From", 15)
                  + " "
                  + CMStrings.padRight("Date", 20)
                  + " Subject^?^.\n\r");
          for (int num = 0; num < msgs.size(); num++) {
            JournalsLibrary.JournalEntry thismsg = msgs.elementAt(num);
            String to = (String) thismsg.to;
            if (to.equalsIgnoreCase("ALL")
                || to.equalsIgnoreCase(mob.Name())
                || (to.toUpperCase().trim().startsWith("MASK=")
                    && CMLib.masking().maskCheck(to.trim().substring(5), mob, true))) {
              mymsgs.addElement(thismsg);
              messages.append(
                  CMStrings.padRight("" + mymsgs.size(), 4)
                      + CMStrings.padRight((thismsg.from), 16)
                      + CMStrings.padRight(CMLib.time().date2String(thismsg.date), 21)
                      + (thismsg.subj)
                      + "\n\r");
            }
          }
          if ((mymsgs.size() == 0)
              || (CMath.bset(metaFlags, Command.METAFLAG_POSSESSED))
              || (CMath.bset(metaFlags, Command.METAFLAG_AS))) {
            if (CMath.bset(mob.getBitmap(), MOB.ATT_AUTOFORWARD))
              mob.tell(
                  "You have no email waiting, but then, it's probably been forwarded to you already.");
            else mob.tell("You have no email waiting.");
            return false;
          }
          Session S = mob.session();
          try {
            if (S != null) S.snoopSuspension(1);
            mob.tell(messages.toString());
          } finally {
            if (S != null) S.snoopSuspension(-1);
          }
          String s = mob.session().prompt("Enter a message #", "");
          if ((!CMath.isInteger(s)) || (mob.session().killFlag())) return false;
          int num = CMath.s_int(s);
          if ((num <= 0) || (num > mymsgs.size())) mob.tell("That is not a valid number.");
          else
            while ((mob.session() != null) && (!mob.session().killFlag())) {
              JournalsLibrary.JournalEntry thismsg =
                  (JournalsLibrary.JournalEntry) mymsgs.elementAt(num - 1);
              String key = thismsg.key;
              String from = thismsg.from;
              String date = CMLib.time().date2String(thismsg.date);
              String subj = thismsg.subj;
              String message = thismsg.msg;
              messages = new StringBuffer("");
              messages.append("^XMessage :^?^." + num + "\n\r");
              messages.append("^XFrom    :^?^." + from + "\n\r");
              messages.append("^XDate    :^?^." + date + "\n\r");
              messages.append("^XSubject :^?^." + subj + "\n\r");
              messages.append("^X------------------------------------------------^?^.\n\r");
              messages.append(message + "\n\r\n\r");
              try {
                if (S != null) S.snoopSuspension(1);
                mob.tell(messages.toString());
              } finally {
                if (S != null) S.snoopSuspension(-1);
              }
              s =
                  mob.session()
                      .choose("Would you like to D)elete, H)old, or R)eply (D/H/R)? ", "DHR", "H");
              if (s.equalsIgnoreCase("H")) break;
              if (s.equalsIgnoreCase("R")) {
                if ((from.length() > 0)
                    && (!from.equals(mob.Name()))
                    && (!from.equalsIgnoreCase("BOX"))
                    && (CMLib.players().getLoadPlayer(from) != null))
                  execute(mob, CMParms.makeVector(getAccessWords()[0], from), metaFlags);
                else mob.tell("You can not reply to this email.");
              } else if (s.equalsIgnoreCase("D")) {
                CMLib.database().DBDeleteJournal(journalName, key);
                msgs.remove(thismsg);
                mob.tell("Deleted.");
                break;
              }
            }
        }
      } else {
        MOB M = CMLib.players().getLoadPlayer(name);
        if (M == null) {
          mob.tell(
              "There is no player called '"
                  + name
                  + "' to send email to.  If you were trying to read your mail, try EMAIL BOX.  If you were trying to change your email address, just enter EMAIL without any parameters.");
          return false;
        }
        if (!CMath.bset(M.getBitmap(), MOB.ATT_AUTOFORWARD)) {
          if (!mob.session().confirm("Send email to '" + M.Name() + "' (Y/n)?", "Y")) return false;
        } else {
          if (!mob.session()
              .confirm(
                  "Send email to '"
                      + M.Name()
                      + "', even though their AUTOFORWARD is turned off (y/N)?",
                  "N")) return false;
        }
        if (CMProps.getIntVar(CMProps.SYSTEMI_MAXMAILBOX) > 0) {
          int count =
              CMLib.database()
                  .DBCountJournal(CMProps.getVar(CMProps.SYSTEM_MAILBOX), null, M.Name());
          if (count >= CMProps.getIntVar(CMProps.SYSTEMI_MAXMAILBOX)) {
            mob.tell(M.Name() + "'s mailbox is full.");
            return false;
          }
        }
        String subject = mob.session().prompt("Email Subject: ", "").trim();
        if (subject.length() == 0) {
          mob.tell("Aborted");
          return false;
        }
        String message = mob.session().prompt("Enter your message\n\r: ", "").trim();
        if (message.trim().length() == 0) {
          mob.tell("Aborted");
          return false;
        }
        message +=
            "\n\r\n\rThis message was sent through the "
                + CMProps.getVar(CMProps.SYSTEM_MUDNAME)
                + " mail server at "
                + CMProps.getVar(CMProps.SYSTEM_MUDDOMAIN)
                + ", port"
                + CMProps.getVar(CMProps.SYSTEM_MUDPORTS)
                + ".  Please contact the administrators regarding any abuse of this system.\n\r";
        CMLib.database()
            .DBWriteJournal(
                CMProps.getVar(CMProps.SYSTEM_MAILBOX), mob.Name(), M.Name(), subject, message);
        mob.tell("Your email has been sent.");
        return true;
      }
    }
    if ((pstats.getEmail() == null) || (pstats.getEmail().length() == 0))
      mob.session().println("\n\rYou have no email address on file for this character.");
    else {
      if (commands == null) return true;
      String change =
          mob.session()
              .prompt(
                  "You currently have '"
                      + pstats.getEmail()
                      + "' set as the email address for this character.\n\rChange it (y/N)?",
                  "N");
      if (change.toUpperCase().startsWith("N")) return false;
    }
    if ((CMProps.getVar(CMProps.SYSTEM_EMAILREQ).toUpperCase().startsWith("PASS"))
        && (commands != null)
        && (CMProps.getVar(CMProps.SYSTEM_MAILBOX).length() > 0))
      mob.session()
          .println(
              "\n\r** Changing your email address will cause you to be logged off, and a new password to be generated and emailed to the new address. **\n\r");
    String newEmail = mob.session().prompt("New E-mail Address:");
    if (newEmail == null) return false;
    newEmail = newEmail.trim();
    if (!CMProps.getVar(CMProps.SYSTEM_EMAILREQ).toUpperCase().startsWith("OPTION")) {
      if (newEmail.length() < 6) return false;
      if (newEmail.indexOf("@") < 0) return false;
      String confirmEmail =
          mob.session()
              .prompt("Confirm that '" + newEmail + "' is correct by re-entering.\n\rRe-enter:");
      if (confirmEmail == null) return false;
      confirmEmail = confirmEmail.trim();
      if (confirmEmail.length() == 0) return false;
      if (!(newEmail.equalsIgnoreCase(confirmEmail))) return false;
    }
    pstats.setEmail(newEmail);
    CMLib.database().DBUpdateEmail(mob);
    if ((commands != null)
        && (CMProps.getVar(CMProps.SYSTEM_EMAILREQ).toUpperCase().startsWith("PASS"))
        && (CMProps.getVar(CMProps.SYSTEM_MAILBOX).length() > 0)) {
      String password = "";
      for (int i = 0; i < 6; i++) password += (char) ('a' + CMLib.dice().roll(1, 26, -1));
      pstats.setPassword(password);
      CMLib.database().DBUpdatePassword(mob.Name(), password);
      CMLib.database()
          .DBWriteJournal(
              CMProps.getVar(CMProps.SYSTEM_MAILBOX),
              mob.Name(),
              mob.Name(),
              "Password for " + mob.Name(),
              "Your new password for "
                  + mob.Name()
                  + " is: "
                  + pstats.password()
                  + "\n\rYou can login by pointing your mud client at "
                  + CMProps.getVar(CMProps.SYSTEM_MUDDOMAIN)
                  + " port(s):"
                  + CMProps.getVar(CMProps.SYSTEM_MUDPORTS)
                  + ".\n\rYou may use the PASSWORD command to change it once you are online.");
      mob.tell("You will receive an email with your new password shortly.  Goodbye.");
      if (mob.session() != null) {
        try {
          Thread.sleep(1000);
        } catch (Exception e) {
        }
        mob.session().kill(false, false, false);
      }
    }
    return true;
  }
예제 #15
0
 public double castingTime(final MOB mob, final List<String> cmds) {
   return CMProps.getActionSkillCost(
       ID(), CMath.div(CMProps.getIntVar(CMProps.Int.DEFABLETIME), 20.0));
 }
예제 #16
0
 @Override
 public int getMaxStat(int abilityCode) {
   final int baseMax = CMProps.getIntVar(CMProps.Int.BASEMAXSTAT);
   return baseMax + getStat(CharStats.CODES.toMAXBASE(abilityCode));
 }
예제 #17
0
  public boolean invoke(
      MOB mob, Vector commands, Environmental givenTarget, boolean auto, int asLevel) {
    if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false;

    Room target = mob.location();
    if ((auto) && (givenTarget != null) && (givenTarget instanceof Room))
      target = (Room) givenTarget;
    Ability A = target.fetchEffect(ID());
    if (A != null) {
      mob.tell("This place is already a safehouse.");
      return false;
    }
    if ((!auto) && (CMLib.law().getLegalBehavior(target) == null)) {
      mob.tell("There is no law here!");
      return false;
    }
    if (!isGoodSafehouse(target)) {
      TrackingLibrary.TrackingFlags flags;
      flags =
          new TrackingLibrary.TrackingFlags()
              .add(TrackingLibrary.TrackingFlag.OPENONLY)
              .add(TrackingLibrary.TrackingFlag.AREAONLY)
              .add(TrackingLibrary.TrackingFlag.NOEMPTYGRIDS)
              .add(TrackingLibrary.TrackingFlag.NOAIR)
              .add(TrackingLibrary.TrackingFlag.NOWATER);
      Vector V = CMLib.tracking().getRadiantRooms(target, flags, 50 + (2 * getXLEVELLevel(mob)));
      Room R = null;
      int v = 0;
      for (; v < V.size(); v++) {
        R = (Room) V.elementAt(v);
        if ((isGoodSafehouse(R)) && (!isLawHere(R))) break;
      }
      mob.tell("A place like this can't be a safehouse.");
      if ((isGoodSafehouse(R)) && (!isLawHere(R))) {
        V =
            CMLib.tracking()
                .findBastardTheBestWay(
                    target, CMParms.makeVector(R), flags, 50 + (2 * getXLEVELLevel(mob)));
        StringBuffer trail = new StringBuffer("");
        int dir = CMLib.tracking().trackNextDirectionFromHere(V, target, true);
        while (target != R) {
          if ((dir < 0) || (dir >= Directions.NUM_DIRECTIONS()) || (target == null)) break;
          trail.append(Directions.getDirectionName(dir));
          if (target.getRoomInDir(dir) != R) trail.append(", ");
          target = target.getRoomInDir(dir);
          dir = CMLib.tracking().trackNextDirectionFromHere(V, target, true);
        }
        if (target == R)
          mob.tell("You happen to know of one nearby though.  Go: " + trail.toString());
      }
      return false;
    }

    boolean success = proficiencyCheck(mob, 0, auto);

    CMMsg msg =
        CMClass.getMsg(
            mob,
            null,
            this,
            auto ? CMMsg.MASK_ALWAYS : CMMsg.MSG_DELICATE_HANDS_ACT,
            CMMsg.MSG_OK_VISUAL,
            CMMsg.MSG_OK_VISUAL,
            auto ? "" : "<S-NAME> hide(s) out from the law here.");
    if (!success)
      return beneficialVisualFizzle(
          mob,
          null,
          auto
              ? ""
              : "<S-NAME> attempt(s) hide out from the law here, but things are just too hot.");
    else if (mob.location().okMessage(mob, msg)) {
      mob.location().send(mob, msg);
      beneficialAffect(mob, target, asLevel, (CMProps.getIntVar(CMProps.SYSTEMI_TICKSPERMUDMONTH)));
    }
    return success;
  }