(define-module (bonnie-bee boss) #:use-module (bonnie-bee actor) #:use-module (bonnie-bee assets) #:use-module (bonnie-bee bullet) #:use-module (chickadee audio) #:use-module (chickadee game-loop) #:use-module (chickadee graphics particles) #:use-module (chickadee math) #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (chickadee scripting) #:use-module (chickadee utils) #:use-module (oop goops) #:use-module (catbird asset) #:use-module (catbird node) #:use-module (catbird node-2d) #:export ()) (define-class ( ) (invincible? #:accessor invincible? #:init-value #t)) (define-method (on-boot (boss )) (attach-to boss (make #:atlas beetle-atlas #:origin (vec2 64.0 32.0) #:animations `((default . ,(make #:frames #(0 1) #:frame-duration 0.4)))))) (define-method (on-enter (boss )) (define (circle-shot n offset speed type) (let loop ((i 0)) (when (< i n) (let ((theta (+ (* (/ tau n) i) offset))) (add-bullet (& (parent boss) bullets) type (position boss) (vec2 (* (cos theta) speed) (* (sin theta) speed))) (loop (+ i 1)))))) (define (random-shot speed) (let ((theta (* (- pi) (random:uniform)))) (add-bullet (& (parent boss) bullets) medium-enemy-bullet (position boss) (vec2 (* (cos theta) speed) (* (sin theta) speed))))) (next-method) (run-script boss (sleep 5.0) (set! (invincible? boss) #f) (let ((big-speed 2.0) (little-speed 1.0)) (while (> (health boss) 800) (let ((d (direction-to boss (& (parent boss) player)))) (audio-play (artifact enemy-shoot-sound)) (add-bullet (& (parent boss) bullets) large-enemy-bullet (position boss) (vec2* d big-speed)) (let loop ((i 0)) (when (< i 16) (random-shot little-speed) (sleep (* (current-timestep) 2.0)) (loop (+ i 1))))))) (sleep 2.5) (let loop ((theta 0.0)) (unless (<= (health boss) 400) (audio-play (artifact enemy-shoot-sound)) (repeat 2 (random-shot 0.5)) (circle-shot 2 theta 1.5 large-enemy-bullet) (circle-shot 6 (- theta) 1.0 medium-enemy-bullet) (sleep (* (current-timestep) 10)) (loop (+ theta (/ pi 17.1))))) (sleep 2.5) (let loop ((theta 0.0)) (audio-play (artifact enemy-shoot-sound)) (circle-shot 10 (* theta 2.0) 1.5 large-enemy-bullet) (circle-shot 4 (- theta) 1.0 medium-enemy-bullet) (sleep (* (current-timestep) 10)) (loop (+ theta (/ pi 37.1)))))) (define-method (on-collide (boss ) (bullet )) (cond ((player-primary-bullet? bullet) (unless (invincible? boss) (damage boss 1)) (kill-bullet bullet) #t) ((player-bomb-bullet? bullet) (unless (invincible? boss) (damage boss 10)) (kill-bullet bullet)) (else #f))) (define-method (on-death (boss )) (audio-play (artifact explosion-sound)) (add-particle-emitter (particles (& (parent boss) particles)) (make-particle-emitter (world-hitbox boss) 20 30)))