-(define-simple-actor <security-robot>
- ((begin-mission actor message)
- ;; used to track the current room / if any rooms are remaining
- (define room (message-ref message 'starting-room))
- (define overseer (message-ref message 'overseer))
-
- ;; Walk through all rooms, clearing out infected droids
- ;; Continue this whil there's still another room to investigate.
- (define response)
- (while room
- (send-message actor overseer
- 'transmission
- #:message (format #f "Entering room ~a..."
- (address-actor-id room)))
-
- ;; Find all droids in this room and exterminate the infected ones.
- (set! response (send-message-wait actor room 'list-droids))
- (for-each
- (lambda (droid-id)
- (cond
- ;; Looks like it's infected
- ((message-ref
- (send-message-wait actor droid-id
- 'infection-expose)
- 'is-infected)
- ;; Inform that it's infected
- (send-message actor overseer
- 'transmission
- #:message
- (format #f "~a found to be infected... taking out"
- (address-actor-id droid-id)))
-
- ;; Keep firing till it's dead.
- (let ((still-alive #t))
- (while still-alive
- (let ((response
- (send-message-wait actor droid-id 'get-shot)))
- (send-message actor overseer 'transmission
- #:message (droid-status-format response))
- (set! still-alive (message-ref response 'alive))))))
-
- ;; Not infected... inform and go to the next one
- (else
- (send-message actor overseer 'transmission
- #:message
- (format #f "~a is clean... moving on."
- (address-actor-id droid-id))))))
- (message-ref response 'droid-ids))
-
- ;; Switch to next room, if there is one.
- (set! room (message-ref
- (send-message-wait actor room 'get-next-room)
- 'id)))
-
- ;; Good job everyone! Shut down the operation.
- (send-message actor overseer 'transmission
- #:message "Mission accomplished.")))
+(define-actor <security-robot> (<actor>)
+ ((begin-mission security-robot-begin-mission)))
+
+(define* (security-robot-begin-mission actor message
+ #:key starting-room overseer)
+ ;; used to track the current room / if any rooms are remaining
+ (define room starting-room)
+
+ ;; Walk through all rooms, clearing out infected droids
+ ;; Continue this whil there's still another room to investigate.
+ (define response)
+ (while room
+ (<- overseer 'transmission
+ #:text (format #f "Entering room ~a..."
+ (address-actor-id room)))
+
+ ;; Find all droids in this room and exterminate the infected ones.
+ (let ((droid-ids (<-wait room 'list-droids)))
+ (for-each
+ (lambda (droid-id)
+ (cond
+ ;; Looks like it's infected
+ ((<-wait droid-id 'infection-expose)
+ ;; Inform that it's infected
+ (<- overseer 'transmission
+ #:text (format #f "~a found to be infected... taking out"
+ (address-actor-id droid-id)))
+
+ ;; Keep firing till it's dead.
+ (let ((still-alive #t))
+ (while still-alive
+ (call-with-values
+ (lambda () (<-wait droid-id 'get-shot))
+ (lambda* (#:key hp-left damage-taken alive)
+ (<- overseer 'transmission
+ #:text (droid-status-format droid-id alive damage-taken hp-left))
+ (set! still-alive alive))))))
+
+ ;; Not infected... inform and go to the next one
+ (else
+ (<- overseer 'transmission
+ #:text
+ (format #f "~a is clean... moving on."
+ (address-actor-id droid-id))))))
+ droid-ids))
+
+ ;; Switch to next room, if there is one.
+ (set! room (<-wait room 'get-next-room)))
+
+ ;; Good job everyone! Shut down the operation.
+ (<-wait overseer 'transmission
+ #:text "Mission accomplished.")
+ (<- overseer 'done!))