Description: This is a proof of concept for having NPCs "go to sleep" at certain times of the Minecraft day. Forgive me if the syntax is a little strange, I've been learning as I go and there are a few things I'm still getting used to with dscript.
Note that I'm building my own list of "sleepable" NPCs by adding them to a global list on assignment and spawn, and then removing them from that list when they are removed. This has a heavy potential for getting messy so it may not be the best solution but as there is no current way to get a list of all NPCs through dScript it's the only one I've got.
Also thanks to Jeebiss for helping me fix a strange issue with the runtask command where using a flag with npcid: would result in the flag not parsing before the task is run. The fix for this is putting ^ before the flag which according to Jeebiss forces it to be parsed before the task is run.
Simply assign "sleep" to any NPC, and make sure to add a bed anchor. My next step will be to add alternate behavior when there's no bed assigned, such as walking to an inn or finding shelter.
Lastly: It's important that this is used with the most recent Denizen dev build. The PAUSE command I make use of in this was fixed earlier today, so having the latest build is necessary. There is also no UNPAUSE or RESUME command yet, which I get around by running a PAUSE DURATION:1 which initiates another pause but with a small duration so the pause ends itself allowing the NPC to continue what it was doing.
World Director:
type: world
events:
on 6:00 in world:
- flag global sleep:!
- runtask 'loop through' "context:sleep_loop|npcs|global"
on 19:00 in world:
- flag global sleep:true
- runtask 'loop through' "context:sleep_loop|npcs|global"
sleep_loop:
type: task
context: npc
script:
- runtask npcid:<^context.npc> sleep_handler
"Sleep":
type: assignment
default constants:
SleepCycle: true
actions:
on assignment:
- if !<flag.g:npcs.aslist> contains '<npc.id>' flag global "npcs:->:<npc.id>"
on spawn:
- if !<flag.g:npcs.aslist> contains '<npc.id>' flag global "npcs:->:<npc.id>"
on despawn:
- if <flag.g:npcs.aslist> contains '<npc.id>' flag global "npcs:<-:<npc.id>"
on remove:
- if <flag.g:npcs.aslist> contains '<npc.id>' flag global "npcs:<-:<npc.id>"
on complete navigation:
- if <flag.n:sleeping> == true execute as_npc "npc select <npc.id>"
- if <flag.n:sleeping> == true execute as_npc "npc sleep --anchor:bed"
sleep_handler:
type: task
script:
- if <cons:SleepCycle> == "false" queue clear
- if <flag.g:sleep> == true if !<flag.n:sleeping> pause waypoints
- if <flag.g:sleep> == true if !<flag.n:sleeping> walkto location:<anchor:bed>
- if <flag.g:sleep> == true if !<flag.n:sleeping> flag npc sleeping:true
- if <flag.n:sleeping> == true if !<flag.g:sleep> runtask 'unpause_waypoints' queue:unpause_queue
- if <flag.n:sleeping> == true if !<flag.g:sleep> flag npc sleeping:!
unpause_waypoints:
type: task
script:
- pause duration:1 waypoints
- wait duration:1