@EventHandler
  public void mobKilled(EntityDeathEvent event) {
    if (type != ItemDropType.MOBKILL) return;
    dB.echoDebug("...checking kill");
    if (event.getEntity().getKiller() != player.getPlayerEntity()) return;
    dB.echoDebug("...killed by player");
    if (event.getEntity().getType() != mob) return;
    dB.echoDebug("...proper mob");
    if (location != null) {
      if (location.distance(player.getPlayerEntity().getLocation()) > radius) return;
    }
    dB.echoDebug("...within range");
    if (region != null) {
      if (!WorldGuardUtilities.inRegion(player.getPlayerEntity().getLocation(), region)) return;
    }
    dB.echoDebug("...within region");

    dB.echoDebug("...trying to drop item");
    if (Utilities.getRandom().nextInt(101) < dropRate) {
      dB.echoDebug("...item should drop now");
      event.getEntity().getWorld().dropItem(event.getEntity().getLocation(), item);
      qtyDropped++;
      dB.echoDebug("...item dropped");
      check();
    }
  }
Exemple #2
0
  @Override
  public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {

    // Get objects
    Action action = (Action) scriptEntry.getObject("action");
    dLocation location = (dLocation) scriptEntry.getObject("location");
    Element range = (Element) scriptEntry.getObject("range");
    Element id = (Element) scriptEntry.getObject("id");

    // Report to dB
    dB.report(
        scriptEntry,
        getName(),
        aH.debugObj("NPC", scriptEntry.getNPC().toString())
            + action.name()
            + id.debug()
            + (location != null ? location.debug() : "")
            + (range != null ? range.debug() : ""));

    dNPC npc = scriptEntry.getNPC();

    switch (action) {
      case ADD:
        npc.getCitizen().getTrait(Anchors.class).addAnchor(id.asString(), location);
        return;

      case ASSUME:
        npc.getEntity()
            .teleport(
                npc.getCitizen().getTrait(Anchors.class).getAnchor(id.asString()).getLocation());
        return;

      case WALKNEAR:
        npc.getNavigator()
            .setTarget(
                Utilities.getWalkableLocationNear(
                    npc.getCitizen().getTrait(Anchors.class).getAnchor(id.asString()).getLocation(),
                    range.asInt()));
        return;

      case WALKTO:
        npc.getNavigator()
            .setTarget(
                npc.getCitizen().getTrait(Anchors.class).getAnchor(id.asString()).getLocation());
        return;

      case REMOVE:
        npc.getCitizen()
            .getTrait(Anchors.class)
            .removeAnchor(npc.getCitizen().getTrait(Anchors.class).getAnchor(id.asString()));
    }
  }
  @EventHandler
  public void blockPlaced(BlockPlaceEvent event) {
    if (type != ItemDropType.BLOCKPLACE) return;
    dB.echoDebug("...checking blockplaceevent");
    if (event.getPlayer() != player.getPlayerEntity()) return;
    dB.echoDebug("...placed by player");
    if (event.getBlock().getType() != block) return;
    dB.echoDebug("...proper block placed");
    if (location != null) {
      if (location.distance(player.getPlayerEntity().getLocation()) > radius) return;
    }
    dB.echoDebug("...within range");
    if (region != null) {
      if (!WorldGuardUtilities.inRegion(player.getPlayerEntity().getLocation(), region)) return;
    }
    dB.echoDebug("...within region");

    if (Utilities.getRandom().nextInt(101) < dropRate) {
      event.getBlock().getWorld().dropItem(event.getBlock().getLocation(), item);
      qtyDropped++;
      dB.echoDebug("...item dropped");
      check();
    }
  }
Exemple #4
0
  // Technically defined in TriggerTrait, but placing here instead.
  // <--[action]
  // @Actions
  // chat
  //
  // @Triggers when a player chats to the NPC.
  //
  // @Context
  // <context.message> returns the triggering message
  // <context.keyword> returns the keyword matched by a RegEx trigger
  //
  // -->
  public Boolean process(Player player, String message) {

    // Check if there is an NPC within range of a player to chat to.
    dNPC npc = Utilities.getClosestNPC_ChatTrigger(player.getLocation(), 25);
    dPlayer denizenPlayer = dPlayer.mirrorBukkitPlayer(player);

    // No NPC? Nothing else to do here.
    if (npc == null) return false;

    // If the NPC doesn't have triggers, or the triggers are not enabled, then
    // just return false.
    if (!npc.getCitizen().hasTrait(TriggerTrait.class)) return false;
    if (!npc.getCitizen().getTrait(TriggerTrait.class).isEnabled(name)) return false;

    // Check range
    if (npc.getTriggerTrait().getRadius(name) < npc.getLocation().distance(player.getLocation()))
      return false;

    // The Denizen config can require some other criteria for a successful chat-with-npc.
    // Should we check 'line of sight'? Players cannot talk to NPCs through walls
    // if enabled. Should the Player chat only when looking at the NPC? This may
    // reduce accidental chats with NPCs.

    if (Settings.ChatMustSeeNPC()) if (!player.hasLineOfSight(npc.getEntity())) return false;

    if (Settings.ChatMustLookAtNPC())
      if (!Rotation.isFacingEntity(player, npc.getEntity(), 45)) return false;

    Boolean ret = false;

    // Denizen should be good to interact with. Let's get the script.
    InteractScriptContainer script = npc.getInteractScript(denizenPlayer, ChatTrigger.class);

    Map<String, dObject> context = new HashMap<String, dObject>();
    context.put("message", new Element(message));

    // If engaged or not cool, calls On Unavailable, if cool, calls On Chat
    // If available (not engaged, and cool) sets cool down and returns true.
    if (!npc.getTriggerTrait().trigger(ChatTrigger.this, denizenPlayer, context)) {
      // If the NPC is not interactable, Settings may allow the chat to filter
      // through. Check the Settings if this is enabled.
      if (Settings.ChatGloballyIfUninteractable()) {
        dB.echoDebug(
            script,
            ChatColor.YELLOW
                + "Resuming. "
                + ChatColor.WHITE
                + "The NPC is currently cooling down or engaged.");
        return false;
      } else {
        ret = true;
      }
    }

    // Debugger
    dB.report(
        script,
        name,
        aH.debugObj("Player", player.getName())
            + aH.debugObj("NPC", npc.toString())
            + aH.debugObj(
                "Radius(Max)",
                npc.getLocation().distance(player.getLocation())
                    + "("
                    + npc.getTriggerTrait().getRadius(name)
                    + ")")
            + aH.debugObj("Trigger text", message)
            + aH.debugObj("LOS", String.valueOf(player.hasLineOfSight(npc.getEntity())))
            + aH.debugObj(
                "Facing", String.valueOf(Rotation.isFacingEntity(player, npc.getEntity(), 45))));

    if (script == null) return false;

    // Check if the NPC has Chat Triggers for this step.
    if (!script.containsTriggerInStep(
        InteractScriptHelper.getCurrentStep(denizenPlayer, script.getName()), ChatTrigger.class)) {

      // If this is a Chatbot, make it chat anything it wants if
      // it has no chat triggers for this step
      if (npc.getCitizen().hasTrait(ChatbotTrait.class)) {
        Utilities.talkToNPC(message, denizenPlayer, npc, Settings.ChatToNpcOverhearingRange());
        npc.getCitizen().getTrait(ChatbotTrait.class).chatTo(player, message);
        return true;
      }
      // No chat trigger for this step.. do we chat globally, or to the NPC?
      else if (!Settings.ChatGloballyIfNoChatTriggers()) {
        dB.echoDebug(
            script,
            player.getName() + " says to " + npc.getNicknameTrait().getNickname() + ", " + message);
        return true;
      } else return ret;
    }

    // Parse the script and match Triggers.. if found, cancel the text! The
    // parser will take care of everything else.
    String id = null;
    boolean matched = false;
    String replacementText = null;
    String regexId = null;
    String regexMessage = null;

    // Use TreeMap to sort chat triggers alphabetically
    TreeMap<String, String> idMap = new TreeMap<String, String>();
    idMap.putAll(script.getIdMapFor(ChatTrigger.class, denizenPlayer));

    if (!idMap.isEmpty()) {
      // Iterate through the different id entries in the step's chat trigger
      for (Map.Entry<String, String> entry : idMap.entrySet()) {

        // Check if the chat trigger specified in the specified id's 'trigger:' key
        // matches the text the player has said
        String triggerText = TagManager.tag(denizenPlayer, npc, entry.getValue());
        Matcher matcher = triggerPattern.matcher(triggerText);
        while (matcher.find()) {
          if (!script.checkSpecificTriggerScriptRequirementsFor(
              ChatTrigger.class, denizenPlayer, npc, entry.getKey())) continue;
          String keyword = TagManager.tag(denizenPlayer, npc, matcher.group().replace("/", ""));
          // Check if the trigger is REGEX, but only if we don't have a REGEX
          // match already (thus using alphabetical priority for triggers)
          if (regexId == null && isKeywordRegex(keyword)) {
            Pattern pattern = Pattern.compile(keyword.substring(6));
            Matcher m = pattern.matcher(message);
            if (m.find()) {
              // REGEX matches are left for last, so save it in case non-REGEX
              // matches don't exist
              regexId = entry.getKey();
              regexMessage = triggerText.replace(matcher.group(), m.group());
              dB.log(
                  "entry value: "
                      + triggerText
                      + "  keyword: "
                      + keyword
                      + "  m.group: "
                      + m.group()
                      + "  matcher.group: "
                      + matcher.group());
              context.put("keyword", new Element(m.group()));
            }
          } else if (isKeywordStrict(keyword)) {
            if (message.toUpperCase().equalsIgnoreCase(keyword.toUpperCase())) {
              // Trigger matches
              id = entry.getKey();
              replacementText = triggerText.replace("/", "");
              matched = true;
            }
          } else if (message.toUpperCase().contains(keyword.toUpperCase())) {
            // Trigger matches
            id = entry.getKey();
            replacementText = triggerText.replace("/", "");
            matched = true;
          }
        }
        if (matched) break;
      }
    }

    if (!matched && regexId != null) {
      id = regexId;
      replacementText = regexMessage;
    }

    // If there was a match, the id of the match should have been returned.
    if (id != null) {
      Utilities.talkToNPC(
          replacementText, denizenPlayer, npc, Settings.ChatToNpcOverhearingRange());
      parse(npc, denizenPlayer, script, id, context);
      return true;
    } else {
      // If this is a Chatbot, make it chat anything it wants if
      // none of its chat triggers worked
      if (npc.getCitizen().hasTrait(ChatbotTrait.class)) {
        Utilities.talkToNPC(message, denizenPlayer, npc, Settings.ChatToNpcOverhearingRange());
        npc.getCitizen().getTrait(ChatbotTrait.class).chatTo(player, message);
        return true;
      } else if (!Settings.ChatGloballyIfFailedChatTriggers()) {
        Utilities.talkToNPC(message, denizenPlayer, npc, Settings.ChatToNpcOverhearingRange());
        return true;
      }
      // No matching chat triggers, and the config.yml says we
      // should just ignore the interaction...
    }
    return ret;
  }