Hire a Bodyguard


Author: mythanical
Created: 2013-03-10T22:15:20-0400
Edited: 2014-01-12T03:54:53-0500
Denizen Version: 0.9.3
Views: 360
Downloads: 3387
Likes: 8


WGET
Description: # Hire a Bodyguard
# Citizens 2 (build #1045)
# Sentry (v. 1.8.0)
# Denizen 0.9.3 (build #1417)

To assign to an NPC, type:
/npc assign --set "mercenary"

You MUST also do the following to assign the global flags needed by this script:
/denizen reload scripts

NEW:
1) You can now enable multiple guards for players.
2) A new health bar, which is dynamically generated. The benefit with this new health bar is that in the future if the script is modified to allow you to specify a health other than 20 for an NPC, that the health bar will automatically work with the new NPC health.
3) Guards can now have an abbreviated version of a player's name at the end of it's own.
4) Guards can be upgraded to the next Tier while 'out in the field'.
5) Various types of food can be used to heal a guard.
6) Global flag default to remove horse when the knight is killed OR fired.

Description:
The purpose of this script is to allow you to have a "bodyguard" service for your players. When they talk to the NPC, it will offer them 4 tiers of guards. The first being the weakest and the cheapest up to the most expensive but also strongest. You can however modify their strength and armor ratings to suit your server.

On default, each 'level' wears different armor - leather, iron and then diamond. However, the armor is purely cosmetic and doesn't affect their armor rating at all. You can modify the type of armor to any one of the examples I provided.

You should also change the price for each guard to suit your economy and server type.

If the player hired a bodyguard and then forgot them somewhere or they disconnected and the bodyguard is gone, they can go back to the mercenary to teleport the bodyguard back to them.

Requirements: For this script to work, you will need:
* Citizens 2 (http://ci.citizensnpcs.com/view/All/job/Citizens2/)
* Sentry (http://wiki.citizensnpcs.com/Sentry)
* Denizen (http://ci.citizensnpcs.com/job/Denizen%20Developmental/)
* An economy to deal with money as a method of payment (like iConomy)

NOTE:
* You may get the following debug in the server log when a bodyguard dies, but
it's nothing to be concerned about:
[dNPC] Uh oh! Denizen has encountered an NPE while trying to fetch a NPC. Has this NPC
been removed?".
* Feel free to suggest features.

Go check out my Petshop (with Mountable NPC's) script for another slightly more complex example of NPC/Player interaction:
http://scripts.citizensnpcs.com/view/rqnu12

# Hire a Bodyguard
# Citizens 2 (build #1045)
# Sentry (v. 1.8.0)
# Denizen 0.9.3 (build #1417)
#
# Description:
#
# The purpose of this script is to allow you to have a "bodyguard" service for your players. When a player talks
# to the NPC, it will offer them 4 different guards. The first being the weakest and the cheapest up to the
# most expensive but also strongest. You can however modify their strength and armor ratings below
# to suit your server.
#
# On default, each 'level' wears different armor - leather, iron, diamond and chainmail (for the horse mounted
# NPC's). However, the armor is purely cosmetic and doesn't affect their armor rating at all. You can modify 
# the type of armor in the 'default constants' section below.
#
# You should also change the price for each guard to suit your economy and server type.
#
# If the player hired a bodyguard and then forgot them somewhere or they disconnected and the bodyguard
# is gone, they can go back to the mercenary to teleport the bodyguard back to them (if it's still alive).
#
# Credits:
#        * davidcernat for having to add a bunch of new features and bug fixes to make this work.
#        * Jeebiss whose 'Hireable Bodyguards' script was used as a template for this one.
#        * fullwall and jrbudda for super fast fixes to Citizens & Sentry to make this possible.
#
# @author mythanical
# @script version 0.6.3
# @last-updated 10 January 2014
# @irc EsperNet IRC Network #denizen-dev
# @Minecraft Server - minecraft.geek.nz
# @Donate Bitcoin: 1Fzacc2gZ5NGRMXg5jWP6NcUkWei34xjzt
# @Donate Litecoin: LhsaGa1QzmVLjMYwg4ZPTVnmSgnBDGc75U

"Bodyguard Global Flag":
  type: world
  events:
    on reload scripts:
    # --- DO NOT MODIFY THESE TWO VALUES ---
    - flag global "Bodyguard Food:!"
    - flag global "Bodyguard Food Heal Amount:!"
 
    # The following is a list of foods that will heal a guard. The flag under that hold the corresponding heal
    # amount for the food in the matching position. So, "i@baked_potato" is second in the list, so the second
    # value in the 'heal amount' list is 6. That is how much the guard will be healed.
    - flag global "Bodyguard Food:|:i@apple|i@baked_potato|i@bread|i@cake|i@carrot|i@cooked_beef|i@cooked_chicken|i@cooked_fish|i@grilled_pork|i@cookie|i@melon|i@mushroom_soup|i@pumpkin_pie|i@raw_beef|i@raw_chicken|i@raw_fish|i@pork"
    - flag global "Bodyguard Food Heal Amount:|:4|6|5|12|4|8|6|5|8|2|2|6|8|3|2|2|3"
 
    # If this value is anything other than '0', the player will get it as a percentage refund on the amount
    # they paid for the guard.
    - flag global "Bodyguard Refund Percentage:50"
 
    # Give players 15 seconds to type 'bye guard' after clicking a guard, to fire them and get a refund
    # if enabled.
    - flag global "Bodyguard Listen Time:15s"
 
    # The name for the bodyguard type - this is what the player will need to enter when they buy
    # their bodyguard. If you use the 'dynamic' player suffix setting further below I wouldn't
    # recommend a name longer than 8 characters.
    - flag global "Bodyguard One Name:Peon"
    - flag global "Bodyguard Two Name:Thug"
    - flag global "Bodyguard Three Name:Brute"
    - flag global "Bodyguard Four Name:Knight"
 
    # Change to 'Disallow' if you do not want to allow Knights (horse mounted Sentries).
    - flag global "SentryHorseMountAllow:Allow"
 
    # Remove Horse when the NPC is fired or dies.
    - flag global "RemoveHorseMount:Allow"
 
    # This sets a limit for the number of guards a player can have.
    - flag global "Bodyguard Limit:2"
 
    # Allows guards names to have the owner's name abbreviated and suffixed at the end. If you
    # change the guard names, you will have to change the abbreviation lengths too otherwise
    # you may get some undesired results.
    #
    # dynamic           (Add the longest player name abbreviation it can fit into 16 chars)
    # 1-16              (If you want a static length abbreviation, then specify a value here. Note, if you make it too long you'll get some undesired results)
    # disallow          (To disable player name suffixes)
    - flag global "Player Name Suffix:dynamic"
 
    # Specify the colour of the abbreviated player name.
    # Color list available here:
    #  http://jd.bukkit.org/rb/apidocs/org/bukkit/ChatColor.html
    - flag global "Player Name Suffix Color:green"
 
    # The "sentry" strength for each bodyguard type.
    - flag global "Bodyguard One Strength:7"
    - flag global "Bodyguard Two Strength:7"
    - flag global "Bodyguard Three Strength:8"
    - flag global "Bodyguard Four Strength:9"
 
    # The "sentry" strength for each bodyguard type.
    - flag global "Bodyguard One Armor:5"
    - flag global "Bodyguard Two Armor:6"
    - flag global "Bodyguard Three Armor:7"
    - flag global "Bodyguard Four Armor:8"
 
    # This is the number of seconds between heals of 1 point, values less than 1.0 are acceptable. Set to 0 to turn off healing.
    # A heal rate of 0.5 is 2hp per second. A healrate of 0.1 is 10hp per second. A healrate of 0.01 is 100hp per second.
    - flag global "Bodyguard One Healrate:0"
    - flag global "Bodyguard Two Healrate:0"
    - flag global "Bodyguard Three Healrate:0"
    - flag global "Bodyguard Four Healrate:0"
 
    # Cosmetic Armor to differentiate between guard levels. You can have 'leather', 'chainmail', 'iron', 'gold' and 'diamond'.
    - flag global "Bodyguard One Appearance:Leather"
    - flag global "Bodyguard Two Appearance:Iron"
    - flag global "Bodyguard Three Appearance:Diamond"
    - flag global "Bodyguard Four Appearance:Chainmail"
 
    # The swords the bodyguards will wield. You can have 'wood', 'stone', 'iron', 'gold', 'diamond'.
    - flag global "Bodyguard One Sword:Wood"
    - flag global "Bodyguard Two Sword:Stone"
    - flag global "Bodyguard Three Sword:Iron"
    - flag global "Bodyguard Four Sword:Diamond"
 
    # Price to hire guard    
    - flag global "Bodyguard One Price:1500"
    - flag global "Bodyguard Two Price:3000"
    - flag global "Bodyguard Three Price:5000"
    - flag global "Bodyguard Four Price:10000"
 
    # Show Guard Health as Bar or Percentage (anything other than "bar" will display a percentage for the health).
    # Experiment and see which one you'd prefer your players to see.
    - flag global "Bodyguard Health:bar"
 
    # -- IGNORE THIS SECTION, NOT IMPLEMENTED YET. ---
    # If this is any value other than 'disallow', an inventory window will open when
    # the guard is right clicked. The guard will also wait until they are right clicked
    # again before they start following the player.
    #
    # drop              (Drop all items on the ground where the guard died)
    # disallow          (Disable bodyguard inventories)
    - flag global "Bodyguard Inventory:disallow"

"Mercenary":
  type: assignment
    
  interact scripts:
  - 10 Hire a Bodyguard

  actions:
    on assignment:
    # These triggers enable interaction with an NPC via chatting, clicking, entering proximity and when damaging the NPC.
    - trigger name:chat toggle:true
    - trigger name:click toggle:true
    - trigger name:proximity toggle:true
    - trigger name:damage toggle:true
    # Make it so the mercenary can be killed by players. The mercenary will respawn 60 seconds later. Otherwise, just comment the following
    # three lines and the mercenary will be invulnerable.
    - ^execute as_npc "npc sel <npc.id>"
    - ^execute as_npc "npc vulnerable"
    - ^execute as_npc "npc respawn 60"

    on death by player:
    # When a player kills the mercenary, narrate something. On my server, I run another script instead that 
    # changes the alignment of the player for committing this heinous act.
    - narrate "<red>You have killed <yellow><npc.name><red>. Are you pleased with yourself?"

"Hire a Bodyguard":
  type: interact
  
  steps:
    1:
      proximity trigger:
        entry:
          script:
          # On player entering NPC proximity range, run a script called 'Check Greeting Requirements'. 
          # The default proximity range is set in Denizen\config.yml
          - run "Check Greeting Requirements"

      click trigger:
        script:
        # On clicking, run a slightly different script to check some requirements to see what dialog
        # the player should be presented with.
        - run "Bodyguard Requirement Check"

      damage trigger:
        script:
        # When you hit the NPC, it will run the script called Warning (further below).
        - run "Warning"

    2:
      chat trigger:
        'Lost NPC':
          Trigger: "/Yes/ please, /find/ a guard for me and bring them back."
          script:
          # When the bodyguard is created, they add their own NPC ID into a player flag. This flag is then used to
          # provide the NPC ID in the teleport command and teleport them back to the same location as the player.
          - engage
          - if <player.flag[GuardId].size> >= 1 {
            - random {
              - chat "<yellow>Ok <yellow><player.name><yellow>, we're tracking him down now..."
              - chat "<yellow>I'm sending word now.. your guard is on their way back."
              - chat "<yellow>I have informed the network of your missing guard, they are searching for them now." }
            - wait 4
            - random {
              - chat "<yellow>Found 'em!"
              - chat "<yellow>Ah good, they are still alive. Here you go <white><player.name><yellow>."
              - chat "<yellow>Welcome back <white><player.flag[GuardId].formatted><yellow>." }
            - teleport <player.flag[GuardId].aslist> location:<player.location>
            - ^foreach <player.flag[GuardId].aslist> {
              - if <%value%.flag[Guarding]> == null {
                - flag %value% Guarding
                - execute as_npc "npc sel <%value%.id>"
                - execute as_npc "sentry guard <npc.owner.name>" }
              }
            }
 
            else {
              - random {
                - chat "<yellow>I'm sorry <white><player.name><yellow>, but I've got nothing on record about you having a guard."
                - chat "<yellow>I..can't find any guards for you on the ledger. Are you sure they're still alive?"
                - chat "<yellow>Your guards either died or you fired them because I can't track any down.."
                }
            }
          - disengage

        'Leave NPC':
          Trigger: /No/ thank you, I want to leave them where they are.
          script:
          - engage
          - chat "<yellow>No problem <white><player.name><yellow>, come see me if you want them brought back."
          - disengage

        'Which Bodyguard':
          Trigger: I am interested in hiring '/REGEX:^\w+$/'.
          script:
          # When the player enters the name of the guard they want to hire, the following logic kicks in.
          # The following options exist in the section below:
          # 1) Engage the NPC so no other players can interact with them.
          # 2) Check to see if what the player entered matches any of the 4 bodyguard names.
          # 3) Has the player already got guards and if so, are they over or under the guard limit. If over, tell
          #    them they cannot hire more guards.
          # 4) Check to see if they've got enough money for the guard name they entered. If they haven't, tell them they don't.
          # 5) Otherwise if what the player typed doesn't match any criteria, tell them the NPC doesn't know what they're saying.
          # 6) Disengage the NPC so other players can interact again.
 
          - engage
          - ^if "<global.flag[Bodyguard One Name]>|<global.flag[Bodyguard Two Name]>|<global.flag[Bodyguard Three Name]>|<global.flag[Bodyguard Four Name]>" contains <context.message> {
            - if <player.flag[GuardId].size> < "<global.flag[Bodyguard Limit]>" {
 
              - if <context.message> == "<global.flag[Bodyguard One Name]>" && <player.money> >= "<global.flag[Bodyguard One Price]>" run "Create Bodyguard" def:One instantly
                else if <context.message> == "<global.flag[Bodyguard Two Name]>" && <player.money> >= "<global.flag[Bodyguard Two Price]>" run "Create Bodyguard" def:Two instantly
                else if <context.message> == "<global.flag[Bodyguard Three Name]>" && <player.money> >= "<global.flag[Bodyguard Three Price]>" run "Create Bodyguard" def:Three instantly
                else if <context.message> == "<global.flag[Bodyguard Four Name]>" && <player.money> >= "<global.flag[Bodyguard Four Price]>" run "Create Bodyguard" def:Four instantly
 
                else if <context.message> == "<global.flag[Bodyguard One Name]>"
                && <player.money> < "<global.flag[Bodyguard One Price]>"
                narrate "<red>You have <gold><player.money.asint><red> <player.money.currency>, but need <gold><global.flag[Bodyguard One Price]><red> <player.money.currency><red> to pay <white><npc.name><red>."
                else if <context.message> == "<global.flag[Bodyguard Two Name]>"
                && <player.money> < "<global.flag[Bodyguard Two Price]>"
                narrate "<red>You have <gold><player.money.asint><red> <player.money.currency>, but need <gold><global.flag[Bodyguard Two Price]><red> <player.money.currency><red> to pay <white><npc.name><red>."
                else if <context.message> == "<global.flag[Bodyguard Three Name]>"
                && <player.money> < "<global.flag[Bodyguard Three Price]>"
                narrate "<red>You have <gold><player.money.asint><red> <player.money.currency>, but need <gold><global.flag[Bodyguard Three Price]><red> <player.money.currency><red> to pay <white><npc.name><red>."
                else if <context.message> == "<global.flag[Bodyguard Four Name]>"
                && <player.money> < "<global.flag[Bodyguard Four Price]>"
                && "<global.flag[SentryHorseMountAllow]>" == "Allow"
                narrate "<red>You have <gold><player.money.asint><red> <player.money.currency>, but need <gold><global.flag[Bodyguard Four Price]><red> <player.money.currency><red> to pay <white><npc.name><red>."
              }
 
              else {
                - narrate "<red>You cannot hire anymore guards. The guard limit per player is <white><global.flag[Bodyguard Limit]>."
              }
            }
            else {
              - chat "<yellow>I'm sorry <white><player.name><yellow>, but I don't know who or what <white>'<context.message>'<yellow> is."
            }
 
          - disengage

      click trigger:
        script:
        # It helps to put some extra click and proximity types triggers in the different steps for a script. That way the
        # player will always get some kind of feedback from an NPC to know where they are at with a dialog or if the NPC
        # is waiting for a response of some sort.
        - run "Bodyguard Requirement Check"

      proximity trigger:
        exit:
          script:
          # When player leaves NPC proximity, put them back to step 1 in 'Hire a Bodyguard' script so
          # it'll be a fresh new conversation when they come back.
          - zap step:1

"Check Greeting Requirements":
  type: task
  speed: 0

  script:
  # The following options exist here (only really for player immersion)
  # 1) If a bodyguard has been hired already, greet them with the 'Mercenary Hired Bodyguard Chat' script.
  # 2) Else simply greet them with the 'Mercenary General Chat'.
  - if <player.flag[GuardId].size> == 1 {
    - random {
      - chat "<yellow>Welcome back <white><player.name><yellow>, hope all is going well with your bodyguard?"
      - chat "<yellow>Hi <white><player.name><yellow>, how is it going with your bodyguard? Are you just checking in?"
      - chat "<yellow>If you ever lose your guard, just come talk to me and I can track them down for you."
      - chat "<yellow>Your bodyguards is a great fighter, but not the smartest. If they ever get lost, just come chat to me."
      - chat "<yellow>Ah <white><player.name><yellow>, I see on the list you've employed one of our fine fighters. Hope all is well."
      - chat "<yellow>Hope your bodyguard has been a great help cracking zombie skulls." }
    }
 
    else if <player.flag[GuardId].size> > 1 {
    - random {
      - chat "<yellow>Welcome back <white><player.name><yellow>, hope all is going well with your <player.flag[GuardId].size> bodyguards?"
      - chat "<yellow>Hi <white><player.name><yellow>, how is it going with your bodyguards? Are you just checking in?"
      - chat "<yellow>If you ever lose your guards, just come talk to me and I can track the <player.flag[GuardId].size> down for you."
      - chat "<yellow>These bodyguards are great fighters, but not the smartest. If they ever get lost, just come chat to me."
      - chat "<yellow>Ah <white><player.name><yellow>, I see on the list you've employed <player.flag[GuardId].size> of our fine fighters. Hope all is well."
      - chat "<yellow>Hope your bodyguards have been a great help cracking zombie skulls." }
    }
 
    else {
      - random {
        - chat "<yellow>Are you interested in some extra protection? Come chat to me."
        - chat "<yellow>Hi <white><player.name><yellow>, need someone to help you out? I can provide a bodyguard at a reasonable price."
        - chat "<yellow>Seems to me like you can use a bodyguard <white><player.name><yellow>."
        - chat "<yellow>Help is hard to find these days, except when you've got coin. Let's talk business."
        - chat "<yellow>Are you an important public figure? Someone wants you dead? Don't worry, I've got a solution."
        - chat "<yellow>Small zombie hordes knocking at the door? Our bodyguards will be knocking on their skulls instead." }
    }

"Warning":
  type: task
  speed: 0

  script:
  # If you hit the mercenary, the "damage" triggers in the "Hire a Bodyguard" section above will run this script.
  - random {
    - chat "<red>Oucch! <yellow>Why would you do that? If I die, you WILL regret it!"
    - chat "<red>Aaarrggg! <yellow>What did I ever do to you? Don't hit me again!"
    - chat "<red>Wha..why are you hurting me? <yellow>Oh, these cuts..they hurt so much."
    - chat "<red>Please don't hurt me! <yellow>I have never done anything bad to you!"
    - chat "<red>Owwee! <yellow>Don't do something now that you will regret later.." }

"Bodyguard Requirement Check":
  type: task
  speed: 0

  script:
  # This task runs when the player interacts with the Mercenary.
  # 1) First it checks to see if the player has reached their bodyguard limit, if so, it will present
  #    them with only the teleport options.
  # 2) Else, if they have a guard but are still under the bodyguard limit it will present them with
  #    a dialogue that lists the guards but also give the 'Find' option to teleport them back.
  # 3) Lastly, if the player doesn't have any guards, it will simply present them with a list of available
  #    guards.
  #
  # This part of the script only shows stuff on the screen, it's the command at the bottom
  # called 'zap' that takes it to the right section where it's waiting for a response from the player.
 
  - if <player.flag[GuardId].size> >= "<global.flag[Bodyguard Limit]>" {
    - random {
      - chat "<yellow>Hi <white><player.name><yellow>, did you lose your bodyguard? We can use our network of agents to track 'em down."
      - chat "<yellow>You can't hire any more guards, but I can track down the missing ones for you."
      - chat "<yellow>I never said these guards were smart. Did you want me to bring them back?" }
    - narrate "<red>Say<&co>"
    - narrate "  <gray>[<green>Yes<gray>] <red>- To teleport <white><player.flag[GuardId].formatted><red> back to you."
    - narrate "  <gray>[<yellow>No<gray>] <red> - To cancel teleport dialogue."
    }
 
    else if <player.flag[GuardId].size> >= 1 && <player.flag[GuardId].size> < "<global.flag[Bodyguard Limit]>" {
      - random {
        - chat "<yellow>Hi <white><player.name><yellow> are you here to hire another guard or find a missing one?"
        - if "<el@val[<m:<global.flag[Bodyguard Limit]>-<player.flag[GuardId].size>>].asint>" > 1 {
          - chat "<yellow>You can still hire <gold><el@val[<m:<global.flag[Bodyguard Limit]>-<player.flag[GuardId].size>>].asint><yellow> guards or do you want me to find a lost guard for you?" }
 
          else {
            - chat "<yellow>Hi <white><player.name><yellow>, do you want to hire another guard or track down a missing one?" }
 
        - chat "<yellow>You've got a couple of options <white><player.name><yellow>, either hire another guard or I can track down your other ones and teleport them back."
        }
      - narrate "<red>Say<&co>"
      - narrate "  <gray>[<white><global.flag[Bodyguard One Name]><gray>]  - Low Level - <gold><global.flag[Bodyguard One Price]> <player.money.currency>"
      - narrate "  <gray>[<yellow><global.flag[Bodyguard Two Name]><gray>]   - Mid Level  - <gold><global.flag[Bodyguard Two Price]> <player.money.currency>"
      - narrate "  <gray>[<blue><global.flag[Bodyguard Three Name]><gray>] - High Level - <gold><global.flag[Bodyguard Three Price]> <player.money.currency>"
      - if "<global.flag[SentryHorseMountAllow]>" == "Allow" narrate "  <gray>[<dark_purple><global.flag[Bodyguard Four Name]><gray>] - Ultra Level - <gold><global.flag[Bodyguard Four Price]> <player.money.currency>"
      - narrate "  <gray>[<green>Find<gray>]<red> to teleport <white><player.flag[GuardId].formatted><red> back to you."
    }
 
    else {
      - random {
        - chat "<yellow>These men will protect you..for a price."
        - chat "<yellow>The more coin you have, the better protection you can buy."
        - chat "<yellow>You have the following guards to choose from..."
        - chat "<yellow>What type of help are you looking for?" }
      - narrate "<red>Say<&co>"
      - narrate "  <gray>[<white><global.flag[Bodyguard One Name]><gray>]  - Low Level - <gold><global.flag[Bodyguard One Price]> <player.money.currency>"
      - narrate "  <gray>[<yellow><global.flag[Bodyguard Two Name]><gray>]   - Mid Level  - <gold><global.flag[Bodyguard Two Price]> <player.money.currency>"
      - narrate "  <gray>[<blue><global.flag[Bodyguard Three Name]><gray>] - High Level - <gold><global.flag[Bodyguard Three Price]> <player.money.currency>"
      - if "<global.flag[SentryHorseMountAllow]>" == "Allow" narrate "  <gray>[<dark_purple><global.flag[Bodyguard Four Name]><gray>] - Ultra Level - <gold><global.flag[Bodyguard Four Price]> <player.money.currency>"
    }
  - zap "s@Hire a Bodyguard" step:2
 

"Create Bodyguard":
  type: task
 
# You'll notice this task keeps on referencing to a variable called %1%. This value got passed into the task
# when the 'run' command was executed in a section above when the player types in whether they wanted a 'Peon',
# 'Brute' etc. So if the user picked the 'Peon', it will pass the word 'One' as a definition into the task.
# So the %1% is then substituted with the word 'One' - so "Bodyguard %1% Price" becomes "Bodyguard One Price" and
# so on.

  script:
  # Take the money from the player for the relevant guard - remember, %1% will be substituted with One, Two,
  # Three or Four.
  - ^take money "qty:<global.flag[Bodyguard %1% Price]>"
 
  # Flag the player with how much they paid for the guard and also what Tier the guard is. Both these flags are
  # actually transfered to the Bodyguard as NPC flags and is used when the guard is upgraded to know which tier
  # they can be upgraded to and what the difference is the player needs to pay.
  - ^flag <player> "Bodyguard Price Paid:<global.flag[Bodyguard %1% Price]>"
  - ^flag <player> "Bodyguard Tier:%1%"
 
  # Give a bit of info on the guard, depending on their tier.
  - ^if %1% == One chat "<yellow>Alright, <white><player.name><yellow>. His life is in your hands. Try not to get him killed too quickly."
    else if %1% == Two chat "<yellow>Alright, <white><player.name><yellow>. <global.flag[Bodyguard Two Name]> is ruthless - but not too smart."
    else if %1% == Three chat "<yellow>Alright, <white><player.name><yellow>. You shouldn<&sq>t be worried about creepers for a while, this <global.flag[Bodyguard %1% Name]> can handle his own..."
    else if %1% == Four chat "<white><player.name><yellow> I present to you the best of the best. The one, the only.. <white><global.flag[Bodyguard %1% Name]><yellow>!"
 
  # Narrate to the player how much they paid.
  - ^narrate "<red>You pay <npc.name> <gold><global.flag[Bodyguard %1% Price]><red> <player.money.currency>."
 
  # This part uses some smarts to add an abbreviation of the player's name at the end of the guard name. The
  # problem is that guard names can be different lengths.
  # 1) If you picked 'dynamic' at the top of the script, it will calculate how much space is available in
  #    the guard's name and try to fit in as much of the player's name. It does this by using the "substring" tag
  #    and manipulates it's length based on a small calculation.
  # 2) Else if it's been 'disallowed' just create the NPC with their usual name.
  # 3) If not dynamic or disallowed then it'll be expecting a number between 1-16. This is obviously if you only
  #    ever want the first, say, 3 letters of an owner's name, but then you NEED to make sure the entire name length
  #    doesn't exceed 16 chars.
  - ^if "<global.flag[Player Name Suffix]>" == "dynamic" {
    - execute as_npc "npc create <global.flag[Bodyguard %1% Name]> [<<global.flag[Player Name Suffix Color]>><player.name.substring[1,<el@val[<m:13-<el@<global.flag[Bodyguard %1% Name]>.length>>].asint>]><white>] --speed 1.2 --trait sentry"
    }
    else if "<global.flag[Player Name Suffix]>" == "disallow" {
      - execute as_npc "npc create <global.flag[Bodyguard %1% Name]> --speed 1.2 --trait sentry"
    }
    else {
      - execute as_npc "npc create <global.flag[Bodyguard %1% Name]> [<<global.flag[Player Name Suffix Color]>><player.name.substring[1,<global.flag[Player Name Suffix]>]><white>] --speed 1.2 --trait sentry"
    }
 
  # This script is commented further below.
  - ^run "Bodyguard Basics" instantly
 
  # If they picked 'Knight', it will translate to tier 'Four' which is a bodyguard on a horse.
  - ^if %1% == Four execute as_npc "sentry mount"
 
  # Next set the relevant strength, healrate and armor.
  - ^execute as_npc "sentry strength <global.flag[Bodyguard %1% Strength]>"
  - ^execute as_npc "sentry healrate <global.flag[Bodyguard %1% Healrate]>"
  - ^execute as_npc "sentry armor <global.flag[Bodyguard %1% Armor]>"
 
  # Equip the NPC with their corresponding armour set at the top of the script.
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Sword]>_SWORD"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_HELMET"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_CHESTPLATE"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_LEGGINGS"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_BOOTS"

"Upgrade Bodyguard":
  type: task
 
# This task is almost a repeat of the one above. The only difference really being
# that it charges the different between the price from the original to the new Tier.

  script:
  - ^define UpgradeCost "<el@val[<m:<global.flag[Bodyguard %1% Price]>-<npc.flag[Price]>>].asint>"
  - ^take money qty:%UpgradeCost%
  - ^narrate "<red>You pay <npc.name> <gold>%UpgradeCost%<red> <player.money.currency>."
  - ^flag <npc> "Price:<global.flag[Bodyguard %1% Price]>"
  - ^flag <npc> "Tier:%1%"
  - ^if %1% == Two chat "<yellow>Ok boss, I have gone for some training and I'm a <white><global.flag[Bodyguard Two Name]><yellow> now! I can smash things with my head!"
    else if %1% == Three chat "<yellow>Alright, <white><player.name><yellow>. You shouldn<&sq>t be worried about creepers for a while, as a <white><global.flag[Bodyguard %1% Name]><yellow> I can handle my own..."
    else if %1% == Four chat "<yellow>I am <white><global.flag[Bodyguard %1% Name]><yellow>. Here to serve and protect with honor. Long live <white><player.name><yellow>!"
 
  - ^if "<global.flag[Player Name Suffix]>" == "dynamic" {
    - rename "<global.flag[Bodyguard %1% Name]> [<<global.flag[Player Name Suffix Color]>><player.name.substring[1,<el@val[<m:13-<el@<global.flag[Bodyguard %1% Name]>.length>>].asint>]><white>]"
    }
    else if "<global.flag[Player Name Suffix]>" == "disallow" {
      - rename "<global.flag[Bodyguard %1% Name]>"
    }
    else {
      - rename "<global.flag[Bodyguard %1% Name]> [<<global.flag[Player Name Suffix Color]>><player.name.substring[1,<global.flag[Player Name Suffix]>]><white>]"
    }
  - ^execute as_npc "npc sel <npc.id>"
  - ^if %1% == Four execute as_npc "sentry mount"
  - ^execute as_npc "sentry strength <global.flag[Bodyguard %1% Strength]>"
  - ^execute as_npc "sentry healrate <global.flag[Bodyguard %1% Healrate]>"
  - ^execute as_npc "sentry armor <global.flag[Bodyguard %1% Armor]>"
  - ^execute as_npc "sentry equip none"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Sword]>_SWORD"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_HELMET"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_CHESTPLATE"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_LEGGINGS"
  - ^execute as_npc "sentry equip <global.flag[Bodyguard %1% Appearance]>_BOOTS"
  - ^if <npc.flag[Guarding]> == null execute as_npc "sentry guard"
    else execute as_npc "sentry guard <npc.owner.name>"
 

"Bodyguard Basics":
  type: task

  script:
  # The point of this script is to combine as many of the commands that are shared between the guards into one script
  # so they don't have to be repeated unnecessarily.
  - ^execute as_npc "npc owner <player.name>"
  - ^execute as_npc "sentry invincible false"
  - ^execute as_npc "sentry respawn -1"
  # Run the script called "Bodyguard Life and Death" in the section below.
  - ^execute as_npc 'npc assign --set "Bodyguard Life and Death"'
  - ^execute as_npc "sentry speed 1.2"
  - ^execute as_npc "sentry guard <player.name>"
  - ^execute as_npc "sentry follow 4"
  - ^flag <player> Guard:Hired
 
# The following assignment is given to the bodyguard itself and controls the living and dying aspects of it.

'Bodyguard Life and Death':
  type: assignment

  actions:
    on assignment:
    # This assignment only has one trigger and that's so the bodyguard can be instructed to follow the player
    # or stay in one spot.
    - trigger name:click toggle:true
    # Because the player didn't create this bodyguard, we need to tell the flag specifically who it should be
    # setting the flag against. The mercenary initially assigned the owner and now this command will put a
    # flag on the owner that holds the NPC ID for the bodyguard. This is so the mercenary will know which NPC
    # it's supposed to teleport back.
    - flag <npc.owner> GuardId:->:<npc>
    # This sets the flag status of the guard to 'true' initially, because it's guarding the player.
    - flag <npc> Guarding
    # Flag the guard with how much they were purchased for. This is used when calculating the refund percentage.
    - flag <npc> "Price:<npc.owner.flag[Bodyguard Price Paid]>"
 
    # Flag the guard with their tier, this is necessary to upgrade the guard.
    - flag <npc> "Tier:<npc.owner.flag[Bodyguard Tier]>"
    
    on click:
    # 1) When a player clicks the bodyguard and they are not the owner, it will tell them who the owner is.
    # 2) If they are the owner, and they are holding any of the foods listed in the 'Bodyguard Food' flag at
    #    the top of the script AND if the guard's health is below 100%, it will take the food and heal the
    #    guard with the corresponding value in the 'Bodyguard Food Heal Amount' global flag.
    # 3) Else if they are the owner and the 'Guarding' flag is set to 'true' (which it is initially) then change it's Sentry
    #    behaviour to guard it's area rather than its owner and display the Sentry's current health.
    # 4) Otherwise, if no criteria is met, run the command to guard the owner (player), update the flag and display the Sentry's current health.
    - ^if <npc.owner> != <player> chat "<yellow>I'm sorry <white><player.name><yellow>, but I work for <white><npc.owner.name><yellow> so I'm not going to take orders from you."
 
      else if "<global.flag[Bodyguard Food].aslist>" contains <player.item_in_Hand> && <npc.health.percentage> != 100 {
        - narrate "<red>You give <white><npc.name><red> <player.item_in_Hand.material.formatted><red> which heals them <green><global.flag[Bodyguard Food Heal Amount].get[<<global.flag[Bodyguard Food].aslist>.find[<player.item_in_Hand>]>]><red> health points."
        - run "Bodyguard Sound"
        - take <player.item_in_Hand>
        - heal <npc> "<global.flag[Bodyguard Food Heal Amount].get[<<global.flag[Bodyguard Food].aslist>.find[<player.item_in_Hand>]>]>"
        - if "<global.flag[Bodyguard Health]>" == "bar" run "Bodyguard Health Status" instantly
          else narrate "<yellow>NPC Health<&co> <red><npc.health.percentage.asint>%"
      }
 
      else if <npc.flag[Guarding]> {
        - if <global.flag[Bodyguard Food].size> > 0 && <npc.health.percentage> != 100 {
          - random {
            - chat "<yellow>I'll wait here boss, but do you have any food? I'm injured!"
            - chat "<yellow>I could really go for <<global.flag[Bodyguard Food].random>.material.formatted> now to heal up. I'll wait around here."
            - chat "<yellow>My mom always used to say, '<italic>Nothing like <<global.flag[Bodyguard Food].random>.material.formatted> to heal an aspiring young guard!<reset><yellow>'."
            - chat "<yellow>Urg, I'm bleeding. Have you got some food to help me heal? In the meanwhile, I'll wait around here until you give me new orders."
            - chat "<yellow>Hmm, <<global.flag[Bodyguard Food].random>.material.formatted> will help heal these wounds. I'll guard this spot."
            - chat "<yellow>Have you got <<global.flag[Bodyguard Food].random>.material.formatted> that I can snack on while I wait?"
            - chat "<yellow>Oh man, these wounds. You know, <<global.flag[Bodyguard Food].random>.material.formatted> will help me heal up while I wait for you to return."
            - chat "<yellow>Any food, like <<global.flag[Bodyguard Food].random>.material.formatted> will give me some health. Got any?"
            - chat "<yellow>How about <<global.flag[Bodyguard Food].random>.material.formatted> sandwich with <<global.flag[Bodyguard Food].random>.material.formatted> on top to heal me?"
            - chat "<yellow>My mom always used to make me <<global.flag[Bodyguard Food].random>.material.formatted> kebab. Hmmm, bet that will go well with <<global.flag[Bodyguard Food].random>.material.formatted> to heal these wounds."
            }
          }
 
          else {           
            - random {
            - chat "<yellow>Oh ok boss, I'll wait back here for you."
            - chat "<yellow>Don't worry about me, I'll stay back here. Please don't forget about me."
            - chat "<yellow>I'll wait around for you..but please don't forget about me."
            - chat "<yellow>You want me to hang back? Ok, no problem."
            - chat "<yellow>Ok, I'll guard this spot."
            - chat "<yellow>I'll stand here and wait until you come get me again."
            }
          }
        - ^execute as_npc "npc sel <npc.id>"
        - ^execute as_npc "sentry guard"
        - ^execute as_npc "sentry spawn"
        - flag <npc> Guarding:!
        - if "<global.flag[Bodyguard Health]>" == "bar" run "Bodyguard Health Status" instantly
          else narrate "<yellow>NPC Health<&co> <red><npc.health.percentage.asint>%" }
 
      else {
        - random {
          - chat "<yellow>Ok, I'm following you."
          - chat "<yellow>Great <white><player.name><yellow>, I'm right behind you."
          - chat "<yellow>You lead the way boss."
          - chat "<yellow>Watching your back. Let's go."
          - chat "<yellow>Great, let's go for a walk."
          - chat "<yellow>Hope we're going to crush some zombie skulls. Let's move." }
        - ^execute as_npc "npc sel <npc.id>"
        - ^execute as_npc "sentry guard <npc.owner.name>"
        - flag <npc> Guarding
        - if "<global.flag[Bodyguard Health]>" == "bar" run "Bodyguard Health Status" instantly
          else narrate "<yellow>NPC Health<&co> <red><npc.health.percentage.asint>%" }

    on death:
    # When the bodyguard dies, it will send a message to the owner, clears all the flags (so another bodyguard 
    # can be hired) and also removes the NPC from Citizens register.
    - narrate "<red>Your bodyguard, <white><npc.name><red>, has died." targets:<npc.owner>
    - flag <npc.owner> GuardId:<-:<npc>
    - if <global.flag[RemoveHorseMount]> == allow && <npc.get_vehicle> != null remove <npc.get_vehicle>

  interact scripts:
  - 10 Bodyguard

"Bodyguard":
  type: interact

  steps:
    1:
      click trigger:
        script:
        # This will construct a little menu when a player interacts with the guard. Currently there
        # are only two options as 'Inventory' is disabled until Developed by Denizen devs.
        # 1) [Upgrade] the guard to the next tier - show the player how much it's going to cost
        #    by doing a calculation on how much they paid initially and what the cost of the next
        #    tier is.
        # 2) [Fire] the guard. If there is a refund percentage specified in the 'Bodyguard Refund Percentage'
        #    flag it'll show what the refund percentage is.
        #
        # When the guard is right clicked, it will zap the interact step to "2" which includes a chat trigger.
        # So, effectively that guard starts 'listening' for certain keywords from the player. It does this
        # for the time specified in the 'Bodyguard Listen Time' global flag before it zaps back to step:1 
        # which doesn't have a 'chat' trigger.. so it stops listening. The reason for this is so that the guard
        # doesn't continuously intercept chats meant to go to other NPC's or players.
        - if <npc.owner> == <player> {
          - zap step:2
          - narrate "<green>------------------------------------------"
          - narrate "<red>You've got <global.flag[Bodyguard Listen Time]> to say<&co>"
          - if "<global.flag[Bodyguard Inventory]>" != disallow narrate "  <green>[<bold>Inventory<reset><green>]<white>  - Not Enabled Yet"
          - if <npc.flag[Tier]> == One {
            - define UpgradeCost "<el@val[<m:<global.flag[Bodyguard Two Price]>-<npc.flag[Price]>>].asint>"
            - narrate "  <blue>[<bold>Upgrade<reset><blue>]<white>    - Upgrade guard to <yellow>Tier 2<white> for <gold>%UpgradeCost%<white> <player.money.currency>" }
 
            else if <npc.flag[Tier]> == Two {
            - define UpgradeCost "<el@val[<m:<global.flag[Bodyguard Three Price]>-<npc.flag[Price]>>].asint>"
            - narrate "  <blue>[<bold>Upgrade<reset><blue>]<white>    - Upgrade guard to <blue>Tier 3<white> for <gold>%UpgradeCost%<white> <player.money.currency>" }
 
            else if <npc.flag[Tier]> == Three {
            - define UpgradeCost "<el@val[<m:<global.flag[Bodyguard Four Price]>-<npc.flag[Price]>>].asint>"
            - narrate "  <blue>[<bold>Upgrade<reset><blue>]<white>    - Upgrade guard to <dark_purple>Tier 4<white> for <gold>%UpgradeCost%<white> <player.money.currency>" }
 
          - if "<global.flag[Bodyguard Refund Percentage]>" > 0 narrate "  <red>[<bold>Fire<reset><red>]<white>          - Fire your guard and get a <gold><global.flag[Bodyguard Refund Percentage]>%<white> refund."
            else narrate "  <red>[<bold>Fire<reset><red>]<white>          - Fire your guard and get no refund."
          - narrate "<green>------------------------------------------"
          - wait "<global.flag[Bodyguard Listen Time]>"
          - zap step:1
          }

    2:
      chat trigger:
        'Inventory':
          trigger: "/inventory/"
          
          script:
          - if <global.flag[Bodyguard Inventory]> != disallow narrate "<red>Feature not enabled yet."

        'Upgrade':
          trigger: "/upgrade/"
          
          script:
          # When the player looks at the guard and types in 'upgrade' it will check the current tier and if they've
          # got enough money before running the upgrade task.
          - if <npc.flag[Tier]> == One && <player.money> >= "<el@val[<m:<global.flag[Bodyguard Two Price]>-<npc.flag[Price]>>].asint>" run "Upgrade Bodyguard" def:Two instantly
            else if <npc.flag[Tier]> == Two && <player.money> >= "<el@val[<m:<global.flag[Bodyguard Three Price]>-<npc.flag[Price]>>].asint>" run "Upgrade Bodyguard" def:Three instantly
            else if <npc.flag[Tier]> == Three && <player.money> >= "<el@val[<m:<global.flag[Bodyguard Four Price]>-<npc.flag[Price]>>].asint>" run "Upgrade Bodyguard" def:Four instantly
 
            else if <npc.flag[Tier]> == One && <player.money> < "<el@val[<m:<global.flag[Bodyguard Two Price]>-<npc.flag[Price]>>].asint>"
            narrate "<red>You need an additional <gold><el@val[<m:<m:<global.flag[Bodyguard Two Price]>-<npc.flag[Price]>>-<player.money>>].asint><red> <player.money.currency> to afford this upgrade."
 
            else if <npc.flag[Tier]> == Two && <player.money> < "<el@val[<m:<global.flag[Bodyguard Three Price]>-<npc.flag[Price]>>].asint>"
            narrate "<red>You need an additional <gold><el@val[<m:<m:<global.flag[Bodyguard Three Price]>-<npc.flag[Price]>>-<player.money>>].asint><red> <player.money.currency> to afford this upgrade."
 
            else if <npc.flag[Tier]> == Three && <player.money> < "<el@val[<m:<global.flag[Bodyguard Four Price]>-<npc.flag[Price]>>].asint>"
            narrate "<red>You need an additional <gold><el@val[<m:<m:<global.flag[Bodyguard Four Price]>-<npc.flag[Price]>>-<player.money>>].asint><red> <player.money.currency> to afford this upgrade."
 
            else narrate "<red>This guard can not be upgraded any further."

        'Fire Guard':
          trigger: "/fire/"
 
          # When the player triggers this, it will first check to see if the player is the owner. Then
          # check if the 'Bodyguard Refund Percentage' is larger than 0, if so it'll do a basic calculation depending
          # on how much the guard was purchased for and then give the player a specified percentage of their
          # money back.

          script:
          - if <npc.owner> != <player> narrate "<red>This guard belongs to <white><npc.owner.name><red>, you cannot fire it."
          - ^if <npc.owner> == <player> {
            - if "<global.flag[Bodyguard Refund Percentage]>" > 0
              {
              - define percentage "<m:<global.flag[Bodyguard Refund Percentage]>/100>"
              - define totalrefund <el@val[<m:<npc.flag[Price]>*%percentage%>].asint>
              - narrate "<red>Your guard, <white><npc.name><red>, has been removed and you<&sq>ve been refunded <gold>%totalrefund%<red> <player.money.currency>."
              - give money qty:%totalrefund%
              }
            - flag <npc.owner> GuardId:<-:<npc>
            - if <global.flag[RemoveHorseMount]> == allow && <npc.get_vehicle> != null remove <npc.get_vehicle>
            - remove <npc>
            }

"Bodyguard Sound":
  type: task
 
# This sound plays when the guard has been given food.

  script:
  - playsound sound:eat location:<npc.location>
  - playsound sound:eat location:<npc.location>
  - playsound sound:eat location:<npc.location>

#-------------------------------------------------------------------------------#
# The following script builds up a health bar for the NPC. It does
# this by dividing their current health by 10, the result of that, say 7.2 is
# then rounded down to 7. It then repeats a loop 7 times, each time adding
# 10 "|" characters into a flag. So 7 x ||||||||||.. the remaining 2 (7.2)
# then just gets added onto that, e.g. ||
#
# The reason I did it this way was so that it didn't repeat the loop 70 times to
# build up the number of health bars.
#
# In the example, 72 bars will be <GREEN> and the remaining 28 bars will be
# <RED>.
#
# This can be used with any NPC regardless of how much health they have 
# because it uses their "percentage" of health rather than max value health.
#-------------------------------------------------------------------------------#

"Bodyguard Health Status":
  type: task
  script:
  - ^if <npc.health.percentage> == 100
    narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||<white>]"
 
    else {
      - ^define GreenTenCount <el@val[<m:floor(<npc.health.percentage>/10)>].asint>
      - ^define GreenTenTotal <el@val[<m:%GreenTenCount%*10>].asint>
      - ^define GreenOneCount <el@val[<m:<npc.health.percentage>-%GreenTenTotal%>].asint>
 
      - ^define RedTenCount <el@val[<m:floor(<m:100-<npc.health.percentage>>/10)>].asint>
      - ^define RedTenTotal <el@val[<m:%RedTenCount%*10>].asint>
      - ^define RedOneCount <el@val[<m:<m:100-<npc.health.percentage>>-%RedTenTotal%>].asint>
 
      - ^repeat %GreenTenCount% {
        - flag <npc> "GreenBars:<npc.flag[GreenBars].replace[null]>||||||||||" }
 
      - ^repeat %GreenOneCount% {
        - flag <npc> "GreenBars:<npc.flag[GreenBars].replace[null]>|" }
 
      - ^repeat %RedTenCount% {
        - flag <npc> "RedBars:<npc.flag[RedBars].replace[null]>||||||||||" }
 
      - ^repeat %RedOneCount% {
        - flag <npc> "RedBars:<npc.flag[RedBars].replace[null]>|" }
 
      - ^if <npc.flag[RedBars]> == null narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green><npc.flag[GreenBars]><white>]"
        else narrate "<red><npc.name.substring[1,12]> Health<&co><white> [<green><npc.flag[GreenBars]><red><npc.flag[RedBars].replace[null]><white>]"
      - ^flag <npc> GreenBars:!
      - ^flag <npc> RedBars:!
    }




Comments
2013-03-23 12:04:28 - magsay0200:

Dear mythanical, I Have So Many Bugs That I discover on this SCRIPT! like when someone to Hire a bodyguard they just going no payable or the money never take, like Peon $1500 and you have $1500 when you buy it, your money still have $1500 when i checked the balance. but i FIX it Already, but i Have Still Problem: Bodyguard Is never attack Mob_Hustle when it close BUG FIX! No Dmg. Mob_Hustle : Still Find Solution! But to Players Have DMG! In 2 Bugs that I Fixed May I Submit to you Or Not? :) Sir Please Help Me For This 1 Problem I am Just a Beginner of Denizen Editor Script. And I wish that you may teach me To make Script and and java script so My wishes may come true that i made My own Plugins :)! i just have Server By the way But Lan only It Called "HGMCrafters" My age is 17. :) By the way my name Is Harold Ge Magsayo..... Thx a lot and you Gaven Script! By:HGM
2013-03-25 09:37:57 - vanillaice:

I found this problem from Sentry plugin. Because I tried make Bodyguard without Denizen. But Mobs couldn't take damage from bodyguard. Also Mobs from bodyguard,too. I reported this bug at Sentry forum.
2013-03-25 22:17:58 - mythanical:

Hey guys! I haven't tested this with MC 1.5 yet or checked whether all the plugins have been updated. I know there were some Sentry issues after the update but simply because it had to be properly updated. Magsay0200, some of your questions will be better answered by joining us on IRC, you can do that by going to --> http://webchat.esper.net/?nick=random_denizen_...&channels=denizen-dev&prompt=1
2013-03-27 07:29:25 - magsay0200:

Sir my Issue I used Version Is 1.4.7 not 1.5! i have not update yet all my bukkit server! :)
2013-04-04 23:44:36 - mythanical:

Magsay0200, I have added double quotes in front and after the money quantity which should now fix the problem with it not taking the money. It happens when there are spaces in constant value names. I'm sorry, I don't know what "mob_hustle" is. Are mobs not taking damage from the sentry? I'd say you'd be best off upgrading everything to the latest versions and getting the latest builds for Citizens, Sentry and Denizen.
2013-04-07 11:13:40 - Cubebix9000:

okay im using mc 1.5.1, denizens 0.8.8, citizens 2.0.8 alpha3 and sentry 1.3.3.2 for 1.5.1 and everything works 99% except that when you tell your guard to guard this area and then click again for him to follow you he wont follow you anymore and he will not attack other players attacking you, also if you lost your guard teleporting him back seems to sometimes work not always u like have to leave the area then come back dosent always work, havent checked if he attacks mobs yet. thanks.
2013-04-07 11:27:56 - Cubebix9000:

yep the guards attack mobs no problem so its just the bugs i have submited above i think its just an update that needs to be done with sentry / denizens ^^
2013-04-09 10:21:34 - mythanical:

Hey Cubebix9000, I'm running Craftbukkit (2744), Citizens (784), Denizen (996) and Sentry (v. 1.3.3.2). I couldn't reproduce the follow/wait issue, it works fine for me. I could however reproduce the teleport issue. This is new and would be because something has changed with Denizen since it's not recognising the command anymore - this is the error I'm getting: 23:13:12 [INFO] +- Executing command: TELEPORT/mythanical ------+ 23:13:12 [INFO] +> Filled tags: [targets:npc.3, location:103.80092906882467,64.0,242.72708999622088,world] 23:13:12 [INFO] ERROR! Invalid TARGET 'npc.3'! 23:13:12 [INFO] ERROR! Woah! Invalid arguments were specified! 23:13:12 [INFO] +> MESSAGE follows: 'Missing TARGETS argument. Nothing to teleport.' 23:13:12 [INFO] Usage: teleport (npc) [location:x,y,z,world] (target(s):[npc.#]|[player.name]) Will have to follow that up with the devs to find out what has changed. I will test the player attacking issue tomorrow and see what the problem is.
2013-04-09 10:32:25 - mythanical:

Just tested Sentry defending you when others player attack you and that's working fine also. I'd suggest you update your builds maybe. The only issue remaining now is the teleport one that is new and then of course the one mentioned in the top description which I'm waiting on the devs to to fix. Voice your need to have it fixed here: https://github.com/aufdemrand/Denizen/issues/145
2013-04-09 10:37:02 - mythanical:

Haha, I just tested the NPC dying to reset flags and it seems like it worked... maybe they did fix it but didn't sign the job off. I'll continue my testing tomorrow :)
2013-04-09 18:27:13 - mythanical:

The teleport command was changed in the newer Denizen builds. The script has been updated to use the new command. Make sure to update your Denizen build to at least 1000+!!!
2013-04-12 14:22:16 - Cubebix9000:

Do you know how to link Npc's? like you can only start this quest if you finished another quest from another npc? ive tried everything :/
2013-04-12 16:42:26 - Cubebix9000:

nvm figured it out.
2013-04-12 16:42:58 - Cubebix9000:

thanks for the fix.
2013-04-12 16:44:54 - Cubebix9000:

its probabaly due to cause im using spigot maybe instead of craftbukkit because craftbukkit breaks alot of plugins and spigot just have better overall preformance and dosent have as many issues as craftbukkit.
2013-04-12 18:20:53 - dtmullican:

I'm also running into the issue where the NPC will not resume following. It's a case sensitivity issue from what I can tell. returns all lowercase. If your name has uppercase, the sentry guard command seems to be case sensitive and thus doesn't know who "Player_A" is when returns "player_a".
2013-04-12 19:57:56 - dtmullican:

I'm also running into the issue where the NPC will not resume following. It's a case sensitivity issue from what I can tell. returns all lowercase. If your name has uppercase, the sentry guard command seems to be case sensitive and thus doesn't know who "Player_A" is when returns "player_a".
2013-04-13 11:01:55 - Umbrae:

I am loving what you have done with this and am experiencing the same as dtmullican. In addition to not guarding the player after stopping, interacting with the 'leader' doesn't get them to return even once they are "found". So far, I haven't been able to fix it on my own.
2013-04-13 14:20:36 - Umbrae:

Additionally, my 'Peon' died, but the Leader seems to think I still have it. /npc list shows it is long since gone.
2013-04-13 16:29:44 - Umbrae:

Additionally, my 'Peon' died, but the Leader seems to think I still have it. /npc list shows it is long since gone.
2013-04-14 05:05:10 - mythanical:

Darn, that would mean the "on death" bug hasn't been fixed yet. I've logged a job and someone else has logged something on Github (https://github.com/aufdemrand/Denizen/issues?state=open). Maybe go post something in those jobs to raise awareness. In regards to the owner lower/uppercase. Aufdemrand did a fix in Citizens build 790 that *should* fix that problem. Let me know how that goes for you guys! (http://ci.citizensnpcs.com/view/All/job/Citizens2/)
2013-04-14 05:06:41 - mythanical:

I was considering building in a flag reset option for OP's. So that while the "on death" isn't working properly that ops can at least reset the flag status without having to edit the "saves.yml" file. Is that something you guys would use?
2013-04-14 06:01:00 - Umbrae:

Mythanical, thank you for the response. I'll post to that Denizen issue to help bring it to attention. That upper/lowercase thing may be a factor for me to consider I have two capital letters in my name. I'm not certain though because initially they seem to follow me just fine. and yes, I would absolutely use a flag reset option -- this would allow control even in the instance of an issue elsewhere in Denizen.. I tried deleting the Mercenary Leader, removing the script, etc, but no matter what, somewhere a trace of owning a merc that prevents further interaction.
2013-04-14 10:01:16 - mythanical:

Umbrae, you need to edit the "saves.yml" file. Look for a value under the specific player having the problem, called something like "Guard:Hired". You need to delete that row out of the file completely and then do "denizen reload -a" from console. I'll look into adding that reset flag, hopefully within the next couple of days. I had someone confirm the follow bug is fixed now with the latest Citizens build. You should update Citizens & Denizen, then try it and let me know if you're still having the follow issue.
2013-04-15 01:49:16 - mythanical:

Hmmm... it would seem to implement a "Reset Flag" option for ops will require methods which hasn't been developed yet. I've logged a request on Github to have some development work done to make this possible. Don't worry, it'll happen.. just have to be patient :)
2013-04-15 14:15:09 - Umbrae:

For whatever reason, maybe I was looking under Citizens instead of Denizen, I wasn't finding the data in saves.yaml. I found it and followed your directions and that works to reset thing. Thank you. I'll look into updating Citizens/Denizen, but I am pretty darn sure they were/are the most current.
2013-04-15 14:43:41 - Umbrae:

Alright, here are my results: I updated from Citizens 2.0.8-SNAPSHOT (build 782) to (build 793). Denizen was up to date. After deleting "Guard:Hired", I was able to hire again. However, it still didn't seem to accept Creeper death. I deleting some of the other information, for instance pointing to the old NPC ID 9 for the bodyguard, and it properly told me that it died by Creeper. Additionally, I was able to tell them to follow or guard the area. They complied. The only thing that doesn't seem to work now is if I go to the Mercenary Leader and ask for him to find the Body Guard I "lost". I "lose" them by telling them not to follow by right-clicking. The Merc Leader says they are on their way, but they remain in place. I hope this helps... it sure has helped me.
2013-04-16 06:36:48 - mythanical:

Umbrae, can you also please check to see if you've got Sentry v. 1.3.3.3? http://wiki.citizensnpcs.com/Sentry
2013-04-16 06:48:09 - mythanical:

I just tested the script, the teleport missing guard works for me ... I'm having trouble reproducing your problem. Is your location in "world" or the nether, or do you use multiverse? The "On Death" bug with creepers..and probably other things like lava etc still persists. Not sure which of the two developments they'll deliver first to make either a permanent fix available or a workaround.
2013-04-21 16:39:56 - paragonx9:

Um, when I talk to the mercenary, he tells me what bodyguards I can choose from, but when I tell him which one nothing happens :(
2013-04-21 16:40:09 - paragonx9:

Um, when I talk to the mercenary, he tells me what bodyguards I can choose from, but when I tell him which one nothing happens :(
2013-05-05 15:49:06 - mythanical:

paragonx9, are you still having the problem? It sounds like you weren't looking at the NPC when you spoke to them or weren't within range. If you look in the "Denizen" folder, there is a file called "config.yml". Check the value called "Range" under "Triggers/Chat" and increase it. Let me know how you go.
2013-05-17 07:14:07 - mortegro:

Dear mythanical, i have the same problem with NPC-Damage: After getting a bodyguard, it takes no damage from the player and deals no damage to NPCs. However, if i remove the sentry trait with "/trait sentry" and put it right back on with the same command, everything works fine. In the saves.yml are no significant differences, and both behaviors are stable over a server restart. [bukkit 1.5.2-r01, citizen #807, denizen 0.8.8, sentry 1.3.5]. Do you have any suggestions how i can fix this?
2013-05-21 17:55:47 - mythanical:

Hi Mortegro, I just tried with Citizen #809, Denizen #1040 (make sure you update this one!) and Sentry 1.3.5 and couldn't reproduce the issue. Player kill NPC, NPC kill player, NPC kill mobs, mobs kill NPC, tnt kill NPC, lava kill NPC. I have made a little change to the script. Can you try it again plz?
2013-05-23 07:00:53 - mortegro:

Hi again, thanks for the reply. I tried these version plus sentry 1.3.6 and have still the same problem. But I kind of found out, that it seems to be a problem with sentry. It appears when i let an npc guard an player. Guarding the terretory it deals damage, guarding an player - nada. With distance-weapons (Bow, torch) - it works. But on the bright side: it seems to be everything allright with denizen and the script...
2013-06-05 06:29:44 - jstmemage:

Hi there Mythanical, I made an account on here hoping that I could send you a PM or start some line of conversation. The Scripts that you have on here are amazing and I would really like to pick your brain a little in like Skype or something.
2013-07-14 19:07:21 - mythanical:

Changes to the health system should fix some of the issues with the "Hired" flag not resetting when the bodyguard dies. Please let me know if you're still experiencing issues with this.
2013-07-20 06:08:55 - Tacoaloto:

I really like the idea of this script, but 1 issue. When guarding the player(myself) he can't harm anybody except for other NPCS. When guarding the immediate area he can damage hostile mobs like usual. Why can't he attack mobs when guarding a player?
2013-07-22 14:26:31 - mythanical:

Hi Tacoaloto! The behavior behind the bodyguard is controlled by the "Sentry" plug-in rather than my script. There are various different conditions you can configure on how the sentry should react to the different types of mobs etc. http://wiki.citizensnpcs.com/Sentry
2013-07-29 08:33:06 - techrosis:

I'm having the same issue with the hired flag not resetting. It removed the npc but didn't reset the flag. Using bukkit 1.6.2, denizen 0.8.9, and sentry 1.5. Any ideas on that? Don't really want to downgrade sentry if I can help it because i plan on using the Sentries on horses :)
2013-08-01 08:24:16 - mythanical:

Hi techrosis, you need Denizen 0.9.2 to fix that issue. You can find it here: http://ci.citizensnpcs.com/view/All/job/Denizen/
2013-09-10 01:26:58 - mythanical:

Script was broken after Denizen Devs made changes to flags and . I have updated the script. Let me know if there are any problems.
2013-10-15 20:52:38 - xojins:

How do we get a previous version of the script if we are running bukkit 1.6.2, denizen 0.9.1 and sentry 1.5? I cant upgrade my server due to some of the plugins that are not ready for 1.6.4. Thanks.
2013-10-27 05:01:01 - mythanical:

xojins, here is a copy I've got from April.. it's actually for Denizen 0.8.8 but check and see if it works. http://pastebin.com/raw.php?i=G0pLpa7Z
2013-11-05 10:10:26 - mythanical:

If you were having problems with guards being assigned to the wrong players or getting the wrong variables applied when several players were hiring guards at the same time, please try script version 0.6.2+. I have changed some of the scripts to run instantly and this should fix your problem. Please report back if it's not the case!
2014-01-29 13:53:25 - beleedad:

Registered just to express my appreciation for your work on this script. Its fantastic. Thank you.
2014-02-16 18:37:37 - xombiemike:

Excellent! I had to replace execute as_npc with as_op though.
2014-02-21 15:17:34 - Daisy:

Trying to run this script ( using Craftbukkit Beta build 1.7.2-RO.3, Citizens2 #1045, Denizen #1417, Sentry 1.8 ) and am seeing [null] for price and name of hireable guards. I only have essentials and vault running for testing the script.
2014-02-21 16:11:32 - Daisy:

Trying to run this script ( using Craftbukkit Beta build 1.7.2-RO.3, Citizens2 #1045, Denizen #1417, Sentry 1.8 ) and am seeing [null] for price and name of hireable guards. I only have essentials and vault running for testing the script.
2014-02-21 17:56:51 - Daisy:

Trying to run this script ( using Craftbukkit Beta build 1.7.2-RO.3, Citizens2 #1045, Denizen #1417, Sentry 1.8 ) and am seeing [null] for price and name of hireable guards. I only have essentials and vault running for testing the script.
2014-02-21 18:00:29 - Daisy:

Sorry for the triple post there. Reloaded the page.