~octaspire/crates2

e55f1389f279a523501a6dc5328c2ea1b56d0669 — octaspire 9 months ago 14d14ac
Add 'Pass Counter' and delayed attach, fix wall collisions
M crates2.asd => crates2.asd +1 -0
@@ 29,6 29,7 @@
                 (:file "turnstiles")
                 (:file "block-timer")
                 (:file "block-counter")
                 (:file "pass-counter")
                 (:file "vacuum")
                 (:file "level")
                 (:file "textual")

M src/classes.lisp => src/classes.lisp +8 -0
@@ 101,6 101,14 @@
            :accessor block-counter-touches
            :initform 0)))

(defclass pass-counter (crate)
  ((count :initarg :count
          :accessor pass-counter-count
          :initform 10)
   (passes :initarg :passes
            :accessor pass-counter-passes
            :initform 0)))

(defclass exit (crate)
  ((activated :initarg :activated
              :accessor exit-activated

M src/level.lisp => src/level.lisp +11 -0
@@ 19,6 19,7 @@
(defmethod update ((self list))
  (let ((level (get-current-level)))
    (when (runningp)
      (attach-created)
      (loop for crate in level
            do (update crate))
      (purge-lamented))))


@@ 36,3 37,13 @@
                               (let ((type (type-of crate)))
                                 (unless (eq type 'player)
                                   (lamentedp crate)))) *level*)))

(defun attach-created ()
  (let ((l (last *level*)))
    (loop for crate in *created*
          do (push crate (cdr l))
          (setf l crate)))
  (setf *created* nil))

(defun request-attaching (crate)
  (setf *created* (cons crate *created*)))

M src/levels.lisp => src/levels.lisp +8 -2
@@ 14,7 14,7 @@
;; limitations under the License.
(in-package :crates2)

(defparameter *num-levels* 12)
(defparameter *num-levels* 13)

(defun load-level (index)
  (ecase index


@@ 69,5 69,11 @@
              (list (make-instance 'exit          :x 1 :y 3 :z 0)
                    (make-instance 'block-counter :x 3 :y 3 :z 0 :count 2)
                    (make-instance 'player        :x 5 :y 3 :z 0)
                    (make-instance 'block-counter :x 8 :y 3 :z 0))))))
                    (make-instance 'block-counter :x 8 :y 3 :z 0))))
    (12 (list (list nil nil nil nil :west nil nil nil nil nil :east nil nil nil nil nil :west nil nil nil nil nil nil nil :east nil nil nil nil :south)
              (list (make-instance 'wall         :x 1 :y 3 :z 0)
                    (make-instance 'exit         :x 3 :y 5 :z 0)
                    (make-instance 'pass-counter :x 4 :y 3 :z 1 :count 3)
                    (make-instance 'player       :x 5 :y 3 :z 0)
                    (make-instance 'wall         :x 8 :y 3 :z 0))))))


M src/main.lisp => src/main.lisp +3 -2
@@ 21,10 21,11 @@
(defparameter *errors* nil)
(defparameter *update-counter* 0)
(defparameter *input* nil)
(defparameter *level-number* -1)
(defparameter *level-number* 11)
(defparameter *running* t)
(defparameter *level* nil)
(defparameter *next-level* nil)
(defparameter *created* nil)
(defparameter *next-level* 12)
(defparameter *level-width* 18)
(defparameter *level-height* 12)


A src/pass-counter.lisp => src/pass-counter.lisp +45 -0
@@ 0,0 1,45 @@
;; Octaspire Crates 2 - Puzzle Game
;; Copyright 2020 octaspire.com
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
(in-package :crates2)

;; Methods

(defmethod passes-left ((self pass-counter))
  (- (pass-counter-count self)
     (pass-counter-passes self)))

(defmethod visual ((self pass-counter))
  (let ((result "pass-counter-")
        (passstr (format nil "~2,'0d" (passes-left self))))
    (setf result (concatenate 'string result passstr))
    result))

(defmethod update ((self pass-counter))
  (ecase (crate-state self)
    (:idle
     (if (<= (passes-left self) 0)
         (setf (crate-state self) :triggered)
         (let ((crate (find-at-of-type (crate-x self) (crate-y self) 0 'moving)))
           (when crate
             (incf (pass-counter-passes self))))))
    (:triggered
     (let* ((x (crate-x self))
            (y (crate-y self))
            (z 0)
            (crate (find-at x y z)))
       (unless crate
         (request-attaching (make-instance 'wall :x x :y y :z z))
         (lament self))))
    (:lamented nil)))

M src/simple-crates.lisp => src/simple-crates.lisp +3 -0
@@ 24,6 24,9 @@
(defmethod visual ((self wall))
  "wall-idle")

(defmethod collide ((self wall) (target moving))
  )

(defmethod collide ((self pushed) (target moving))
  (setf (velocity self) (on-which-side-i-am self target)))


M src/textual.lisp => src/textual.lisp +17 -5
@@ 22,12 22,12 @@

(defun init-visual-hash ()
  ;; VACUUM
  (setf (gethash "vacuum-idle" *visual-hash*) #("+----+" "|suck|" "+----+"))
  (setf (gethash "vacuum-full" *visual-hash*) #("+----+" "|SUCK|" "+----+"))
  (setf (gethash "vacuum-idle" *visual-hash*)            #("+----+" "|suck|" "+----+"))
  (setf (gethash "vacuum-full" *visual-hash*)            #("+----+" "|SUCK|" "+----+"))
  ;; WALL
  (setf (gethash "wall-idle"   *visual-hash*) #("+----+" "|XXXX|" "+----+"))
  (setf (gethash "wall-idle" *visual-hash*)              #("+----+" "|XXXX|" "+----+"))
  ;; PUSHED
  (setf (gethash "pushed-idle" *visual-hash*) #("+----+" "|PUSH|" "+----+"))
  (setf (gethash "pushed-idle" *visual-hash*)            #("+----+" "|PUSH|" "+----+"))
  ;; BLOCK-TIMER
  (setf (gethash "block-timer-durable-10" *visual-hash*) #("+----+" "BTXX10" "+----+"))
  (setf (gethash "block-timer-durable-09" *visual-hash*) #("+----+" "BTXX09" "+----+"))


@@ 82,7 82,19 @@
  (setf (gethash "block-counter-03"       *visual-hash*) #("+----+" "BCXX03" "+----+"))
  (setf (gethash "block-counter-02"       *visual-hash*) #("+----+" "BCXX02" "+----+"))
  (setf (gethash "block-counter-01"       *visual-hash*) #("+----+" "BCXX01" "+----+"))
  (setf (gethash "block-counter-00"       *visual-hash*) #("+----+" "BCXX00" "+----+")))
  (setf (gethash "block-counter-00"       *visual-hash*) #("+----+" "BCXX00" "+----+"))
  ;; PASS-COUNTER
  (setf (gethash "pass-counter-10"        *visual-hash*) #("+----+" "PC  10" "+----+"))
  (setf (gethash "pass-counter-09"        *visual-hash*) #("+----+" "PC  09" "+----+"))
  (setf (gethash "pass-counter-08"        *visual-hash*) #("+----+" "PC  08" "+----+"))
  (setf (gethash "pass-counter-07"        *visual-hash*) #("+----+" "PC  07" "+----+"))
  (setf (gethash "pass-counter-06"        *visual-hash*) #("+----+" "PC  06" "+----+"))
  (setf (gethash "pass-counter-05"        *visual-hash*) #("+----+" "PC  05" "+----+"))
  (setf (gethash "pass-counter-04"        *visual-hash*) #("+----+" "PC  04" "+----+"))
  (setf (gethash "pass-counter-03"        *visual-hash*) #("+----+" "PC  03" "+----+"))
  (setf (gethash "pass-counter-02"        *visual-hash*) #("+----+" "PC  02" "+----+"))
  (setf (gethash "pass-counter-01"        *visual-hash*) #("+----+" "PC  01" "+----+"))
  (setf (gethash "pass-counter-00"        *visual-hash*) #("+----+" "PC  00" "+----+")))

(defun empty-line ()
  (let* ((w *level-width*)