public void startSpeaking(MOB mob) {
   Room mobHomeRoom = mob.getStartRoom();
   Area mobHomeArea = ((mobHomeRoom == null) ? null : mobHomeRoom.getArea());
   if (((lang != null) || (langStr.length() > 0))
       && (doPlayers || mob.isMonster())
       && ((!noMobs) || (!mob.isMonster()))
       && ((!homeOnly) || (homeRoom == null) || (mobHomeRoom == homeRoom))
       && ((!homeOnly) || (homeArea == null) || (mobHomeArea == homeArea))
       && (mob.fetchEffect(langStr) == null)
       && ((mobMask == null) || CMLib.masking().maskCheck(mobMask, mob, true))) {
     if (lang == null) lang = getLanguage();
     if (lang == null) {
       lang = (Language) CMClass.getAbility("Common");
       Log.errOut("Prop_LanguageSpeaker", "Unknown language " + langStr);
     }
     if (lang != null) {
       switch (affectedType) {
         case AREA:
           lang = (Language) lang.copyOf();
           break;
         case LOCALE:
           lang = (Language) lang.copyOf();
           break;
         case MOB:
           break;
         case EXIT:
           lang = (Language) lang.copyOf();
           break;
         default: // item
           break;
       }
       mob.addNonUninvokableEffect(lang);
       lang.setSavable(false);
       lang.invoke(mob, mob, false, 0);
     }
   }
 }
 public void executeMsg(final Environmental myHost, final CMMsg msg) {
   if (affected != null)
     switch (affectedType) {
       case AREA:
         {
           if (msg.targetMinor() == CMMsg.TYP_ENTER) startSpeaking(msg.source());
           else if (msg.sourceMinor() == CMMsg.TYP_LIFE) startSpeaking(msg.source());
           break;
         }
       case LOCALE:
         {
           if ((msg.target() == affected) && (msg.targetMinor() == CMMsg.TYP_ENTER))
             startSpeaking(msg.source());
           else if (msg.sourceMinor() == CMMsg.TYP_LIFE) startSpeaking(msg.source());
           break;
         }
       case MOB:
         {
           if (lang == null) startSpeaking((MOB) affected);
           break;
         }
       case EXIT:
         {
           if ((msg.targetMinor() == CMMsg.TYP_ENTER) && (msg.tool() == affected))
             startSpeaking(msg.source());
           break;
         }
       default: // item
         {
           if ((msg.target() == affected)
               && (msg.targetMinor() == CMMsg.TYP_GET)
               && ((lang == null) || (lang.affecting() != msg.source()))) {
             if ((lang != null) && (lang.affecting() != null)) lang.affecting().delEffect(lang);
             startSpeaking(msg.source());
           } else if ((msg.target() == affected)
               && (msg.targetMinor() == CMMsg.TYP_DROP)
               && (lang != null)
               && (lang.affecting() != null)) {
             lang.affecting().delEffect(lang);
             lang.setAffectedOne(null);
           }
           break;
         }
     }
   super.executeMsg(myHost, msg);
 }
 public String accountForYourself() {
   return "Forces speaking the language: " + ((lang != null) ? lang.name() : "?");
 }