@Override
  public boolean invoke(MOB mob, Vector commands, Physical givenTarget, boolean auto, int asLevel) {
    final MOB target = getTarget(mob, commands, givenTarget);
    if (target == null) return false;
    Item myPlant = Druid_MyPlants.myPlant(mob.location(), mob, 0);
    if (myPlant == null) {
      if (auto) myPlant = new Chant_SummonPlants().buildPlant(mob, mob.location());
      else {
        mob.tell(L("There doesn't appear to be any of your plants here to choke with."));
        return false;
      }
    }

    if (target.getWearPositions(Wearable.WORN_NECK) == 0) {
      if (!auto) mob.tell(L("Ummm, @x1 doesn't HAVE a neck...", target.name(mob)));
      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) at <T-NAME> while pointing at @x1!^?", myPlant.name()));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        target.moveItemTo(myPlant);
        myPlant.setRawWornCode(Wearable.WORN_NECK);
        mob.location()
            .show(
                target,
                null,
                CMMsg.MSG_OK_VISUAL,
                L("@x1 jumps up and wraps itself around <S-YOUPOSS> neck!", myPlant.name()));
        beneficialAffect(mob, myPlant, asLevel, 5);
      }
    } else
      return maliciousFizzle(
          mob, target, L("<S-NAME> chant(s) at <T-NAME>, but the magic fizzles."));

    // return whether it worked
    return success;
  }
  @Override
  public boolean invoke(
      MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel) {
    if (commands.size() < 2) {
      if (mob.isMonster() && (commands.size() == 1)) {
        final String parm = correctItem(mob);
        if (parm != null) commands.add(parm);
      }
      if (commands.size() < 2) {
        mob.tell(L("You must specify a target, and what item to swap on the target!"));
        return false;
      }
    }
    final Item I = mob.findItem(null, commands.get(commands.size() - 1));
    if ((I == null) || (!CMLib.flags().canBeSeenBy(I, mob))) {
      mob.tell(L("You don't seem to have '@x1'.", (commands.get(commands.size() - 1))));
      return false;
    }
    if (((I instanceof Armor) && (I.basePhyStats().armor() > 1))
        || ((I instanceof Weapon) && (I.basePhyStats().damage() > 1))) {
      mob.tell(L("@x1 is not buffoonish enough!", I.name(mob)));
      return false;
    }
    commands.remove(commands.size() - 1);

    final MOB target = getTarget(mob, commands, givenTarget);
    if (target == null) return false;

    final Item targetItem = targetItem(target);
    if (targetItem == null) {
      if (!freePosition(target)) {
        mob.tell(L("@x1 has no free wearing positions!", target.name(mob)));
        return false;
      }
    }

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

    int levelDiff = target.phyStats().level() - mob.phyStats().level();

    final boolean success = proficiencyCheck(mob, 0, auto);
    if (levelDiff > 0)
      levelDiff = -(levelDiff * ((!CMLib.flags().canBeSeenBy(mob, target)) ? 5 : 15));
    else levelDiff = -(levelDiff * ((!CMLib.flags().canBeSeenBy(mob, target)) ? 1 : 2));

    if (success) {
      final CMMsg msg =
          CMClass.getMsg(
              mob,
              target,
              this,
              (CMMsg.MSG_NOISYMOVEMENT | CMMsg.MASK_DELICATE | CMMsg.MASK_MALICIOUS)
                  | (auto ? CMMsg.MASK_ALWAYS : 0),
              auto ? "" : L("<S-NAME> do(es) buffoonery to <T-NAMESELF>."));
      if (mob.location().okMessage(mob, msg)) {
        mob.location().send(mob, msg);
        long position = -1;
        if (targetItem != null) {
          position = targetItem.rawWornCode();
          targetItem.unWear();
        } else {
          final Vector<Long> free = getFreeWearingPositions(target);
          if (free.size() < 1) {
            mob.tell(L("@x1 has no free wearing positions!", target.name(mob)));
            return false;
          }
          if ((free.contains(Long.valueOf(Wearable.WORN_WIELD)))
              && ((I instanceof Weapon) || (!(I instanceof Armor)))) position = Wearable.WORN_WIELD;
          else position = free.elementAt(CMLib.dice().roll(1, free.size(), -1)).longValue();
        }
        if (position >= 0) {
          I.unWear();
          target.moveItemTo(I);
          I.wearAt(position);
        }
      }
    } else
      return beneficialVisualFizzle(
          mob, target, L("<S-NAME> attempt(s) buffoonery on <T-NAMESELF>, but fail(s)."));

    return success;
  }