@Override
 public String genderName() {
   if (genderName != null) return genderName;
   switch (getStat(STAT_GENDER)) {
     case 'M':
       return CMLib.lang().L("male");
     case 'F':
       return CMLib.lang().L("female");
     default:
       return CMLib.lang().L("neuter");
   }
 }
 @Override
 public String HeShe() {
   final char c =
       ((genderName != null) && (genderName.length() > 0))
           ? Character.toUpperCase(genderName.charAt(0))
           : (char) getStat(STAT_GENDER);
   switch (c) {
     case 'M':
       return CMLib.lang().L("He");
     case 'F':
       return CMLib.lang().L("She");
     default:
       return CMLib.lang().L("It");
   }
 }
Exemple #3
0
 public static void doAnimalFollowerLevelingCheck(CharClass C, Environmental host, CMMsg msg) {
   if ((msg.sourceMessage() == null)
       && (msg.sourceMinor() == CMMsg.TYP_LEVEL)
       && (msg.source().isMonster())) {
     final MOB druidM = msg.source().amUltimatelyFollowing();
     if ((druidM != null)
         && (!druidM.isMonster())
         && (druidM.charStats().getCurrentClass().ID().equals(C.ID()))
         && (CMLib.flags().isAnimalIntelligence(msg.source())
             || msg.source()
                 .charStats()
                 .getMyRace()
                 .racialCategory()
                 .equalsIgnoreCase("Vegetation")
             || msg.source()
                 .charStats()
                 .getMyRace()
                 .racialCategory()
                 .equalsIgnoreCase("Stone Golem"))) {
       final int xp = msg.source().phyStats().level() * 5;
       if (xp > 0) {
         druidM.tell(
             CMLib.lang().L("Your stewardship has benefitted @x1.", msg.source().name(druidM)));
         CMLib.leveler().postExperience(druidM, null, null, xp, false);
       }
     }
   }
 }
Exemple #4
0
public class Inebriation extends Poison_Alcohol {
  @Override
  public String ID() {
    return "Inebriation";
  }

  private static final String localizedName = CMLib.lang().L("Inebriation");

  @Override
  public String name() {
    return localizedName;
  }

  private static final String[] triggerStrings = I(new String[] {"INEBRIATE"});

  @Override
  public String[] triggerStrings() {
    return triggerStrings;
  }

  @Override
  protected int alchoholContribution() {
    return 6;
  }
}
/*
   Copyright 2003-2016 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Play_Carol extends Play {
  @Override
  public String ID() {
    return "Play_Carol";
  }

  private static final String localizedName = CMLib.lang().L("Carol");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_BENEFICIAL_OTHERS;
  }

  @Override
  protected String songOf() {
    return CMLib.english().startWithAorAn(name());
  }

  @Override
  public void affectCharStats(MOB mob, CharStats stats) {
    super.affectCharStats(mob, stats);
    if (invoker() != null)
      stats.setStat(
          CharStats.STAT_SAVE_MIND,
          stats.getStat(CharStats.STAT_SAVE_MIND)
              + (adjustedLevel(invoker(), 0) * 2)
              + invoker().charStats().getStat(CharStats.STAT_CHARISMA));
  }
}
Exemple #6
0
/*
   Copyright 2004-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Play_Flutes extends Play_Instrument {
  @Override
  public String ID() {
    return "Play_Flutes";
  }

  private static final String localizedName = CMLib.lang().L("Flutes");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  protected int requiredInstrumentType() {
    return MusicalInstrument.TYPE_FLUTES;
  }

  @Override
  public String mimicSpell() {
    return "Chant_CharmAnimal";
  }

  private static Ability theSpell = null;

  @Override
  protected Ability getSpell() {
    if (theSpell != null) return theSpell;
    if (mimicSpell().length() == 0) return null;
    theSpell = CMClass.getAbility(mimicSpell());
    return theSpell;
  }
}
/*
  Copyright 2003-2016 Bo Zimmerman

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
public class Play_Trombones extends Play_Instrument {
  @Override
  public String ID() {
    return "Play_Trombones";
  }

  private static final String localizedName = CMLib.lang().L("Trombones");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  protected InstrumentType requiredInstrumentType() {
    return InstrumentType.TROMBONES;
  }

  @Override
  public String mimicSpell() {
    return "Spell_Frenzy";
  }

  private static Ability theSpell = null;

  @Override
  protected Ability getSpell() {
    if (theSpell != null) return theSpell;
    if (mimicSpell().length() == 0) return null;
    theSpell = CMClass.getAbility(mimicSpell());
    return theSpell;
  }
}
/*
   Copyright 2003-2016 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Trap_OpenGas extends Trap_Open {
  @Override
  public String ID() {
    return "Trap_OpenGas";
  }

  private static final String localizedName = CMLib.lang().L("Open Gas Trap");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  protected int canAffectCode() {
    return Ability.CAN_EXITS | Ability.CAN_ITEMS;
  }

  @Override
  protected int canTargetCode() {
    return 0;
  }

  @Override
  protected int trapType() {
    return TRAP_GAS;
  }
}
Exemple #9
0
 public static void waveIfAble(MOB mob, Physical afftarget, String message, Wand me) {
   if ((mob.isMine(me)) && (message != null) && (!me.amWearingAt(Wearable.IN_INVENTORY))) {
     Physical target = null;
     if (mob.location() != null) target = afftarget;
     final int x = message.toUpperCase().indexOf(me.magicWord().toUpperCase());
     if (x >= 0) {
       message = message.substring(x + me.magicWord().length());
       final int y = message.indexOf('\'');
       if (y >= 0) message = message.substring(0, y);
       message = message.trim();
       final Ability wandUse = mob.fetchAbility("Skill_WandUse");
       if ((wandUse == null) || (!wandUse.proficiencyCheck(null, 0, false)))
         mob.tell(CMLib.lang().L("@x1 glows faintly for a moment, then fades.", me.name()));
       else {
         Ability A = me.getSpell();
         if (A == null) mob.tell(CMLib.lang().L("Something seems wrong with @x1.", me.name()));
         else if (me.usesRemaining() <= 0) mob.tell(CMLib.lang().L("@x1 seems spent.", me.name()));
         else {
           wandUse.setInvoker(mob);
           A = (Ability) A.newInstance();
           if (useTheWand(A, mob, wandUse.abilityCode())) {
             final Vector V = new Vector();
             if (target != null) V.addElement(target.name());
             V.addAll(CMParms.parse(message));
             mob.location()
                 .show(
                     mob,
                     null,
                     CMMsg.MSG_OK_VISUAL,
                     CMLib.lang().L("@x1 glows brightly.", me.name()));
             me.setUsesRemaining(me.usesRemaining() - 1);
             int level = me.phyStats().level();
             final int lowest = CMLib.ableMapper().lowestQualifyingLevel(A.ID());
             if (level < lowest) level = lowest;
             A.invoke(mob, V, target, true, level);
             wandUse.helpProficiency(mob, 0);
             return;
           }
         }
       }
     }
   }
 }
Exemple #10
0
/*
   Copyright 2005-2015 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Baking extends Cooking {
  @Override
  public String ID() {
    return "Baking";
  }

  private static final String localizedName = CMLib.lang().L("Baking");

  @Override
  public String name() {
    return localizedName;
  }

  private static final String[] triggerStrings = I(new String[] {"BAKING", "BAKE"});

  @Override
  public String supportedResourceString() {
    return "MISC";
  }

  @Override
  public String[] triggerStrings() {
    return triggerStrings;
  }

  @Override
  public String cookWordShort() {
    return "bake";
  }

  @Override
  public String cookWord() {
    return "baking";
  }

  @Override
  public boolean honorHerbs() {
    return false;
  }

  @Override
  public boolean requireLid() {
    return true;
  }

  @Override
  public String parametersFile() {
    return "bake.txt";
  }

  @Override
  protected List<List<String>> loadRecipes() {
    return super.loadRecipes(parametersFile());
  }
}
 public static void colorForSale(Room R, boolean rental, boolean reset) {
   synchronized (("SYNC" + R.roomID()).intern()) {
     R = CMLib.map().getRoom(R);
     final String theStr = rental ? RENTSTR : SALESTR;
     final String otherStr = rental ? SALESTR : RENTSTR;
     int x = R.description().indexOf(otherStr);
     while (x >= 0) {
       R.setDescription(R.description().substring(0, x));
       CMLib.database().DBUpdateRoom(R);
       x = R.description().indexOf(otherStr);
     }
     final String oldDescription = R.description();
     x = R.description().indexOf(theStr.trim());
     if ((x < 0)
         || (reset
             && (!R.displayText()
                 .equals(CMath.bset(R.domainType(), Room.INDOORS) ? INDOORSTR : OUTDOORSTR)))) {
       if (reset) {
         R.setDescription("");
         R.setDisplayText(CMath.bset(R.domainType(), Room.INDOORS) ? INDOORSTR : OUTDOORSTR);
         x = -1;
       }
       if (x < 0) R.setDescription(R.description() + theStr);
       else if (!reset) R.setDescription(R.description().substring(0, x + theStr.trim().length()));
       if (!R.description().equals(oldDescription)) CMLib.database().DBUpdateRoom(R);
     } else {
       R.setDescription(R.description().substring(0, x + theStr.trim().length()));
       if (!R.description().equals(oldDescription)) CMLib.database().DBUpdateRoom(R);
     }
     Item I = R.findItem(null, "$id$");
     if ((I == null) || (!I.ID().equals("GenWallpaper"))) {
       I = CMClass.getItem("GenWallpaper");
       CMLib.flags().setReadable(I, true);
       I.setName(("id"));
       I.setReadableText(CMLib.lang().L("This room is " + CMLib.map().getExtendedRoomID(R)));
       I.setDescription(CMLib.lang().L("This room is @x1", CMLib.map().getExtendedRoomID(R)));
       R.addItem(I);
       CMLib.database().DBUpdateItems(R);
     }
   }
 }
Exemple #12
0
/*
   Copyright 2004-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Ranger_Enemy4 extends Ranger_Enemy1 {
  @Override
  public String ID() {
    return "Ranger_Enemy4";
  }

  private static final String localizedName = CMLib.lang().L("Favored Enemy 4");

  @Override
  public String name() {
    return localizedName;
  }
}
Exemple #13
0
 public static void doAnimalFreeingCheck(CharClass C, Environmental host, CMMsg msg) {
   if ((msg.source() != host)
       && (msg.sourceMinor() == CMMsg.TYP_NOFOLLOW)
       && (msg.source().isMonster())
       && (host instanceof MOB)
       && (!((MOB) host).isMonster())
       && (msg.target() == host)
       && (msg.source().getStartRoom() != null)
       && (CMLib.law().isACity(msg.source().getStartRoom().getArea()))
       && (((MOB) host).charStats().getCurrentClass().ID().equals(C.ID()))
       && (CMLib.flags().isAnimalIntelligence(msg.source())
           || msg.source().charStats().getMyRace().racialCategory().equalsIgnoreCase("Vegetation")
           || msg.source()
               .charStats()
               .getMyRace()
               .racialCategory()
               .equalsIgnoreCase("Stone Golem"))
       && (CMLib.flags().flaggedAffects(msg.source(), Ability.FLAG_SUMMONING).size() == 0)
       && (msg.source().location() != null)
       && (!msg.source().amDestroyed())
       && (CMLib.flags().isInTheGame((MOB) host, true))
       && (!CMLib.law().isACity(msg.source().location().getArea()))) {
     Object[] stuff = (Object[]) animalChecking.get(host);
     final Room room = msg.source().location();
     if ((stuff == null)
         || (System.currentTimeMillis() - ((Long) stuff[0]).longValue()
             > (room.getArea().getTimeObj().getDaysInMonth()
                 * room.getArea().getTimeObj().getHoursInDay()
                 * CMProps.getMillisPerMudHour()))) {
       stuff = new Object[3];
       stuff[0] = Long.valueOf(System.currentTimeMillis());
       animalChecking.remove(host);
       animalChecking.put(host, stuff);
       stuff[1] = Integer.valueOf(0);
       stuff[2] = new Vector();
     }
     if ((((Integer) stuff[1]).intValue() < 19)
         && (!((List) stuff[2]).contains("" + msg.source()))) {
       stuff[1] = Integer.valueOf(((Integer) stuff[1]).intValue() + 1);
       ((MOB) host)
           .tell(
               CMLib.lang()
                   .L(
                       "You have freed @x1 from @x2.",
                       msg.source().name((MOB) host),
                       (msg.source().getStartRoom().getArea().name())));
       CMLib.leveler()
           .postExperience((MOB) host, null, null, ((Integer) stuff[1]).intValue(), false);
     }
   }
 }
Exemple #14
0
/*
   Copyright 2003-2015 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Transmuter extends SpecialistMage {
  @Override
  public String ID() {
    return "Transmuter";
  }

  private static final String localizedStaticName = CMLib.lang().L("Transmuter");

  @Override
  public String name() {
    return localizedStaticName;
  }

  @Override
  public int domain() {
    return Ability.DOMAIN_TRANSMUTATION;
  }

  @Override
  public int opposed() {
    return Ability.DOMAIN_CONJURATION;
  }

  @Override
  public int availabilityCode() {
    return Area.THEME_FANTASY;
  }

  @Override
  public void initializeClass() {
    super.initializeClass();
    CMLib.ableMapper().delCharAbilityMapping(ID(), "Spell_MagicMissile");

    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Spell_DeadenSmell", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 3, "Spell_CauseStink", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 5, "Spell_ShrinkMouth", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 7, "Spell_LightSensitivity", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 8, "Skill_Spellcraft", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 9, "Spell_MassWaterbreath", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 11, "Spell_Misstep", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 13, "Spell_Sonar", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "Spell_Grow", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 17, "Spell_LedFoot", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 19, "Spell_Toadstool", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 20, "Spell_AddLimb", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Spell_PolymorphSelf", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Spell_BigMouth", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 25, "Spell_Transformation", 25, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 30, "Spell_Clone", 25, true);
  }
}
/*
   Copyright 2004-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Play_Accompaniment extends Play {
  @Override
  public String ID() {
    return "Play_Accompaniment";
  }

  private static final String localizedName = CMLib.lang().L("Accompaniment");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_BENEFICIAL_OTHERS;
  }

  @Override
  public void affectPhyStats(Physical E, PhyStats stats) {
    super.affectPhyStats(E, stats);
    if ((E instanceof MOB)
        && (E != invoker())
        && (((MOB) E).charStats().getCurrentClass().baseClass().equals("Bard"))) {
      int lvl = adjustedLevel(invoker(), 0) / 10;
      if (lvl < 1) lvl = 1;
      stats.setLevel(stats.level() + lvl);
    }
  }

  @Override
  public void affectCharStats(MOB E, CharStats stats) {
    super.affectCharStats(E, stats);
    if ((E != null) && (E != invoker()) && (stats.getCurrentClass().baseClass().equals("Bard"))) {
      int lvl = adjustedLevel(invoker(), 0) / 10;
      if (lvl < 1) lvl = 1;
      stats.setClassLevel(stats.getCurrentClass(), stats.getCurrentClassLevel() + lvl);
    }
  }

  @Override
  public int castingQuality(MOB mob, Physical target) {
    if (mob != null) {
      if (mob.getGroupMembers(new HashSet<MOB>()).size() < 2) return Ability.QUALITY_INDIFFERENT;
    }
    return super.castingQuality(mob, target);
  }
}
Exemple #16
0
 public static boolean useTheWand(Ability A, MOB mob, int level) {
   int manaRequired = 5;
   final int q = CMLib.ableMapper().qualifyingLevel(mob, A);
   if (q > 0) {
     if (q < CMLib.ableMapper().qualifyingClassLevel(mob, A)) manaRequired = 0;
     else manaRequired = 5;
   } else manaRequired = 25;
   manaRequired -= (2 * level);
   if (manaRequired < 5) manaRequired = 5;
   if (manaRequired > mob.curState().getMana()) {
     mob.tell(CMLib.lang().L("You don't have enough mana."));
     return false;
   }
   mob.curState().adjMana(-manaRequired, mob.maxState());
   return true;
 }
 protected static boolean reportError(
     final Electronics me,
     final Software controlI,
     final MOB mob,
     final String literalMessage,
     final String controlMessage) {
   if ((mob != null)
       && (mob.location() == CMLib.map().roomLocation(me))
       && (literalMessage != null)) mob.tell(literalMessage);
   if (controlMessage != null) {
     if (controlI != null) controlI.addScreenMessage(controlMessage);
     else if ((mob != null) && (me != null))
       mob.tell(CMLib.lang().L("A panel on @x1 reports '@x2'.", me.name(mob), controlMessage));
   }
   return false;
 }
/*
   Copyright 2016-2016 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Proficiency_Axe extends Proficiency_Weapon {
  @Override
  public String ID() {
    return "Proficiency_Axe";
  }

  private static final String localizedName = CMLib.lang().L("Axe Proficiency");

  @Override
  public String name() {
    return localizedName;
  }

  public Proficiency_Axe() {
    super();
    weaponClass = Weapon.CLASS_AXE;
  }
}
Exemple #19
0
/*
   Copyright 2003-2016 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Hobbit extends Halfling {
  @Override
  public String ID() {
    return "Hobbit";
  }

  private static final String localizedStaticName = CMLib.lang().L("Hobbit");

  @Override
  public String name() {
    return localizedStaticName;
  }

  @Override
  public int availabilityCode() {
    return Area.THEME_FANTASY | Area.THEME_SKILLONLYMASK;
  }
}
Exemple #20
0
public class BigCatSpeak extends AnimalSpeak {
  @Override
  public String ID() {
    return "BigCatSpeak";
  }

  private static final String localizedName = CMLib.lang().L("BigCat Speak");

  @Override
  public String name() {
    return localizedName;
  }

  private static final String[] animalSounds = {"growl", "roar", "snarl"};

  protected String[] getSounds() {
    return animalSounds;
  }
}
public class Fighter_SwampTactics extends Fighter_FieldTactics {
  @Override
  public String ID() {
    return "Fighter_SwampTactics";
  }

  private static final String localizedName = CMLib.lang().L("Swamp Tactics");

  @Override
  public String name() {
    return localizedName;
  }

  private static final Integer[] landClasses = {Integer.valueOf(Room.DOMAIN_OUTDOORS_SWAMP)};

  @Override
  public Integer[] landClasses() {
    return landClasses;
  }
}
Exemple #22
0
public class PigSpeak extends AnimalSpeak {
  @Override
  public String ID() {
    return "PigSpeak";
  }

  private static final String localizedName = CMLib.lang().L("Pig Speak");

  @Override
  public String name() {
    return localizedName;
  }

  private static final String[] animalSounds = {
    "snort", "grunt", "squeal", "oink", "oink", "oink", "oink", "oink", "oink"
  };

  @Override
  protected String[] getSounds() {
    return animalSounds;
  }
}
/*
   Copyright 2013-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Trap_SnakeThruPit extends Trap_SnakePit {
  @Override
  public String ID() {
    return "Trap_SnakeThruPit";
  }

  private static final String localizedName = CMLib.lang().L("small snake pit");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  protected int trapLevel() {
    return 9;
  }

  @Override
  public boolean getTravelThroughFlag() {
    return true;
  }
}
public class Prayer_DailyBread extends Prayer {
  @Override
  public String ID() {
    return "Prayer_DailyBread";
  }

  private static final String localizedName = CMLib.lang().L("Daily Bread");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_PRAYER | Ability.DOMAIN_EVANGELISM;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_OK_OTHERS;
  }

  @Override
  public long flags() {
    return Ability.FLAG_UNHOLY;
  }

  @Override
  protected int canAffectCode() {
    return 0;
  }

  @Override
  protected int canTargetCode() {
    return Ability.CAN_MOBS;
  }

  @Override
  protected int overrideMana() {
    return 100;
  }

  @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 (!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);
    Item Bread = null;
    Item BreadContainer = null;
    for (int i = 0; i < target.numItems(); i++) {
      final Item I = target.getItem(i);
      if ((I != null) && (I instanceof Food)) {
        if (I.container() != null) {
          Bread = I;
          BreadContainer = I.container();
        } else {
          Bread = I;
          BreadContainer = null;
          break;
        }
      }
    }
    if ((Bread != null) && (BreadContainer != null))
      CMLib.commands().postGet(target, BreadContainer, Bread, false);
    if (Bread == null) {
      final ShopKeeper SK = CMLib.coffeeShops().getShopKeeper(target);
      if (SK != null) {
        for (final Iterator<Environmental> i = SK.getShop().getStoreInventory(); i.hasNext(); ) {
          final Environmental E2 = i.next();
          if ((E2 != null) && (E2 instanceof Food)) {
            Bread = (Item) E2.copyOf();
            target.addItem(Bread);
            break;
          }
        }
      }
    }
    if ((success) && (Bread != null)) {
      CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              this,
              verbalCastCode(mob, target, auto),
              L(
                  "^S<S-NAME> @x1 for <T-NAMESELF> to provide <S-HIS-HER> daily bread!^?",
                  prayWord(mob)));
      final CMMsg msg2 =
          CMClass.getMsg(
              mob,
              target,
              this,
              CMMsg.MSK_CAST_MALICIOUS_VERBAL | CMMsg.TYP_MIND | (auto ? CMMsg.MASK_ALWAYS : 0),
              null);
      if ((mob.location().okMessage(mob, msg)) && (mob.location().okMessage(mob, msg2))) {
        mob.location().send(mob, msg);
        mob.location().send(mob, msg2);
        if ((msg.value() <= 0) && (msg2.value() <= 0)) {
          msg =
              CMClass.getMsg(
                  target,
                  mob,
                  Bread,
                  CMMsg.MSG_GIVE,
                  L("<S-NAME> gladly donate(s) <O-NAME> to <T-NAMESELF>."));
          if (mob.location().okMessage(mob, msg)) mob.location().send(mob, msg);
        }
      }
    } else
      maliciousFizzle(
          mob,
          target,
          auto
              ? ""
              : L(
                  "<S-NAME> @x1 for <T-NAMESELF> to provide <S-HIS-HER> daily bread, but nothing happens.",
                  prayWord(mob)));

    // return whether it worked
    return success;
  }
}
/*
   Copyright 2001-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
@SuppressWarnings("rawtypes")
public class Spell_ClarifyScroll extends Spell {
  @Override
  public String ID() {
    return "Spell_ClarifyScroll";
  }

  private static final String localizedName = CMLib.lang().L("Clarify Scroll");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public int overrideMana() {
    return 50;
  }

  @Override
  protected int canTargetCode() {
    return CAN_ITEMS;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_SPELL | Ability.DOMAIN_ENCHANTMENT;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_INDIFFERENT;
  }

  @Override
  public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel) {
    final Item target = getTarget(mob, null, givenTarget, commands, Wearable.FILTER_ANY);
    if (target == null) return false;

    if (!(target instanceof Scroll)) {
      mob.tell(L("You can't clarify that."));
      return false;
    }

    if (((Scroll) target).usesRemaining() > ((Scroll) target).getSpells().size()) {
      mob.tell(L("That scroll can not be enhanced any further."));
      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,
              somanticCastCode(mob, target, auto),
              auto
                  ? ""
                  : L(
                      "^S<S-NAME> wave(s) <S-HIS-HER> fingers at <T-NAMESELF>, uttering a magical phrase.^?"));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        mob.location()
            .show(
                mob, target, CMMsg.MSG_OK_VISUAL, L("The words on <T-NAME> become more definite!"));
        ((Scroll) target).setUsesRemaining(((Scroll) target).usesRemaining() + 1);
      }

    } else
      beneficialVisualFizzle(
          mob,
          target,
          L(
              "<S-NAME> wave(s) <S-HIS-HER> fingers at <T-NAMESELF>, uttering a magical phrase, and looking very frustrated."));

    // return whether it worked
    return success;
  }
}
public class Chant_Crossbreed extends Chant {
  @Override
  public String ID() {
    return "Chant_Crossbreed";
  }

  private static final String localizedName = CMLib.lang().L("Crossbreed");

  @Override
  public String name() {
    return localizedName;
  }

  private static final String localizedStaticDisplay = CMLib.lang().L("(Crossbreed)");

  @Override
  public String displayText() {
    return localizedStaticDisplay;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_CHANT | Ability.DOMAIN_BREEDING;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_OK_OTHERS;
  }

  @Override
  public void unInvoke() {
    // undo the affects of this spell
    if (!(affected instanceof MOB)) return;
    final MOB mob = (MOB) affected;

    super.unInvoke();

    if (canBeUninvoked()) mob.tell(L("Your strange cross-fertility subsides."));
  }

  @Override
  public void executeMsg(final Environmental myHost, final CMMsg msg) {
    super.executeMsg(myHost, msg);
    // the sex rules
    if (!(affected instanceof MOB)) return;

    final MOB myChar = (MOB) affected;
    if (msg.target() instanceof MOB) {
      final MOB mate = (MOB) msg.target();
      if ((msg.amISource(myChar))
          && (msg.tool() instanceof Social)
          && (msg.tool().Name().equals("MATE <T-NAME>") || msg.tool().Name().equals("SEX <T-NAME>"))
          && (msg.sourceMinor() != CMMsg.TYP_CHANNEL)
          && (myChar.charStats().getStat(CharStats.STAT_GENDER)
              != mate.charStats().getStat(CharStats.STAT_GENDER))
          && ((mate.charStats().getStat(CharStats.STAT_GENDER) == ('M'))
              || (mate.charStats().getStat(CharStats.STAT_GENDER) == ('F')))
          && ((myChar.charStats().getStat(CharStats.STAT_GENDER) == ('M'))
              || (myChar.charStats().getStat(CharStats.STAT_GENDER) == ('F')))
          && (!mate.charStats().getMyRace().canBreedWith(myChar.charStats().getMyRace()))
          && (myChar.location() == mate.location())
          && (myChar
                  .fetchWornItems(
                      Wearable.WORN_LEGS | Wearable.WORN_WAIST, (short) -2048, (short) 0)
                  .size()
              == 0)
          && (mate.fetchWornItems(
                      Wearable.WORN_LEGS | Wearable.WORN_WAIST, (short) -2048, (short) 0)
                  .size()
              == 0)
          && ((mate.charStats().getStat(CharStats.STAT_AGE) == 0)
              || ((mate.charStats().ageCategory() > Race.AGE_CHILD)
                  && (mate.charStats().ageCategory() < Race.AGE_OLD)))
          && ((myChar.charStats().getStat(CharStats.STAT_AGE) == 0)
              || ((myChar.charStats().ageCategory() > Race.AGE_CHILD)
                  && (myChar.charStats().ageCategory() < Race.AGE_OLD)))) {
        MOB female = myChar;
        MOB male = mate;
        if ((mate.charStats().getStat(CharStats.STAT_GENDER) == ('F'))) {
          female = mate;
          male = myChar;
        }
        final Ability A = CMClass.getAbility("Pregnancy");
        if ((A != null)
            && (female.fetchAbility(A.ID()) == null)
            && (female.fetchEffect(A.ID()) == null)) {
          A.invoke(male, female, true, 0);
          unInvoke();
        }
      }
    }
  }

  @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 (!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("^S<S-NAME> chant(s) to <T-NAMESELF>.^?"));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        mob.location()
            .show(target, null, CMMsg.MSG_OK_VISUAL, L("<S-NAME> seem(s) strangely fertile!"));
        beneficialAffect(mob, target, asLevel, Ability.TICKS_ALMOST_FOREVER);
      }
    } else
      return beneficialWordsFizzle(
          mob, target, L("<S-NAME> chant(s) to <T-NAMESELF>, but the magic fades."));

    // return whether it worked
    return success;
  }
}
public class Prayer_LowerLaw extends Prayer {
  @Override
  public String ID() {
    return "Prayer_LowerLaw";
  }

  private static final String localizedName = CMLib.lang().L("Lower Law");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public String displayText() {
    return "";
  }

  @Override
  protected int canTargetCode() {
    return 0;
  }

  @Override
  public long flags() {
    return Ability.FLAG_HOLY;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_INDIFFERENT;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_PRAYER | Ability.DOMAIN_COMMUNING;
  }

  public void possiblyAddLaw(Law L, Vector<String> V, String code) {
    if (L.basicCrimes().containsKey(code)) {
      final String name = L.basicCrimes().get(code)[Law.BIT_CRIMENAME];
      if (!V.contains(name)) V.add(name);
    }
  }

  @Override
  public boolean invoke(
      MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) {
    if (!super.invoke(mob, commands, givenTarget, auto, asLevel)) 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,
              null,
              this,
              verbalCastCode(mob, null, auto),
              auto
                  ? ""
                  : L("^S<S-NAME> @x1 for knowledge of the lower law here.^?", prayWord(mob)));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        final Area O = CMLib.law().getLegalObject(mob.location());
        final LegalBehavior B = CMLib.law().getLegalBehavior(mob.location());
        if ((B == null) || (O == null)) mob.tell(L("No lower law is established here."));
        else {
          final Law L = B.legalInfo(O);
          final Vector<String> crimes = new Vector<String>();
          possiblyAddLaw(L, crimes, "TRESPASSING");
          possiblyAddLaw(L, crimes, "ASSAULT");
          possiblyAddLaw(L, crimes, "MURDER");
          possiblyAddLaw(L, crimes, "NUDITY");
          possiblyAddLaw(L, crimes, "ARMED");
          possiblyAddLaw(L, crimes, "RESISTINGARREST");
          possiblyAddLaw(L, crimes, "PROPERTYROB");
          for (final String key : L.abilityCrimes().keySet())
            if (key.startsWith("$")) crimes.add(key.substring(1));
          if (L.taxLaws().containsKey("TAXEVASION"))
            crimes.add(((String[]) L.taxLaws().get("TAXEVASION"))[Law.BIT_CRIMENAME]);
          for (int x = 0; x < L.bannedSubstances().size(); x++) {
            final String name = L.bannedBits().get(x)[Law.BIT_CRIMENAME];
            if (!crimes.contains(name)) crimes.add(name);
          }
          for (int x = 0; x < L.otherCrimes().size(); x++) {
            final String name = L.otherBits().get(x)[Law.BIT_CRIMENAME];
            if (!crimes.contains(name)) crimes.add(name);
          }
          mob.tell(
              L(
                  "The following lower crimes are divinely revealed to you: @x1.",
                  CMLib.english().toEnglishStringList(crimes.toArray(new String[0]))));
        }
      }
    } else
      beneficialWordsFizzle(mob, null, L("<S-NAME> @x1, but nothing is revealed.", prayWord(mob)));

    return success;
  }
}
Exemple #28
0
/*
   Copyright 2002-2014 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class Druid extends StdCharClass {
  @Override
  public String ID() {
    return "Druid";
  }

  private static final String localizedStaticName = CMLib.lang().L("Druid");

  @Override
  public String name() {
    return localizedStaticName;
  }

  @Override
  public String baseClass() {
    return ID();
  }

  @Override
  public int getBonusPracLevel() {
    return 2;
  }

  @Override
  public int getBonusAttackLevel() {
    return 0;
  }

  @Override
  public int getAttackAttribute() {
    return CharStats.STAT_CONSTITUTION;
  }

  @Override
  public int getLevelsPerBonusDamage() {
    return 30;
  }

  @Override
  public String getHitPointsFormula() {
    return "((@x6<@x7)/2)+(2*(1?7))";
  }

  @Override
  public String getManaFormula() {
    return "((@x4<@x5)/4)+(1*(1?4))";
  }

  @Override
  protected String armorFailMessage() {
    return "<S-NAME> watch(es) <S-HIS-HER> armor absorb <S-HIS-HER> magical energy!";
  }

  @Override
  public int allowedArmorLevel() {
    return CharClass.ARMOR_NONMETAL;
  }

  @Override
  public int allowedWeaponLevel() {
    return CharClass.WEAPONS_NATURAL;
  }

  private final HashSet requiredWeaponMaterials = buildRequiredWeaponMaterials();

  @Override
  protected HashSet requiredWeaponMaterials() {
    return requiredWeaponMaterials;
  }

  @Override
  public int requiredArmorSourceMinor() {
    return CMMsg.TYP_CAST_SPELL;
  }

  public static Hashtable animalChecking = new Hashtable();

  public Druid() {
    super();
    maxStatAdj[CharStats.STAT_CONSTITUTION] = 7;
  }

  @Override
  public void initializeClass() {
    super.initializeClass();
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_Write", 0, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_Recall", 50, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_Revoke", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_WandUse", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_Swim", 100, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_Climb", 100, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Specialization_Natural", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Specialization_Staff", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Herbology", 0, false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Druidic", 75, true);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Druid_DruidicPass", true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Druid_ShapeShift", true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Druid_MyPlants", true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Chant_PredictWeather", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Chant_BestowName", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Chant_SummonPlants", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Chant_HardenSkin", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 1, "Skill_WildernessLore", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 2, "Chant_SummonWater", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 2, "Chant_LocatePlants", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 2, "Chant_SensePoison", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 3, "Chant_SummonFood", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 3, "Chant_Moonbeam", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 3, "Chant_RestoreMana", 0, "", false, true);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 3, "Chant_SenseLife", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 4, "Chant_Tangle", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 4, "Chant_SummonFire", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 4, "Chant_LocateAnimals", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 5, "Chant_FortifyFood", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 5, "Chant_Farsight", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 5, "Chant_FeelElectricity", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 6, "Chant_CalmAnimal", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 6, "Chant_Sunray", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 6, "Chant_Treeform", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 7, "Chant_Goodberry", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 7, "Chant_Hunger", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 7, "Chant_FeelCold", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 7, "Chant_NaturalBalance", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 8, "Chant_WarpWood", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 8, "Chant_ControlFire", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 8, "Chant_VenomWard", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 9, "Chant_CalmWind", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 9, "Chant_Barkskin", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 9, "Chant_WaterWalking", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 10, "Chant_AnimalFriendship", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 10, "Chant_FeelHeat", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 10, "Chant_GrowClub", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 10, "Chant_Brittle", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 11, "Chant_PlantPass", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 11, "Chant_WindGust", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 11, "Chant_Poison", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 12, "Chant_Treemind", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 12, "Chant_WhisperWard", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 12, "Chant_BreatheWater", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 13, "Chant_HoldAnimal", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 13, "Chant_PlantBed", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 13, "Chant_LightningWard", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 14, "Chant_ColdWard", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 14, "Chant_Bury", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 14, "Chant_IllusionaryForest", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 14, "Chant_Hippieness", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "Herbalism", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "Chant_Fertilization", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "Chant_CharmAnimal", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "Chant_CalmWeather", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 15, "PlantLore", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 16, "Chant_FireWard", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 16, "Chant_Shillelagh", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 16, "Chant_SummonPeace", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 17, "Chant_Plague", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 17, "Chant_DistantGrowth", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 17, "Chant_Earthquake", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 18, "Chant_PlantMaze", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 18, "Chant_GasWard", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 18, "Chant_Hibernation", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 18, "Chant_Reabsorb", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 19, "Chant_SummonAnimal", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 19, "Chant_Nectar", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 19, "Chant_SummonHeat", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 19, "Chant_SenseSentience", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 20, "Scrapping", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 20, "Chant_Grapevine", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 20, "Chant_SummonCold", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 20, "Chant_SummonInsects", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Chant_AnimalSpy", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Chant_SummonRain", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Chant_PlantSnare", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Chant_SensePregnancy", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 21, "Chant_SenseFluids", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 22, "Chant_Treemorph", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 22, "Chant_SummonWind", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 22, "Chant_NeutralizePoison", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 22, "Chant_FindPlant", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 22, "Chant_SensePlants", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Chant_GrowItem", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Chant_SummonLightning", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Chant_SummonMount", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Chant_FindOre", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 23, "Chant_SenseOres", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_CharmArea", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_SummonElemental", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_SummonFear", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_SenseAge", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_FindGem", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 24, "Chant_SenseGems", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 25, "Chant_SpeedTime", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 25, "Chant_SummonSapling", false);
    CMLib.ableMapper().addCharAbilityMapping(ID(), 25, "Chant_Feralness", false);

    CMLib.ableMapper().addCharAbilityMapping(ID(), 30, "Chant_Reincarnation", true);
  }

  @Override
  public int availabilityCode() {
    return Area.THEME_FANTASY;
  }

  @Override
  public void grantAbilities(MOB mob, boolean isBorrowedClass) {
    super.grantAbilities(mob, isBorrowedClass);

    if (mob.playerStats() == null) {
      final List<AbilityMapper.AbilityMapping> V =
          CMLib.ableMapper()
              .getUpToLevelListings(ID(), mob.charStats().getClassLevel(ID()), false, false);
      for (final AbilityMapper.AbilityMapping able : V) {
        final Ability A = CMClass.getAbility(able.abilityID);
        if ((A != null)
            && ((A.classificationCode() & Ability.ALL_ACODES) == Ability.ACODE_CHANT)
            && (!CMLib.ableMapper().getDefaultGain(ID(), true, A.ID())))
          giveMobAbility(
              mob,
              A,
              CMLib.ableMapper().getDefaultProficiency(ID(), true, A.ID()),
              CMLib.ableMapper().getDefaultParm(ID(), true, A.ID()),
              isBorrowedClass);
      }
      return;
    }

    final Vector grantable = new Vector();

    final int level = mob.charStats().getClassLevel(this);
    int numChants = 2;
    for (final Enumeration<Ability> a = CMClass.abilities(); a.hasMoreElements(); ) {
      final Ability A = a.nextElement();
      if ((CMLib.ableMapper().getQualifyingLevel(ID(), true, A.ID()) == level)
          && ((CMLib.ableMapper().getQualifyingLevel(ID(), true, A.ID()) <= 25)
              && (!CMLib.ableMapper().getSecretSkill(ID(), true, A.ID()))
              && (!CMLib.ableMapper().getDefaultGain(ID(), true, A.ID()))
              && ((A.classificationCode() & Ability.ALL_ACODES) == Ability.ACODE_CHANT))) {
        if (!grantable.contains(A.ID())) grantable.addElement(A.ID());
      }
    }
    for (int a = 0; a < mob.numAbilities(); a++) {
      final Ability A = mob.fetchAbility(a);
      if (grantable.contains(A.ID())) {
        grantable.remove(A.ID());
        numChants--;
      }
    }
    for (int i = 0; i < numChants; i++) {
      if (grantable.size() == 0) break;
      final String AID = (String) grantable.elementAt(CMLib.dice().roll(1, grantable.size(), -1));
      if (AID != null) {
        grantable.removeElement(AID);
        giveMobAbility(
            mob,
            CMClass.getAbility(AID),
            CMLib.ableMapper().getDefaultProficiency(ID(), true, AID),
            CMLib.ableMapper().getDefaultParm(ID(), true, AID),
            isBorrowedClass);
      }
    }
  }

  @Override
  public void affectCharState(MOB affected, CharState affectableState) {
    super.affectCharState(affected, affectableState);
    if (affected.location() != null)
      for (int i = 0; i < affected.location().numItems(); i++) {
        final Item I = affected.location().getItem(i);
        if ((I != null) && (I.ID().equals("DruidicMonument")))
          affectableState.setMana(affectableState.getMana() + (affectableState.getMana() / 2));
      }
  }

  private final String[] raceRequiredList =
      new String[] {
        "Human",
        "Humanoid",
        "Elf",
        "Vegetation",
        "Dwarf",
        "Giant-kin",
        "Goblinoid",
        "HalfElf",
        "Centaur"
      };

  @Override
  public String[] getRequiredRaceList() {
    return raceRequiredList;
  }

  private final Pair<String, Integer>[] minimumStatRequirements =
      new Pair[] {new Pair<String, Integer>("Constitution", Integer.valueOf(9))};

  @Override
  public Pair<String, Integer>[] getMinimumStatRequirements() {
    return minimumStatRequirements;
  }

  @Override
  public String getOtherLimitsDesc() {
    return "Must remain Neutral to avoid skill and chant failure chances.";
  }

  @Override
  public String getOtherBonusDesc() {
    return "When leading animals into battle, will not divide experience among animal followers.  Can create a druidic connection with an area.  Benefits from animal/plant/stone followers leveling.  Benefits from freeing animals from cities.  Benefits from balancing the weather.";
  }

  @Override
  public boolean okMessage(final Environmental myHost, final CMMsg msg) {
    if (!(myHost instanceof MOB)) return super.okMessage(myHost, msg);
    final MOB myChar = (MOB) myHost;
    if (!super.okMessage(myChar, msg)) return false;

    if (msg.amISource(myChar)
        && (!myChar.isMonster())
        && (msg.sourceMinor() == CMMsg.TYP_CAST_SPELL)
        && (msg.tool() instanceof Ability)
        && ((((Ability) msg.tool()).classificationCode() & Ability.ALL_ACODES)
            == Ability.ACODE_CHANT)
        && (myChar.isMine(msg.tool()))
        && (isQualifyingAuthority(myChar, (Ability) msg.tool()))
        && (CMLib.dice().rollPercentage() < 50)) {
      if (((Ability) msg.tool()).appropriateToMyFactions(myChar)) return true;
      myChar.tell(L("Extreme emotions disrupt your chant."));
      return false;
    }
    return true;
  }

  public static void doAnimalFollowerLevelingCheck(CharClass C, Environmental host, CMMsg msg) {
    if ((msg.sourceMessage() == null)
        && (msg.sourceMinor() == CMMsg.TYP_LEVEL)
        && (msg.source().isMonster())) {
      final MOB druidM = msg.source().amUltimatelyFollowing();
      if ((druidM != null)
          && (!druidM.isMonster())
          && (druidM.charStats().getCurrentClass().ID().equals(C.ID()))
          && (CMLib.flags().isAnimalIntelligence(msg.source())
              || msg.source()
                  .charStats()
                  .getMyRace()
                  .racialCategory()
                  .equalsIgnoreCase("Vegetation")
              || msg.source()
                  .charStats()
                  .getMyRace()
                  .racialCategory()
                  .equalsIgnoreCase("Stone Golem"))) {
        final int xp = msg.source().phyStats().level() * 5;
        if (xp > 0) {
          druidM.tell(
              CMLib.lang().L("Your stewardship has benefitted @x1.", msg.source().name(druidM)));
          CMLib.leveler().postExperience(druidM, null, null, xp, false);
        }
      }
    }
  }

  public static void doAnimalFreeingCheck(CharClass C, Environmental host, CMMsg msg) {
    if ((msg.source() != host)
        && (msg.sourceMinor() == CMMsg.TYP_NOFOLLOW)
        && (msg.source().isMonster())
        && (host instanceof MOB)
        && (!((MOB) host).isMonster())
        && (msg.target() == host)
        && (msg.source().getStartRoom() != null)
        && (CMLib.law().isACity(msg.source().getStartRoom().getArea()))
        && (((MOB) host).charStats().getCurrentClass().ID().equals(C.ID()))
        && (CMLib.flags().isAnimalIntelligence(msg.source())
            || msg.source().charStats().getMyRace().racialCategory().equalsIgnoreCase("Vegetation")
            || msg.source()
                .charStats()
                .getMyRace()
                .racialCategory()
                .equalsIgnoreCase("Stone Golem"))
        && (CMLib.flags().flaggedAffects(msg.source(), Ability.FLAG_SUMMONING).size() == 0)
        && (msg.source().location() != null)
        && (!msg.source().amDestroyed())
        && (CMLib.flags().isInTheGame((MOB) host, true))
        && (!CMLib.law().isACity(msg.source().location().getArea()))) {
      Object[] stuff = (Object[]) animalChecking.get(host);
      final Room room = msg.source().location();
      if ((stuff == null)
          || (System.currentTimeMillis() - ((Long) stuff[0]).longValue()
              > (room.getArea().getTimeObj().getDaysInMonth()
                  * room.getArea().getTimeObj().getHoursInDay()
                  * CMProps.getMillisPerMudHour()))) {
        stuff = new Object[3];
        stuff[0] = Long.valueOf(System.currentTimeMillis());
        animalChecking.remove(host);
        animalChecking.put(host, stuff);
        stuff[1] = Integer.valueOf(0);
        stuff[2] = new Vector();
      }
      if ((((Integer) stuff[1]).intValue() < 19)
          && (!((List) stuff[2]).contains("" + msg.source()))) {
        stuff[1] = Integer.valueOf(((Integer) stuff[1]).intValue() + 1);
        ((MOB) host)
            .tell(
                CMLib.lang()
                    .L(
                        "You have freed @x1 from @x2.",
                        msg.source().name((MOB) host),
                        (msg.source().getStartRoom().getArea().name())));
        CMLib.leveler()
            .postExperience((MOB) host, null, null, ((Integer) stuff[1]).intValue(), false);
      }
    }
  }

  @Override
  public void executeMsg(Environmental host, CMMsg msg) {
    super.executeMsg(host, msg);
    Druid.doAnimalFollowerLevelingCheck(this, host, msg);
    Druid.doAnimalFreeingCheck(this, host, msg);
  }

  @Override
  public boolean isValidClassDivider(MOB killer, MOB killed, MOB mob, Set<MOB> followers) {
    if ((mob != null)
        && (mob != killed)
        && (!mob.amDead())
        && ((!mob.isMonster()) || (!CMLib.flags().isAnimalIntelligence(mob)))
        && ((mob.getVictim() == killed) || (followers.contains(mob)) || (mob == killer)))
      return true;
    return false;
  }

  @Override
  public List<Item> outfit(MOB myChar) {
    if (outfitChoices == null) {
      outfitChoices = new Vector();
      final Weapon w = CMClass.getWeapon("Quarterstaff");
      outfitChoices.add(w);
    }
    return outfitChoices;
  }

  @Override
  public int classDurationModifier(MOB myChar, Ability skill, int duration) {
    if (myChar == null) return duration;
    if (((skill.classificationCode() & Ability.ALL_DOMAINS) == Ability.DOMAIN_CRAFTINGSKILL)
        && (myChar.charStats().getCurrentClass().ID().equals(ID()))
        && (!skill.ID().equals("FoodPrep"))
        && (!skill.ID().equals("Cooking"))
        && (!skill.ID().equals("Herbalism"))
        && (!skill.ID().equals("Weaving"))
        && (!skill.ID().equals("Masonry"))) return duration * 2;

    return duration;
  }
}
public class Spell_Refit extends Spell {
  @Override
  public String ID() {
    return "Spell_Refit";
  }

  private static final String localizedName = CMLib.lang().L("Refit");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  protected int canTargetCode() {
    return CAN_ITEMS;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_SPELL | Ability.DOMAIN_ALTERATION;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_INDIFFERENT;
  }

  @Override
  public boolean invoke(
      MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) {
    final Item target = getTarget(mob, null, givenTarget, commands, Wearable.FILTER_UNWORNONLY);
    if (target == null) return false;
    if (!(target instanceof Armor)) {
      mob.tell(L("@x1 cannot be refitted.", target.name(mob)));
      return false;
    }

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

    final boolean success =
        proficiencyCheck(
            mob,
            (((mob.phyStats().level() + (2 * getXLEVELLevel(mob))) - target.phyStats().level())
                * 5),
            auto);

    if (success) {
      final CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              this,
              verbalCastCode(mob, target, auto),
              (auto ? "<T-NAME> begins to shimmer!" : "^S<S-NAME> incant(s) at <T-NAMESELF>!^?"));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);

        if (target.phyStats().height() == 0)
          mob.tell(L("Nothing happens to @x1.", target.name(mob)));
        else {
          mob.location()
              .show(
                  mob,
                  target,
                  CMMsg.MSG_OK_VISUAL,
                  L("<T-NAME> begin(s) to magically resize itself!"));
          target.basePhyStats().setHeight(0);
        }
        target.recoverPhyStats();
        mob.location().recoverRoomStats();
      }

    } else
      beneficialWordsFizzle(
          mob, target, L("<S-NAME> incant(s) at <T-NAMESELF>, but nothing happens."));

    // return whether it worked
    return success;
  }
}
public class Prayer_Thunderbolt extends Prayer {
  @Override
  public String ID() {
    return "Prayer_Thunderbolt";
  }

  private static final String localizedName = CMLib.lang().L("Thunderbolt");

  @Override
  public String name() {
    return localizedName;
  }

  @Override
  public int classificationCode() {
    return Ability.ACODE_PRAYER | Ability.DOMAIN_CREATION;
  }

  @Override
  public int abstractQuality() {
    return Ability.QUALITY_MALICIOUS;
  }

  @Override
  public long flags() {
    return Ability.FLAG_NEUTRAL;
  }

  @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 (!super.invoke(mob, commands, givenTarget, auto, asLevel)) return false;

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

    final Room R = target.location();
    if (success) {
      final Prayer_Thunderbolt newOne = (Prayer_Thunderbolt) this.copyOf();
      final CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              newOne,
              verbalCastCode(mob, target, auto),
              L(
                      auto
                          ? "<T-NAME> is filled with a holy charge!"
                          : "^S<S-NAME> " + prayForWord(mob) + " to strike down <T-NAMESELF>!^?")
                  + CMLib.protocol().msp("lightning.wav", 40));
      final CMMsg msg2 =
          CMClass.getMsg(
              mob,
              target,
              this,
              CMMsg.MSK_CAST_MALICIOUS_VERBAL | CMMsg.TYP_ELECTRIC | (auto ? CMMsg.MASK_ALWAYS : 0),
              null);
      if ((R.okMessage(mob, msg)) && ((R.okMessage(mob, msg2)))) {
        R.send(mob, msg);
        R.send(mob, msg2);
        if ((msg.value() <= 0) && (msg2.value() <= 0)) {
          final int harming =
              CMLib.dice().roll(1, adjustedLevel(mob, asLevel), adjustedLevel(mob, asLevel));
          CMLib.combat()
              .postDamage(
                  mob,
                  target,
                  this,
                  harming,
                  CMMsg.MASK_ALWAYS | CMMsg.TYP_ELECTRIC,
                  Weapon.TYPE_STRIKING,
                  L("^SThe STRIKE of @x1 <DAMAGES> <T-NAME>!^?", hisHerDiety(mob)));
        }
      }
    } else
      return maliciousFizzle(mob, target, L("<S-NAME> @x1, but nothing happens.", prayWord(mob)));

    // return whether it worked
    return success;
  }
}