Add electron warp terminals.

This commit is contained in:
David Thompson 2024-05-22 12:35:56 -04:00
parent 747a1d285a
commit 9b88cb19c0
6 changed files with 154 additions and 22 deletions

View file

@ -13,6 +13,7 @@
^xor-gate
^or-gate
^electric-switch
^electron-warp
^player
^level))
@ -31,9 +32,6 @@
((new-val)
(bcom (^cell bcom new-val)))))
;; TODO: Add layer info to 'describe' output for sorting sprites when
;; rendering.
;; TODO: Port actor-lib methods and use it.
(define (^exit bcom x y)
(define position (vector x y 1))
@ -211,6 +209,47 @@
(('describe) `(electric-switch ,position ,($ on?)))
(('collide other offset grid-info) #f)))
(define (^electron-warp bcom x y target-x target-y)
(define position (vector x y 0))
(define state (spawn ^cell 'copper))
(define electron? (spawn ^cell))
(define (find-receiver grid-info)
(let lp ((objs ($ grid-info 'occupants target-x target-y)))
(match objs
(() (error "no electron receiver at tile" target-x target-y))
((obj . rest)
(if (eq? ($ obj 'type) 'electron-warp)
obj
(lp rest))))))
(match-lambda*
(('type) 'electron-warp)
(('position) position)
(('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f)
(('exit obj grid-info) #f)
(('wire-state grid-info) ($ state))
(('update-wire-state grid-info)
(match ($ state)
('electron-head ($ state 'electron-tail))
('electron-tail ($ state 'copper))
('copper
(if ($ electron?)
(begin
($ state 'electron-head)
($ electron? #f))
(let ((neighbors ($ grid-info 'wireworld-neighbor-count x y)))
(if (<= 1 neighbors 2)
(begin
($ state 'electron-head)
;; Forward an electron head to the receiver.
($ (find-receiver grid-info) 'give-electron))
($ state 'copper)))))))
(('give-electron) ($ electron? #t))
(('alive?) #t)
(('describe) `(electron-warp ,position ,($ state)))
(('collide other offset grid-info) #f)))
(define (^gem bcom x y)
(define position (vector x y 1))
(define picked-up? (spawn ^cell))
@ -403,7 +442,6 @@
(('enter obj grid-info) #f)
(('exit obj grid-info) #f)
(('wire-state grid-info) #f)
(('update-wire-state grid-info) #f)
(('alive?) ($ alive?))
(('describe) `(player ,($ position)))
(('collide other offset grid-info)
@ -468,7 +506,9 @@
(match ($ obj-cell)
(() #f)
;; TODO: Handle tiles with many occupants. Might not be
;; necessary in practice.
;; necessary in practice. Actually this *WILL* cause
;; problems for electron warps, at least, since they are
;; invisible and the player can stand over them.
((refr . _)
($ wire-cell ($ refr 'wire-state grid-info))))))))
(define (wire-state-at x y)