Paste #16561: Test2

Date: 2015/06/17 16:07:17 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924


################################################################################
#
#                         d  R  e  s  t  a  u  r  a  n  t
#                       For the real Restaurant experience!
#
#
#   Authors: |Anthony| calico-kid
#   Version: 0.2
#   dScript Version: 0.9.6-DEV_b111
#
#
#
#--- About this script
#
#  The dRestarunt system brings realistic NPC animated restaurants to Minecraft.
# Those with permissions can create new restaurants. Restaurants can be bought
# and sold, and Waitresses and Chefs can be employed and fired.
#
#  Restaurants must have properly built equipment for the NPCs to be able to do
# their jobs. NPCs will automagically navigate their environment. A list of
# equipment and building instructions will follow. Adding more equipment to your
# restaurant will unlock additional menu items.
#
#  You can create new menu items by creating a new dRestaurant_item script. Copy
# the provided template and build your "recipe" using the provided animations.
# dRestaurant will keep track of ingredient stock and equipment. If a menu item
# can't be made for whatever reason, it will be removed from the menu for that
# specific restaurant.
#
#  Each restaurant can have it's own menu. Restaurant owners are responsible for
# hiring chefs and waitresses, keeping raw materials stocked, building kitchen
# equipment, and creating their menus. Players can learn new menu items by
# buying a menu item from an existing restaurant and adding it to their menu.
# Server owned restaurants can add any menu item to any restaurant provided it
# has the correct equipment.
#
#
#--- Permissions
#
#  dRestaurant.admin   - Admin perm gives access to all commands and features.
#                      - Can manage all restaurants.
#  dRestaurant.create  - Can create new dRestaurants.
#  dRestaurant.delete  - Can delete dRestaurants you own.
#  dRestaurant.buy     - Can buy dRestaurants that are for sale.
#  dRestaurant.sell    - Can sell dRestaurants that you own.
#  dRestaurant.manage  - Can manage dRestaurants you have purchased.
#  dRestaurant.user    - General user permission to interact with dRestaurant NPCs
#
#
#--- Ticket System
#
#  The Ticket System is a single flag that holds all the ticket information for
# all restaurants. We're using <util.random.duuid> for our %ticketNumber% to
# avoid some silly incremental indexing method.
#
#  The server flag that holds the ticket info: <server.flag[dRestaurantTickets]>
#  It contains a list of lists and is structured like this:
#   - %ticketNumber%/%chef%/%waitress%/<player>/%foodItems%|...
#
#  To get a list of all ticket numbers:
#   - define ticketList <server.flag[dRestaurantTickets].get_sub_items[1].split_by[/]>
#
#  To get a specific ticket object all you need is the %ticketNumber%
#   - define tickets '<server.flag[dRestaurantTickets].as_list>'
#   - define ticket '<def[tickets].get[<def[tickets].get_sub_items[1].split_by[/].find[%ticketNumber%]>]>'
#
#  To get ticket details
#   - define ticketNumber '<def[ticket].split_by[/].get[1]>'
#   - define chef '<def[ticket].split_by[/].get[2].as_npc>'
#   - define waitress '<def[ticket].split_by[/].get[3].as_npc>'
#   - define player '<def[ticket].split_by[/].get[4].as_player>'
#   - define foodItems '<def[ticket].split_by[/].get[5].split_by[\]>'
#
#  To add a new ticket
#   - define ticketNumber '<util.random.duuid>'
#   - define chef ''
#   - define waitress ''
#   - define player ''
#   - define foodItems ''
#   - flag server dRestaurantTickets:->:%ticketNumber%/%chef%/%waitress%/<player>/%foodItems%
#
#  To remove an existing ticket use the %ticket% object as defined above
#   - flag server dRestaurantTickets:<-:%ticket%
#
#
#--- NPC Workflow
#    - For those that want to know and for me so I don't have to remember
#
#  A typical dRestaurant workflow can be outlined as such:
#
#  - Player gets menu from a waitress
#    - <player.flag[dRestaurant_Order]> now holds the name of the restaurant.
#
#  - Player selects items from menu and hits the Order Accept button
#    - <player.flag[dRestaurant_Order]> now has %restaurant%/<def[foodItems].as_list>
#    - flag player dRestaurant_Order_Placed:true
#      - Boolean check for getting and opening a menu.
#    - event "order placed" context:player|<player>
#
#  - Notify the least busy Waitress that a player has placed his order
#    - flag %waitress% dRestaurant_MenuQueue:->:<player>
#    - Check her status and collect menus if she's available
#
#  - Build a new ticket object for each food item the player ordered and notify
#    the kitchen.
#    - inject s@MasterWaitressNPC p:assignWaitress
#    - inject s@MasterWaitressNPC p:assignChef
#    - inject s@MasterWaitressNPC p:assignTicketNumber
#    - flag server dRestaurantTickets:->:%ticketNumber%/%chef%/%waitress%/<player>/%food%
#    - action "order in" %chef% context:ticket|%ticketNumber%
#
#  - Chef hears the order and decides what to do
#    - flag npc OrderQueue:->:%ticketNumber%
#    - If chef is available he'll run processOrderQueue
#    - If chef is busy he'll start cooking when he's not
#
#  - Chef completes cooking
#    - Deliver food to window
#    - flag npc OrderQueue:<-:%ticketNumber%
#    - event "order up" context:ticket|%ticketNumber%|displayItems|<def[displayItems].replace[li@].replace[|].with[/]>
#
#  - Notify the Waitress that an order is ready to be delivered to the player:
#    - flag npc TicketQueue:->:%ticketNumber%/<def[displayItems].as_list.replace[li@].replace[|].with[\]>
#    - If waitress is available she'll run processTicketQueue
#    - If waitress is busy she'll run processTicketQueue
#
#  - Deliver food to player
#    - Waitress walks to window, collects food, brings it to player
#    - flag npc TicketQueue:<-:%TicketQueueEntry%
#    - Remove ticket object from master ticket list
#      - flag server dRestaurantTickets:<-:%ticket%
#
#
################################################################################
#
#  dRestaurant World Script
#
#  This should cover all restaurant related world events. This is also the house
# for all of the equipment locators and the animations.
#
dRestaurant:
  type: world
  debug: false

#______________________________________
#--------------------------------------
#  DRESTAURANT EVENT HANDLERS
#
  events:
#
#--------------------------------------
#
#  dRestaurant Events
#
#    on server start:
#      - wait 2t
#      - define dRestaurants <server.list_flags[dRestaurant.].parse[split[.].get[1|2].replace[dRestaurant].with[cu@restaurant].replace[|].with[_].replace[li@].to_lowercase].deduplicate>
#      - if <def[dRestaurants].is_empty||true> queue clear
#      - define locs <def[dRestaurants].parse[list_partial_chunks.parse[cuboid.center].replace[li@]]||li@>
#      - foreach %locs% {
#        - chunkload add %value%
#        }
    on world loads:
      - wait 10s
      - define dRestaurants <server.list_flags[dRestaurant.].parse[split[.].get[1|2].replace[dRestaurant].with[cu@restaurant].replace[|].with[_].replace[li@].to_lowercase].deduplicate>
      - if <def[dRestaurants].is_empty||true> queue clear
      - define chunks <def[dRestaurants].parse[list_partial_chunks.replace[li@]]||li@>
      - define chunksWorld <def[chunks].filter[world.is[==].to[<c.world>]]||li@>
      - foreach %chunksWorld% {
        - chunkload add %value%
        - announce to_console "<&b>dRestaurant<&co> <&3>Loading chunk <&f><def[value]>"
        }

    on i@dRestaurant_Menu spawns:
      - determine CANCELLED

    on player drops i@dRestaurant_Menu:
      - determine CANCELLED

    on player exits notable cuboid:
      - if <c.cuboids.filter[notable_name.split[_].get[1].is[==].to[restaurant]].is_empty||true> queue clear
      - if !<player.has_flag[dRestaurant_Order]||false> queue clear
      - run s@dRestaurant p:exitCuboid

    on player consumes item:
      - if !<c.item.scriptname.split[_].get[1|2].contains[dRestaurant|Food]||false> queue clear
      - determine passively cancelled
      - take <c.item.simple> qty:1
      - narrate format:TBFormat "That was a tasty <c.item.display>"
      - define script '<c.item.scriptname.as_script>'
      - adjust <player> 'saturation:<player.saturation.add[<def[script].yaml_key[saturation]>]||<player.saturation>>'
      - adjust <player> 'food_level:<player.food_level.add[<def[script].yaml_key[foodLevel]>]||<player.food_level>>'
      - adjust <player> 'health:<player.health.add[<def[script].yaml_key[health]>]||<player.health>>'
      - foreach '<def[script].yaml_key[effects]||li@>' {
        - define potion '<def[value].split[/].as_list>'
        - cast '<def[potion].get[1]>' 'd:<def[potion].get[2]||20>s' 'p:<def[potion].get[3]||1>' <player>
        }

    # Custom event fired by the world script when a player places an order
    on order placed:
      # Define requisite data and do null check
      - define player '<c.player||null>'
      - define orderDetails <def[player].flag[dRestaurant_Order]||null>
      - define restaurant <def[orderDetails].split[/].get[1]||null>
      - define foodItems <def[orderDetails].split[/].get[2].as_list||null>
      - inject s@MasterWaitressNPC p:assignWaitress
      # This nullCheck should probably be written as a foreach to properly
      # handle definitions that contain lists
      - define nullCheck li@%player%|%orderDetails%|%restaurant%|%foodItems%|%waitress%
      - if <def[nullCheck].contains[null]> {
        - announce "<&b>dRestaurant<&co> <&c>Something went wrong on <&6>order placed<&c>!" to_console
        - announce "<&b>dRestaurant<&co> <&3>player<&co> <&b>%player%" to_console
        - announce "<&b>dRestaurant<&co> <&3>orderDetails<&co> <&b>%orderDetails%" to_console
        - announce "<&b>dRestaurant<&co> <&3>restaurant<&co> <&b>%restaurant%" to_console
        - announce "<&b>dRestaurant<&co> <&3>foodItems<&co> <&b>%foodItems%" to_console
        - announce "<&b>dRestaurant<&co> <&3>waitress<&co> <&b>%waitress%" to_console
        - queue clear
        }
      # Tell the least busy waitress to collect the menu. She'll decide when to
      # actually get the menu based on status.
      - flag %waitress% dRestaurant_MenuQueue:->:<player>
      # Each of the %foodItems% in an order is a unique %ticketNumber%. This
      # means that all work is evenly distributed amongst the restaurant staff.
      # We do one final null check before creating each ticket.
      - foreach %foodItems% {
        - define food '<def[value].split[,].get[1].as_item>'
        - inject s@MasterWaitressNPC p:assignChef
        - inject s@MasterWaitressNPC p:assignTicketNumber
        - if <el@val[%chef%|%ticketNumber%|%food%|%foodItems%].as_list.contains[null]> {
          - announce "<&b>dRestaurant<&co> <&c>Something went wrong on <&6>order placed<&c>!" to_console
          - announce "<&b>dRestaurant<&co> <&3>player<&co> <&b>%player%" to_console
          - announce "<&b>dRestaurant<&co> <&3>restaurant<&co> <&b>%restaurant%" to_console
          - announce "<&b>dRestaurant<&co> <&3>foodItem<&co> <&b>%food%" to_console
          - announce "<&b>dRestaurant<&co> <&3>foodItems<&co> <&b>%foodItems%" to_console
          - announce "<&b>dRestaurant<&co> <&3>chef<&co> <&b>%chef%" to_console
          - announce "<&b>dRestaurant<&co> <&3>ticketNumber<&co> <&b>%ticketNumber%" to_console
          - foreach next
         }
        - flag server dRestaurantTickets:->:%ticketNumber%/%restaurant%/%chef%/<player>/%food%
        - action "order in" %chef% context:ticket|%ticketNumber%
        - wait 10t
        }

    # Custom event fired by the chef when an order is ready for delivery
    on order up:
      # Define requisite data and do null check
      - define ticketNumber '<c.ticket||null>'
      - define displayItems '<c.displayItems.split_by[/]||null>'
      - define tickets '<server.flag[dRestaurantTickets].as_list||null>'
      - define ticket '<def[tickets].get[<def[tickets].get_sub_items[1].split_by[/].find[%ticketNumber%]>]||null>'
      - define restaurant '<def[ticket].split[/].get[2]||null>'
      - inject s@MasterWaitressNPC p:assignWaitress
      # This nullCheck should probably be written as a foreach to properly
      # handle definitions that contain lists
      - define nullCheck li@%ticketNumber%|%tickets%|%ticket%|%waitress%
      - if <def[nullCheck].contains[null]> {
        - announce "<&b>dRestaurant<&co> <&c>Something went wrong on <&6>order up<&c>!" to_console
        - announce "<&b>dRestaurant<&co> <&3>ticketNumber<&co> <&b>%ticketNumber%" to_console
        - announce "<&b>dRestaurant<&co> <&3>tickets<&co> <&b>%tickets%" to_console
        - announce "<&b>dRestaurant<&co> <&3>ticket<&co> <&b>%ticket%" to_console
        - announce "<&b>dRestaurant<&co> <&3>waitress<&co> <&b>%waitress%" to_console
        - queue clear
        }
      - flag %waitress% TicketQueue:->:%ticketNumber%/<def[displayItems].as_list.replace[li@].replace[|].with[\]||null>
      # Let the waitress decide what to do based on status
      - inject npc:%waitress% s@MasterWaitressNPC p:orderup_<def[waitress].flag[Status]||drunk>

    # There has to be a way to cancel an order /after/ it has been entered into
    # the ticket system if the chef detects missing equipment or ingredients,
    # or if a player action cancels the order (logout, exit restaurant, dies)
    on order canceled:
      - announce to_console "<&b>dRestaurant<&co> <&c><c.ticket> cancelled!"

#
#  END dRestaurant NPC events
#--------------------------------------
#
#  Cuboid Selection
#
    on player right clicks block with dRestaurantTool:
    - determine passively CANCELLED
    - if !<player.has_permission[dRestaurant.create]> {
      - take i@dRestaurantTool
      - run s@dRestaurantMsg 'def:<&4><&l>ERROR<&co><&r> <&a>You should not have this!' instantly
      - queue stop
      }
    - run s@dRestaurantMsg 'def:<&a>Set POS1 to <context.location.simple>'
    - flag player dRestaurantToolPOS1:<context.location>

    on player left clicks block with dRestaurantTool:
    - determine passively CANCELLED
    - if !<player.has_permission[dRestaurant.create]> {
      - take i@dRestaurantTool
      - run s@dRestaurantMsg 'def:<&4><&l>ERROR<&co><&r> <&a>You should not have this!' instantly
      - queue stop
      }
    - run s@dRestaurantMsg 'def:<&a>Set POS2 to <context.location.simple>' instantly
    - flag player dRestaurantToolPOS2:<context.location>

#
#  END Cuboid Selection
#--------------------------------------
#
#  NPC Spawn Eggs
#
    on player right clicks with i@chefegg:
      - create player chef712 <player.location.cursor_on.add[0.5,1,0.5]>
      - execute as_op "npc select"
      - assignment set script:MasterChefNPC npc:<player.selected_npc>
      - take i@chefegg
      - give i@waitressegg
      - flag player chef:<player.selected_npc>

    on player right clicks with i@waitressegg:
      - create player waitress <player.location.cursor_on.add[0.5,1,0.5]>
      - execute as_op "npc select"
      - assignment set script:waitress npc:<player.selected_npc>
      - take i@waitressegg
      - flag <player.selected_npc> chef:<player.flag[chef]>

#
#  END NPC Spawn Eggs
#--------------------------------------
#
#  Logic
#
# A place for some logic stuff
#
#
  exitCuboid:
    - ^define restaurant <player.flag[dRestaurant_Order].split[/].get[1]||null>
    - ^run s@dRestaurantMsg 'def:<&b>Get back to <&f>%restaurant%<&b> before the time runs out!' instantly
    - ^wait 1t
    - ^repeat 5 {
      - define inRestaurant '<player.location.cuboids.filter[notable_name.is[==].to[restaurant_%restaurant%]]||li@>'
      - if !<def[inRestaurant].is_empty||true> {
        - define msg '<&f>You made it back in time!'
        - adjust <player> 'show_boss_bar:200|%msg%'
        - playsound <player> 'sound:note_pling' 'pitch:1.3'
        - wait 1s
        - adjust <player> 'show_boss_bar'
        - queue stop
        }
      - define counter '<el@val[6].sub[%value%].as_int||0>'
      - define bar '<def[counter].mul[40].as_int||0>'
      - define msg '<&c>Order Canceling in<&co> <&6>%counter%'
      - adjust <player> 'show_boss_bar:%bar%|%msg%'
      - playsound <player> 'sound:note_pling' 'pitch:1.3'
      - wait 1s
      }

    - ^define inRestaurant <player.location.cuboids.filter[notable_name.is[==].to[restaurant_%restaurant%]]||li@>
    - ^if !<def[inRestaurant].is_empty||true> {
        - define msg '<&f>You barely made it back in time!'
        - adjust <player> 'show_boss_bar:200|%msg%'
        - playsound <player> 'sound:note_pling' 'pitch:1.3'
        - wait 1t
        - adjust <player> 'show_boss_bar'
        - queue stop
      }
      else {
      - define msg '<&c>Your Order is Canceled!'
      - adjust <player> 'show_boss_bar:0|%msg%'
      - playsound <player> 'sound:note_pling' 'pitch:0.3'
      - flag player dRestaurant_Order:!
      - run s@dRestaurantMenu p:takeMenu instantly
      - narrate format:TBFormat "I didn<&sq>t need that anyway..."
      - wait 1t
      - adjust <player> 'show_boss_bar'
      - queue clear
      }
    }
#
#
#  END DRESTAURANT EVENT HANDLERS
#______________________________________
#--------------------------------------
#
#  Animations
#
# These are the animations we provide to the end users. All they have to do is
# inject them from their recipe scripts and have the right definitions available
#
#  TODO
#
#    - Figure out a way to have unattended cooking operations
#    - Add a cookTime option to baking
#    - Animations for any new equipment
#
#
#-----------------------
#  Chef Specific Animations
#
  getFood_FancyFridge:
  # Walk to the FancyFridge and get the %foodItems%
    - ^inject s@dRestaurant_Equipment_FancyFridge instantly
    - ^define destination '<def[locations].random>'
    - ^define door '<def[destination].split[/].get[2].as_location>'
    - ^lookclose state:true
    - ~walk auto_range %door% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> '<def[destination].split[/].get[1].as_location>'
    - ^playsound %door% sound:door_open
    - ^animate <npc> animation:ARM_SWING
    - ^switch %door% state:toggle
    - ^wait 15t
    - foreach %foodItems% {
      - animate <npc> animation:ARM_SWING
      - equip <npc> hand:<def[value].as_item>
      - wait 15t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^switch %door% state:toggle
    - ^playsound %door% sound:door_close
    - ^wait 10t

  getFood_BasicFridge:
  # Walk to the BancyFridge and get the %foodItems%
    - ^inject s@dRestaurant_Equipment_BasicFridge instantly
    - ^define destination '<def[locations].random>'
    - ^define door '<def[destination].split[/].get[2].as_location>'
    - ^lookclose state:true
    - ~walk auto_range %door% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> '<def[destination].split[/].get[1].as_location>'
    - ^playsound %door% sound:door_open
    - ^animate <npc> animation:ARM_SWING
    - ^switch %door% state:toggle
    - ^wait 15t
    - foreach %foodItems% {
      - animate <npc> animation:ARM_SWING
      - equip <npc> hand:<def[value].as_item>
      - wait 15t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^switch %door% state:toggle
    - ^playsound %door% sound:door_close
    - ^wait 10t

  washFood:
  # Walk to sink and wash the %foodItems%
    - ^inject s@dRestaurant_Equipment_Sink instantly
    - ^define destination '<def[locations].random>'
    - ^define sinkLoc '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %sinkLoc%
    - ^wait 5t
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:SNEAK
    - ^animate <npc> animation:ARM_SWING
    - ^playsound %sinkLoc% sound:splash2
    - ^define displayItems li@
    - ^foreach %foodItems% {
      - displayitem <def[value].as_item> '%sinkLoc%' save:displayItem_%loop_index%
      - define displayItems '<def[displayItems].include[<entry[displayItem_%loop_index%].dropped>]>'
      }
    - ^foreach %foodItems% {
      - define food <def[value].as_item>
      - ^repeat 5 {
        - equip <npc> hand:%food%
        - animate <npc> animation:ARM_SWING
        - playsound %sinkLoc% sound:swim
        - wait <util.random.int[5].to[15]>t
        }
      }
    - ^playsound %sinkLoc% sound:splash2
    - ^animate <npc> animation:STOP_SNEAKING
    - ^remove %displayItems%
    - ^animate <npc> animation:ARM_SWING
    - equip <npc> hand:<def[foodItems].random.as_item>
    - ^wait 10t

  prepFood:
  # Walk to prep area and prep the %foodItems%
    - ^inject s@dRestaurant_Equipment_Prep instantly
    - ^define destination '<def[locations].random>'
    - ^define prepLoc '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %prepLoc%
    - ^animate <npc> animation:SNEAK
    - ^animate <npc> animation:ARM_SWING
    - equip <npc> hand:<i@air>
    - ^define displayItems li@
    - ^foreach %foodItems% {
      - displayitem <def[value].as_item> '%prepLoc%' save:displayItem_%loop_index%
      - define displayItems '<def[displayItems].include[<entry[displayItem_%loop_index%].dropped>]>'
      }
    - ^repeat 5 {
      - animate <npc> animation:ARM_SWING
      - ^define sound 'li@step_ladder|lava_pop'
      - playsound %prepLoc% sound:<def[sound].random>
      - wait 5t
      }
    - ^remove %displayItems%
    - ^animate <npc> animation:STOP_SNEAKING
    - equip <npc> hand:<def[foodItems].random.as_item>
    - ^wait 10t

  bakeFood_Attended:
  # Walk to oven and bake the %foodItem%
  # Items should be baked one at a time in my opinion, but idk.
    - ^inject s@dRestaurant_Equipment_Oven instantly
    - ^define destination '<def[locations].random>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^define furnace '<def[destination].split[/].get[1].as_location>'
    - ^look <npc> %furnace%
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:ARM_SWING
    - ^wait 5t
    - ^playsound %furnace% sound:ghast_fireball
    - ^showfake m@burning_furnace,<def[furnace].material.data> %furnace% to:<def[furnace].find.players.within[10]> d:200t
    - ^repeat 20 {
      - ^define sound 'li@fuse|fire.random|fire.random|fire.random'
      - ^playsound %furnace% sound:<def[sound].random>
      - ^wait 5t
      }
    - ^animate <npc> animation:ARM_SWING
    - equip <npc> hand:%foodItem%
    - ^wait 10t

  bakeFood_Unattended:
  # Walk to oven and start cooking.
    - ^inject s@dRestaurant_Equipment_Oven instantly
    - ^define destination '<def[locations].random>'
    - ^define furnace '<def[destination].split[/].get[1].as_location>'
    - ^define walkLoc '<def[destination].split[/].get[2].as_location>'
    - ^lookclose state:true
    - ~walk auto_range %walkLoc% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %furnace%
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:ARM_SWING
    - ^wait 5t
    - ^playsound %furnace% sound:ghast_fireball
    - ^modifyblock %furnace% m@burning_furnace,<def[furnace].material.data> no_physics
    - ^run locally bakeFood_Unattended_Cooking def:%ticketNumber%|%furnace%|%walkLoc%|%cookTime%|%cookedFood%

  bakeFood_Unattended_Cooking:
  # This is the part of the animation that is done without the NPC
    - define ticketNumber %1%
    - define furnace %2%
    - define walkLoc %3%
    - define cookTime %4%
    - define cookedFood %5%
    # Default (fallback) cook time of 30 seconds
    - ^define finishTime <def[cookTime].mul[1000].add_int[<server.current_time_millis>]||<server.current_time_millis.add_int[30000]>>
    # This method provides AT LEAST a 90 second max cook time. The longest
    # possible cook time is 270 seconds. There's a bit of randomness to this
    # though since the wait time between iterations is random. Animation will
    # stop regardless of the actual cook time after 360 iterations.
    - ^repeat 360 {
      - if <def[finishTime].is[LESS].than[<server.current_time_millis>]> repeat stop
      - ^define sound 'li@fuse|fire.random|fire.random'
      - ^playsound %furnace% sound:<def[sound].random>
      - ^wait <util.random.int[5].to[15]>t
      }
    - ^action "cook complete" context:ticket|%ticketNumber%|equipmentLoc|%furnace%|walkLoc|%walkLoc%|displayEntity|null|cookedFood|%cookedFood%

  bakeFood_Unattended_Get:
  # This is triggered from the cook complete action
    - ^lookclose state:true
    - ~walk auto_range %walkLoc% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %equipmentLoc%
    - ^animate <npc> animation:ARM_SWING
    - equip <npc> hand:%cookedFood%
    - ^modifyblock %equipmentLoc% m@furnace,<def[equipmentLoc].material.data> no_physics
    - ^wait 10t

  grillFood_Attended:
  # Walk to grill and cook %rawFood% into %cookedFood%
    - ^inject s@dRestaurant_Equipment_Grill instantly
    - ^define destination '<def[locations].random>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^define grill '<def[destination].split[/].get[1].as_location>'
    - ^look <npc> %grill%
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:ARM_SWING
    - ^wait 5t
    - ^playsound %grill% sound:ghast_fireball
    - ^displayitem <def[rawFood].as_item> '%grill%' d:300s save:rawFood
    # Default (fallback) cook time of 30 seconds
    - ^define finishTime <def[cookTime].mul[1000].add_int[<server.current_time_millis>]||<server.current_time_millis.add_int[30000]>>
    # This method provides AT LEAST a 90 second max cook time. The longest
    # possible cook time is 270 seconds. There's a bit of randomness to this
    # though since the wait time between iterations is random. Animation will
    # stop regardless of the actual cook time after 360 iterations.
    - ^repeat 360 {
      - if <def[finishTime].is[LESS].than[<server.current_time_millis>]> repeat stop
      - ^define sound 'li@fuse|fuse|fire.random'
      - ^playsound %grill% sound:<def[sound].random>
      - ^if <util.random.int[1].to[10].is[OR_MORE].than[7]> animate <npc> animation:ARM_SWING
      - ^if <util.random.int[1].to[10].is[OR_MORE].than[4]> playeffect %grill% effect:smoke qty:1 data:4
      - ^wait <util.random.int[5].to[15]>t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^remove <entry[rawFood].dropped>
    - ^displayitem <def[cookedFood].as_item> '%grill%' d:30s save:cookedFood
    - ^repeat 3 {
      - ^define sound 'li@fuse|fuse|fire.random'
      - ^playsound %grill% sound:<def[sound].random>
      - ^playeffect %grill% effect:smoke qty:1 data:4
      - ^wait 15t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^remove <entry[cookedFood].dropped>
    - equip <npc> hand:%cookedFood%
    - ^wait 10t

  boilFood_Attended:
  # Walk to stove and cook %rawFood% into %cookedFood%
    - ^inject s@dRestaurant_Equipment_Stove instantly
    - ^define destination '<def[locations].random>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^define stove '<def[destination].split[/].get[1].as_location>'
    - ^look <npc> %stove%
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:ARM_SWING
    - ^wait 5t
    - ^playsound %stove% sound:ghast_fireball
    - ^modifyblock %stove% m@burning_furnace,<def[stove].material.data> no_physics
    - ^displayitem <def[rawFood].as_item> '%stove%' d:300s save:rawFood
    # Default (fallback) cook time of 30 seconds
    - ^define finishTime <def[cookTime].mul[1000].add_int[<server.current_time_millis>]||<server.current_time_millis.add_int[30000]>>
    # This method provides AT LEAST a 90 second max cook time. The longest
    # possible cook time is 270 seconds. There's a bit of randomness to this
    # though since the wait time between iterations is random. Animation will
    # stop regardless of the actual cook time after 360 iterations.
    - ^repeat 360 {
      - if <def[finishTime].is[LESS].than[<server.current_time_millis>]> repeat stop
      - ^define sound 'li@fuse|lava|fire.random'
      - ^playsound %stove% sound:<def[sound].random>
      - ^if <util.random.int[1].to[10].is[OR_MORE].than[7]> animate <npc> animation:ARM_SWING
      - ^if <util.random.int[1].to[10].is[OR_MORE].than[4]> playeffect %stove% effect:mob_spell qty:10 data:0.2 offset:0.2
      - ^wait <util.random.int[5].to[15]>t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^remove <entry[rawFood].dropped>
    - ^displayitem <def[cookedFood].as_item> '%stove%' d:30s save:cookedFood
    - ^repeat 3 {
      - ^define sound 'li@fuse|lava|fire.random'
      - ^playsound %stove% sound:<def[sound].random>
      - ^playeffect %stove% effect:smoke qty:1 data:4
      - ^wait 15t
      }
    - ^animate <npc> animation:ARM_SWING
    - ^remove <entry[cookedFood].dropped>
    - equip <npc> hand:%cookedFood%
    - ^modifyblock %stove% m@furnace,<def[stove].material.data> no_physics
    - ^wait 10t

  boilFood_Unattended:
  # Walk to stove and start cooking.
    - ^inject s@dRestaurant_Equipment_Stove instantly
    - ^define destination '<def[locations].random>'
    - ^define stove '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ^define walkLoc '<def[destination].split[/].get[2].as_location>'
    - ^lookclose state:false
    - ~walk auto_range %walkLoc% speed:<def[speed].add[0.1].as_money||0.8>
    - ^look <npc> %stove%
    - equip <npc> hand:<i@air>
    - ^animate <npc> animation:ARM_SWING
    - ^wait 5t
    - ^playsound %stove% sound:ghast_fireball
    - ^modifyblock %stove% m@burning_furnace,<def[stove].material.data> no_physics
    - ^displayitem <def[rawFood].as_item> '%stove%' d:300s save:rawFood
    - ^run locally boilFood_Unattended_Cooking def:%ticketNumber%|%stove%|%walkLoc%|<entry[rawFood].dropped>|%cookTime%|%cookedFood%

  boilFood_Unattended_Cooking:
  # This is the part of the animation that is done without the NPC
    - define ticketNumber %1%
    - define stove %2%
    - define walkLoc %3%
    - define rawDisplay %4%
    - define cookTime %5%
    - define cookedFood %6%
    # Default (fallback) cook time of 30 seconds
    - ^define finishTime <def[cookTime].mul[1000].add_int[<server.current_time_millis>]||<server.current_time_millis.add_int[30000]>>
    # This method provides AT LEAST a 90 second max cook time. The longest
    # possible cook time is 270 seconds. There's a bit of randomness to this
    # though since the wait time between iterations is random. Animation will
    # stop regardless of the actual cook time after 360 iterations.
    - ^repeat 360 {
      - if <def[finishTime].is[LESS].than[<server.current_time_millis>]> repeat stop
      - ^define sound 'li@fuse|lava|fire.random'
      - ^playsound %stove% sound:<def[sound].random>
      - ^if <util.random.int[1].to[10].is[OR_MORE].than[4]> playeffect %stove% effect:mob_spell qty:10 data:0.2 offset:0.2
      - ^wait <util.random.int[5].to[15]>t
      }
    - ^remove %rawDisplay%
    - ^displayitem <def[cookedFood].as_item> '%stove%' d:30s save:cookedFood
    - ^repeat 3 {
      - ^define sound 'li@fuse|lava|fire.random'
      - ^playsound %stove% sound:<def[sound].random>
      - ^playeffect %stove% effect:smoke qty:1 data:4
      - ^wait 15t
      }
    - ^action "cook complete" context:ticket|%ticketNumber%|equipmentLoc|%stove%|walkLoc|%walkLoc%|displayEntity|<entry[cookedFood].dropped>|cookedFood|%cookedFood%

  boilFood_Unattended_Get:
  # This is triggered from the cook complete action
    - ^lookclose state:true
    - ~walk auto_range %walkLoc% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %equipmentLoc%
    - ^animate <npc> animation:ARM_SWING
    - ^remove %displayEntity%
    - equip <npc> hand:%cookedFood%
    - ^modifyblock %equipmentLoc% m@furnace,<def[equipmentLoc].material.data> no_physics
    - ^wait 10t

  deliverFood_chef:
  # Walk to the window and deliver the %foodItems%
    - ^inject s@dRestaurant_Equipment_ChefWindow instantly
    - ^define destination '<def[locations].random>'
    - ^define windowLoc '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %windowLoc%
    - equip <npc> hand:<i@air>
    - ^define displayItems li@
    - ^foreach %foodItems% {
      - displayitem <def[value].as_item> '%windowLoc%' d:30s save:displayItem_%loop_index%
      - define displayItems '<def[displayItems].include[<entry[displayItem_%loop_index%].dropped>]>'
      }
    - ^narrate "Order up!" 'targets:<npc.location.find.players.within[3]>' format:GenericNPCFormat
    - ^event "order up" context:ticket|%ticketNumber%|displayItems|<def[displayItems].replace[li@].replace[|].with[/]>


#-----------------------
#  Waitress Specific Animations
#
  deliverFood_waitress:
  # Walk to window, collect the %foodItems%, and deliver them to the player.
  # Currently using a simple walkto command. This may lead to table dancers.
    # Find the window and walk to it
    - ^inject s@dRestaurant_Equipment_WaitressWindow instantly
    - ^define destination '<def[locations].random>'
    - ^define windowLoc '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range '<def[destination].split[/].get[2].as_location>' 'speed:<def[speed].add[0.1].as_money||0.8>'
    - ^lookclose state:false
    - ^look <npc> %windowLoc%
    - ^wait 10t
    # Pickup the food. This means we need to store the entity id for the display items
    - ^remove %displayItems%
    - equip <npc> hand:<def[foodItems].random.as_item>
    - ^wait 10t
    - ^lookclose state:true
    - ^if <def[player].is_online>
      && <def[player].location.is_within[cu@restaurant_%restaurant%]||false> {
      - follow target:%player%
      - inject locally followPlayer_waitress
      - follow stop target:%player%
      - wait 10t
      - animate <npc> animation:arm_swing
      - playsound <def[player].location> sound:silverfish_walk pitch:0.3
      - playsound <def[player].location> sound:step_grass pitch:0.7
      }
    - ^give player:%player% %foodItems%
    - equip <npc> hand:i@air
    - ^narrate format:GenericNPCFormat "Here is your <def[foodItems].parse[display].as_list.formatted>" target:%player%

  followPlayer_waitress:
    - ^wait 1s
    - ^define counter <def[counter].add[1]||0>
    - ^if <npc.is_spawned||false>
      && <def[player].is_online||false>
      && <def[counter].is[OR_LESS].than[9]||false>
      && <def[player].location.distance[<npc.location>].is[MORE].than[3]||false>
      && <def[player].location.is_within[cu@restaurant_%restaurant%]||false>
      && <npc.location.is_within[cu@restaurant_<def[restaurant]||null>]||false>
      && <el@val[<npc.flag[Status].is[==].to[order]||false>].or[<npc.flag[Status].is[==].to[deliver]||false>]||false> {
      - inject locally followPlayer_waitress
      }
      else follow stop target:%player%

  idleQueue_Waitress_Fidget:
    - ^if <util.random.int[1].to[100].is[OR_MORE].than[99]> {
      - random {
        - narrate format:GenericNPCFormat "We<&sq>ve got the best food!" targets:<npc.location.find.players.within[5]||null>
        - narrate format:GenericNPCFormat "Our chefs were trained by the finest programmers!" targets:<npc.location.find.players.within[5]||null>
        - narrate format:GenericNPCFormat "I hope you enjoy your meal." targets:<npc.location.find.players.within[5]||null>
        - narrate format:GenericNPCFormat "You can watch the Chefs do what they do best!" targets:<npc.location.find.players.within[5]||null>
        - narrate format:GenericNPCFormat "Enjoy your stay!" targets:<npc.location.find.players.within[5]||null>
        }
      }
    - ^define fidgetLocation '<def[fidgetValues].get[5]||<npc.location>>'
    - ^define fidgetHeight '<def[fidgetValues].get[6]||1>'
    - ^define pathMaterial '<def[fidgetValues].get[7].split_by[/]||cobblestone|coal_block|cobblestone_stairs>'
    - ^define target '<cu@restaurant_%restaurant%.get_spawnable_blocks[%pathMaterial%].filter[distance[<npc.location>].is[OR_LESS].than[%range%]].filter[distance[%fidgetLocation%].vertical.is[OR_LESS].than[%fidgetHeight%]].random||%fidgetLocation%>'
    - ~walk auto_range %target% speed:%speed%
#    - ^repeat 5 {
#      - define target '<cu@restaurant_%restaurant%.get_spawnable_blocks[%pathMaterial%].random||null>'
#      - if <def[target].distance[%fidgetLocation%].vertical.is[OR_LESS].than[%fidgetHeight%]>
#        && <def[target].distance[<npc.location>].is[OR_LESS].than[%fidgetRadius%]> {
#        - ~walk auto_range %target% speed:%speed%
#        - repeat stop
#        }
#      }


#
#  END Animations
#-----------------------
#
#  Chef Idle Mechanics
#
  idleQueue_Chef:
    - ^if !<npc.is_spawned||false> queue clear
    - ^flag npc Status:idle
    - ^lookclose state:true
    - ^if <queue.exists[processOrder_<npc.id>]||false> queue queue:processOrder_<npc.id> stop
    - ^define fidgetValues '<npc.flag[dRestaurant_FidgetValues].as_list||null>'
    - ^define list li@55/Fidget|15/DishWashing|15/PrepCleaning|15/GrillCleaning
    - ^inject s@WeightedRandomChoice p:asDef instantly
    - ^define restaurant '<def[fidgetValues].get[1]||null>'
    - ^define range '<def[fidgetValues].get[3]||30>'
    - ^define speed '<def[fidgetValues].get[4]||0.7>'
    - ^inject locally idleQueue_Chef_%result%
    - ^define wait '<def[fidgetValues].get[2]||10>'
    - ^wait <util.random.int[<def[wait].mul[0.5].as_int>].to[<def[wait].mul[1.5].as_int>]>s
    - ^if <queue.exists[processOrder_<npc.id>]||false> queue queue:processOrder_<npc.id> stop
    - ^run s@MasterChefNPC p:processOrderQueue id:processOrder_<npc.id> delay:2t
    - ^queue clear

  idleQueue_Chef_Fidget:
#    - ^narrate format:GenericNPCFormat "Just walking around..." 'targets:<npc.location.find.players.within[5]>'
    - ^define fidgetLocation '<def[fidgetValues].get[5]||npc.location>'
    - ^define fidgetHeight '<def[fidgetValues].get[6]||1>'
    - ^define pathMaterial '<def[fidgetValues].get[7].split_by[/]||cobblestone|coal_block|cobblestone_stairs>'
    - ^repeat 5 {
      - define target '<cu@restaurant_%restaurant%.get_spawnable_blocks[%pathMaterial%].random||null>'
#      - define target '<def[fidgetLocation].as_location.find.surface_blocks[<def[pathMaterial]>].within[<def[range]>].random>'
      - if <def[target].distance[%fidgetLocation%].vertical.is[OR_LESS].than[%fidgetHeight%]> {
        - ~walk auto_range %target% speed:%speed%
        - repeat stop
        }
      }

  idleQueue_Chef_DishWashing:
  # washing dishes in prep for customers
    - ^narrate format:GenericNPCFormat "Time to wash some dishes." 'targets:<npc.location.find.players.within[5]>'
    - ^define fooditems li@bowl|wood_plate
    - inject locally washfood
    - inject locally prepFood
    - ^lookclose state:true
    - equip <npc> hand:i@air

  idleQueue_Chef_PrepCleaning:
    - ^narrate format:GenericNPCFormat "I<&sq>m going to clean the prep station." 'targets:<npc.location.find.players.within[5]>'
    - ^inject s@dRestaurant_Equipment_prep
    - ^define destination '<def[locations].random>'
    - ^define prepstand '<def[destination].split[/].get[2].as_location>'
    - ^define prep '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range %prepstand% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %prep%
    - equip <npc> hand:i@potion,16388
    - wait 1s
    - ^playeffect %prep% effect:snow_shovel qty:2
    - playsound <npc.location> sound:fuse pitch:2
    - ^playeffect %prep% effect:snow_shovel qty:2
    - playsound <npc.location> sound:fuse pitch:2
    - equip <npc> hand:i@red_carpet
    - ^animate <npc> animation:arm_swing
    - playsound <npc.location> sound:step_wood pitch:-1
    - ^animate <npc> animation:arm_swing
    - playsound <npc.location> sound:step_wood pitch:-1
    - wait 1s
    - ^playeffect %prep% effect:fireworks_spark qty:5
    - ^playsound <npc.location> sound:level_up pitch:-1
    - ^lookclose state:true
    - equip <npc> hand:i@air

  idleQueue_Chef_GrillCleaning:
    - narrate format:GenericNPCFormat "That grill needs a good cleaning!" 'targets:<npc.location.find.players.within[5]>'
    - ^inject s@dRestaurant_Equipment_Grill
    - ^define destination '<def[locations].random>'
    - ^define grillpad'<def[destination].split[/].get[2].as_location>'
    - ^define grill '<def[destination].split[/].get[1].as_location>'
    - ^lookclose state:true
    - ~walk auto_range %grillpad% speed:<def[speed].add[0.1].as_money||0.8>
    - ^lookclose state:false
    - ^look <npc> %grill%
    - equip <npc> hand:i@potion,16388
    - wait 1s
    - ^playeffect %grill% effect:snow_shovel qty:2
    - playsound <npc.location> sound:fuse pitch:2
    - ^playeffect %grill% effect:snow_shovel qty:2
    - playsound <npc.location> sound:fuse pitch:2
    - equip <npc> hand:i@red_carpet
    - ^animate <npc> animation:arm_swing
    - playsound <npc.location> sound:fizz pitch:2
    - ^animate <npc> animation:arm_swing
    - playsound <npc.location> sound:fizz pitch:2
    - wait 1s
    - ^playeffect %grill% effect:fireworks_spark qty:5
    - ^playsound <npc.location> sound:level_up pitch:-1
    - ^lookclose state:true
    - equip <npc> hand:i@air

#
#  END Chef Idle Mechanics
#-----------------------
#
#
#
#  END DRESTAURANT WORLD SCRIPT
#______________________________________
#-------------------------------------