Fishing Quest - Repeatable with Listener


Author: mythanical
Created: 2013-04-14T00:50:52-0400
Edited: 2014-01-12T03:31:37-0500
Denizen Version: 0.9.3
Views: 102
Downloads: 1693
Likes: 4


WGET
Description: Fishing Quest - Repeatable with Listener
Citizens 2 (build #1045)
Denizen 0.9.3 (build #1417)

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

Description:

This is a simple repeatable quest that requires the player to bring the Fisherman some..well, fish. What makes this script slightly different is the fact that the player doesn't have to return ALL the fish in one trip. Instead this script uses a counter, that will add into a flag the number of fish the player returns on each trip.

Once the player has brought back all the necessary fish the script will complete and can be repeated when the flag expires based on the time-out you've set.

One extra little feature is that the script uses a 'listener' to see if the player did in fact catch the fish themself. If they didn't catch all the fish, then during the reward stage they will be paid less based on the amount you specify in the 'FishCheatRewardQty' constant value.

NOTE: I use a female skin for this quest, so you may want to adjust dialog accordingly.

The SIT feature may not work currently:
Tip: Place the NPC next to a lake/pond, build a chair (wood slab), look at the chair and type '/npc sit -c'. Then look at where you want the NPC to cast their rod and type '/npc fish -c'. You toggle /npc lookclose' on and off to get them to face in the right direction.

# Fisherman Quest - Repeatable
# Citizens 2 (build #1045)
# Denizen 0.9.3 (build #1417)
#
# To assign to an NPC, type:
# /npc assign --set "fisherman"
#
# Description:
#
# This is a simple repeatable quest that requires the player to bring the Fisherman some..well, fish. What makes this
# script slightly different is the fact that the player doesn't have to return ALL the fish in one trip. Instead
# this script uses a counter, that will add into a flag the number of fish the player returns on each trip.
#
# Once the player has brought back all the necessary fish the script will complete and can be repeated when the flag expires
# based on the time-out you've set.
#
# One extra little feature is that the script uses a 'listener' to see if the player did in fact catch the fish them self.
# If they didn't catch all the fish, then during the reward stage they will be paid less based on the amount you
# specify in the 'FishCheatRewardQty' constant value.
#
# NOTE: The dialogue is based on a female NPC.
#
# Tip: Place the NPC next to a lake/pond, build a chair, look at the chair and type '/npc sit -c'. Then look at where you
#    want the NPC to cast their rod and type '/npc fish -c'. You toggle /npc lookclose' on and off to get them to face
#    in the right direction.
#
# @author mythanical
# @script version 0.8.4
# @last-updated 12 January 2014
# @irc EsperNet IRC Network #denizen-dev
# @Minecraft Server - minecraft.geek.nz

"Fisherman":
  type: assignment

  default constants:

    # Number of fish needed for the quest
    FishQty: 10
    # Money Reward Qty
    FishingRewardQty: 600
    # Reward amount if player cheated by not catching all the fish themselves.
    FishCheatRewardQty: 300
    # The time in between each repeat of the quest (currently set at 24 hours)
    # Just replace the 'h' with 'm' for minutes, 's' for seconds etc.
    Fishing Quest Repeat Timeout: 24h

  interact scripts:
  - 10 Catching Fish

  actions:
    on assignment:
    # These triggers enable interaction with an NPC via chatting, clicking and entering proximity.
    - trigger name:chat toggle:true
    - trigger name:click toggle:true
    - trigger name:proximity toggle:true
    # The NPC will equip a fishing rod.
    - equip i@fishing_rod

"Catching Fish":
  type: interact

  steps:
    1:
      proximity trigger:
        entry:
          script:
          # On player entering NPC proximity range, run a script. 
          # The default proximity range is set in Denizen\config.yml
          - ^run "Fisherman 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 "Fisherman Quest Requirement Check"

    2:
      chat trigger:
        'Start Questline':
          Trigger: /Yes/, I<&sq>ll go catch some fish for you!
          script:
          # If the player answer 'yes', this will set the quest flag to started and also start 'listening' for the player
          # catching fish. Once the player caught the number of fish specified in the constant (FishQty) at the top of the script, 
          # it will run the 'Finished Fishing' script.
          - flag <player> Fishing:Started
          - ^listen item "id:Fishing Listener" type:fish qty:<npc.constant[FishQty]> "script:Fishing Completion Reminder"
          - ^random {
            - chat "<yellow>Aww thank you, you<&sq>re so sweet! Please bring me <red><npc.constant[FishQty]><yellow> fish."
            - chat "<yellow>Yay! Thank you <white><player.name><yellow>! Please bring me <red><npc.constant[FishQty]><yellow> fish."
            - chat "<yellow>Wonderful! Please bring me <red><npc.constant[FishQty]><yellow> fish." }
          - narrate "<red> Fisherman - Quest Started"
          - ^zap step:1
        'Deny Questline':
          Trigger: /No/, I can<&sq>t be bothered with petty tasks like fishing. I<&sq>ve got monsters to slay!
          script:
          # If the player says 'no', then display one of the following 3 messages and put them back at Step 1 for
          # the 'Catching Fish' script.
          - random {
            - chat "<yellow>Oh.. ok then. I really thought you could.. oh nevermind."
            - chat "<yellow>Oh that is grea.. oh wait, you said <&sq>No<&sq>. I<&sq>ll be ok, I think."
            - chat "<yellow>Nevermind me, who am I anyway? You<&sq>ve got more important things to worry about." }
          - random {
            - narrate "<white><npc.name><red> starts crying softly."
            - narrate "<red>Tears start rolling down <aqua><npc.name><&sq>s <red>face."
            - narrate "<red>You hear quiet whimpering as you walk away from <aqua><npc.name><red>." }
          - ^zap step:1

        'What Did You Say':
          trigger: /REGEX:\w+/
          # This is a catch-all trigger that will repeat what the player said if what they
          # typed didn't match any of the chat triggers above.
          script:
          - chat "<yellow>Sorry <white><player.name><yellow>, but I don<&sq>t what <&sq><white><context.message><yellow><&sq> means."
          - ^narrate "<red>Say<&co>"
          - ^narrate "  <blue>Yes<blue> <gray>or<red> No"

      proximity trigger:
        exit:
          script:
          # If they exit the proximity trigger for the NPC, put them back at Step 1 so they get presented with the
          # relevant options when they come back later.
          - ^zap step:1

      click trigger:
        script:
        # This is simply to present the options again if the player accidently clicks the NPC rather than type a response.
        - ^run "Fisherman Quest Requirement Check"

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

  script:
  # The following options exist here
  # 1) If the value against the flag 'Fish' is 'Started', then ask user how the fishing is going.
  # 2) Else if the player has already done the quest and the timeout hasn't expired yet, simply chat something.
  # 3) Otherwise if no criteria is met, simply run the script called 'Fisherman General Chat'.
  - if <player.flag[Fishing]> == Started chat "<yellow>How is that fishing going?"
 
    else if <player.flag[Fishing]> == Claimed chat "<yellow>Thanks again for your help <yellow><player.name><yellow>!"
 
    else {
      - random {
        - chat "<yellow>Oh no no no, how am I going to get enough fish to the market in time?"
        - chat "<yellow>Why can<&sq>t people eat something else for a while? I can<&sq>t keep up with the demand."
        - chat "<yellow>Come on fishies! Take a bite!"
        - chat "<yellow>Oh that was a big one.. now, to make it bite."
        - chat "<yellow>That<&sq>s right fishies, grab onto that hook. You<&sq>ll be off to the market soon."
        - chat "<yellow>Stop hiding under that rock.. there is a nice juice worm on this hook waiting for you."
        - chat "<yellow>Arrg.. slow morning. The fish won<&sq>t seem to bite. I need help!"
        }
    }

"Fisherman Quest Requirement Check":
  type: task

  script:
  # The following options exist here:
  # 1) If the 'FishQuestCounter' is more or equal to the amount of fish the NPC wants AND the quest has in fact been started, then
  #  give the player their reward by running the 'Fishing Reward' script.
  # 2) Else if the quest is started and the player has some fish in their inventory, run the 'Fish Counter' script.
  # 3) Else if the quest is started, but the player doesn't have at least one fish in their inventory then tell the player how much
  #  they have brought. It gets the value from the 'FishQuestCounter' flag or if that doesn't exist, simply use the word 'no'.
  # 4) Else if the quest has been completed, tell them when to come back by using '.expiration' as part of the flag name. Displays like '20h 12m' for example.
  # 5) Else if the player has never done the quest OR the quest timeout has expired, then present them the fishing quest.
  - ^if <player.flag[FishQuestCounter]||0> >= <npc.constant[FishQty]> && <player.flag[Fishing]> == Started run "Fishing Reward"
    else if <player.flag[Fishing]> == Started && <player.inventory.contains[raw_fish]> run "Fish Counter"
    else if <player.flag[Fishing]> == Started chat "<yellow>You<&sq>ve brought me <white><player.flag[FishQuestCounter].asint || no><yellow> fish so far and I need <white><player.flag[FishCountLeft].asint || <npc.constant[FishQty]>><yellow> more before I<&sq>m off to the market!"
    else if <player.flag[Fishing]> == Claimed chat "<yellow>Thanks for your help <white><player.name><yellow>, I<&sq>ve got enough fish for now. Please come back in <red><player.flag[Fishing].expiration.formatted><yellow> to help me again."
    else run "Present Fishing Quest"

"Present Fishing Quest":
  type: task

  script:
  # This part presents the player with the quest, giving them some details via random dialog options
  # and then asks them to answer 'yes' or 'no' before 'zapping' to Step 2 in the script 'Catching Fish'
  # where it's waiting for the player to type something.
  - ^random {
    - ^chat "<yellow>Hello there <white><player.name><yellow>! Can you please help me catch some fish for the market?"
    - ^chat "<yellow>Oh hey <white><player.name><yellow>, they are waiting for more fish at the market and I don<&sq>t have enough time!"
    - ^chat "<yellow>Fish fish fish... I can<&sq>t keep up with the demand. Can you help me please?"
    - ^chat "<yellow>Oh no! Why don<&sq>t these fish bite? I<&sq>m running out of time! Please help me <white><player.name><yellow>."
    - ^chat "<yellow>When I took up this job, I thought it was going to be relaxing. I just can<&sq>t keep up. Help me?" }
  - random {
    - ^chat "<yellow>I will pay you <gold><npc.constant[FishingRewardQty]><yellow> <player.money.currency> if you catch <gray><npc.constant[FishQty]><yellow> fresh fish for me."
    - ^chat "<yellow>How does <gold><npc.constant[FishingRewardQty]><yellow> <player.money.currency> for catching <gray><npc.constant[FishQty]><yellow> fresh fish sound to you?"
    - ^chat "<yellow>The reward for catching <gray><npc.constant[FishQty]><yellow> fresh fish is <gold><npc.constant[FishingRewardQty]><yellow> <player.money.currency>. Interested?" }
  - ^narrate "<red>Say<&co>"
  - ^narrate "  <blue>Yes<blue> <gray>or<red> No"
  - ^zap step:2 "s@Catching Fish"

"Fishing Completion Reminder":
  type: task
  speed: 0

  script:
  # If the listener runs because the player caught enough fish, tell them to return to the NPC and set a flag to prove they did infact
  # catch all the fish themself. This flag is used later to determine how much the player should be rewarded.
  - ^narrate "<red>You should have caught enough fish by now to complete the <white>Fishing<red> Quest, that<&sq>s if you didn<&sq>t let any go. Return to <white><npc.name><red> for your reward."
  - ^flag <player> PlayerCaughtAllFish

"Fish Counter":
  type: task

  script:
  # The reason I use a 'count' script is so that the player has freedom in how much fish they bring back in each instance. So
  # they can bring back 1 at a time, or 5 at a time. It doesn't require the player to have ALL the fish in their inventory for
  # the script to progress.
  # ---------------------------------------------------------------------------------------------------------------------------
  # Count how much fish the player has in their inventory and put that value inside a flag called 'FishTempCount'
  - ^flag <player> FishTempCount:<player.inventory.qty[raw_fish]>

  # Then check if 'FishCountLeft' flag exists, if not create the flag and assign the 'FishQty' constant value to the flag.
  - ^if <player.flag[FishCountLeft]||0> == 0 flag <player> FishCountLeft:<npc.constant[FishQty]>

  # A quick IF statement then checks to see if the player has more fish in their inventory than what the NPC needs. If so, only take
  # however much is still needed. If they have less than what is needed, only take the quantity they have in their inventory.
  - ^if <player.inventory.qty[raw_fish]> >= <player.flag[FishCountLeft]> take i@raw_fish qty:<player.flag[FishCountLeft]>
    else take i@raw_fish qty:<player.flag[FishTempCount]>

  # Then subtract the fish count for this particular trip from the total remaining fish the NPC wants.
  - ^flag <player> FishCountLeft:-:<player.flag[FishTempCount]>

  # This flag does the opposite by instead storing the total count of fish that has been returned to the NPC. This provides
  # flexibility in dialog by being able to say how much the player has brought back or how much they still need to bring back.
  - ^flag <player> FishQuestCounter:+:<player.flag[FishTempCount]>

  # Now clear the flag for this trip, preparing it for the next time the player could return for a few fish.
  - ^flag <player> FishTempCount:!
 
  # If the player hasn't returned all the fish needed yet, tell them how much they've brought and how much they still need to bring.
  - ^if <player.flag[FishQuestCounter]> < <npc.constant[FishQty]> narrate "<red>You have brought <white><npc.name><red> a total of <gold><player.flag[FishQuestCounter].asint><red> fish, with <gold><player.flag[FishCountLeft].asint><red> remaining."
    else run "Fisherman Quest Requirement Check"

"Fishing Reward":
  type: task

  script:
  # The flag is set with a 'duration' of when it will expire and it determines when from the constant value called 'Fishing Quest Repeat Timeout' set
  # at the top of this script.
  - ^flag <player> Fishing:Claimed "duration:<npc.constant[Fishing Quest Repeat Timeout]>"
  - ^random {
     - ^chat "<yellow>You are a life saver <white><player.name><yellow>! You should come back later to help me again, if you can of course."
     - ^chat "<yellow>I can<&sq>t believe it <white><player.name><yellow>, I can fill my quota at the market today. Thank you!"
     - ^chat "<yellow>You<&sq>re my hero <white><player.name><yellow>. Please come help me again later and I<&sq>ll reward you." }
  # This IF statement checks to see if the 'PlayerCaughtAllFish' flag is true (so if the fishing 'listener' ran when the player caught their
  # fishing quantity) and reward them the full amount. Otherwise, only reward them with the amount set in the 'FishCheatRewardQty' constant value.
  - ^if <player.flag[PlayerCaughtAllFish]> give money qty:<npc.constant[FishingRewardQty]>
    else give money qty:<npc.constant[FishCheatRewardQty]>
  # The same if statement to decide which narrate the player gets depending on the 'PlayerCaughtAllFish' flag value.
  - ^if <player.flag[PlayerCaughtAllFish]> narrate "<red>You are rewarded <gold><npc.constant[FishingRewardQty]><red> <player.money.currency> for bringing <white><npc.name><red> fresh fish you caught yourself."
    else narrate "<red>You are only rewarded <gold><npc.constant[FishCheatRewardQty]><red> <player.money.currency> for bringing <white><npc.name><red> old fish you didn<&sq>t catch as part of this quest."
  # Run the script to reset all the relevant flags.
  - ^run "Reset Fishing Flags"
  - wait 2
  - narrate "<red> Fisherman - Quest Completed"

"Reset Fishing Flags":
  type: task

  script:
  # Clean-up all flags (except for 'Fishing') and reset listener so quest is ready again when the 'Claimed' value on flag 'Fishing' expires.
  - ^flag <player> PlayerCaughtAllFish:!
  - ^flag <player> FishQuestCounter:!
  - ^flag <player> FishTempCount:!
  - ^flag <player> FishCountLeft:!
  - ^listen cancel "id:Fishing Listener"




Comments
2013-07-20 04:53:49 - Tacoaloto:

I'm not sure what's going on but (1.6.2) the fisherman won't detect when I catch fish, and then the fish in my inventory doesn't become recognized by the npc either..
2013-08-02 09:30:08 - techrosis:

I'm having a similar issue since i upgraded to denizen 0.9.2....listener seems to be working...i get notified that i've caught 10 fish but then when i go to turn them in it says i haven't turned in any fish.....like i said it was working and the only thing that changed was the upgrade to denizen
2013-08-02 10:25:06 - techrosis:

I'm having a similar issue since i upgraded to denizen 0.9.2....listener seems to be working...i get notified that i've caught 10 fish but then when i go to turn them in it says i haven't turned in any fish.....like i said it was working and the only thing that changed was the upgrade to denizen
2013-08-02 22:39:19 - Daisy:

Seeing the same thing with players not being able to give the fish to the fisherman since updating to latest Denizen 0.9.2 and craftbukkit 1.6.2
2013-08-24 16:29:57 - mythanical:

I'm not sure whether the listener issue has been fixed yet but the one where it wasn't accepting the fish has!
2013-09-11 20:07:25 - Daisy:

Thank you! Appears to be working now!
2014-05-30 04:08:44 - graywolf336:

Went to test this but sadly when I give it one fish the server lags for a while and then it takes the fish and does the rest of the script.. Version: Denizen 0.9.4 (build 1473), Citizen 2.0.13 (build 1128)