|
@@ -77,12 +77,14 @@
|
77
|
77
|
(health-regen :initarg :health-regen :initform 1 :type fixnum)
|
78
|
78
|
(color :initarg :color :initform (color-from-name "#1919ff"))))
|
79
|
79
|
|
80
|
|
-(defclass tomb (tile-entity)
|
|
80
|
+(defclass tomb (floor-tile)
|
81
|
81
|
((codepoint :initform #x2616)
|
82
|
|
- (color :initform (color-from-name "yellow"))))
|
|
82
|
+ (color :initform (color-from-name "yellow"))
|
|
83
|
+ (awakened :initform nil :reader awakened-p :accessor awakened)))
|
83
|
84
|
|
84
|
85
|
(defclass minion (mobile)
|
85
|
|
- ((color :initarg :color :initform (color-from-name "yellow"))))
|
|
86
|
+ ((color :initarg :color :initform (color-from-name "yellow"))
|
|
87
|
+ (codepoint :initform #x265f)))
|
86
|
88
|
|
87
|
89
|
(defun calc-coord (location map)
|
88
|
90
|
(values (mod location (game-map-width map)) (floor (/ location (game-map-width map)))))
|
|
@@ -248,30 +250,26 @@
|
248
|
250
|
|
249
|
251
|
(defmethod bash-left ((object player-character) map)
|
250
|
252
|
(let* ((location (1- (slot-value object 'location)))
|
251
|
|
- (potential-target (gethash location (game-map-mobiles map)))
|
252
|
|
- (target (and potential-target (typep potential-target 'mobile))))
|
253
|
|
- (when target
|
|
253
|
+ (target (gethash location (game-map-mobiles map))))
|
|
254
|
+ (when (and target (typep target 'mobile))
|
254
|
255
|
(decf (slot-value target 'health) (slot-value object 'melee-attack-damage)))))
|
255
|
256
|
|
256
|
257
|
(defmethod bash-right ((object player-character) map)
|
257
|
258
|
(let* ((location (1+ (slot-value object 'location)))
|
258
|
|
- (potential-target (gethash location (game-map-mobiles map)))
|
259
|
|
- (target (and potential-target (typep potential-target 'mobile))))
|
260
|
|
- (when target
|
|
259
|
+ (target (gethash location (game-map-mobiles map))))
|
|
260
|
+ (when (and target (typep target 'mobile))
|
261
|
261
|
(decf (slot-value target 'health) (slot-value object 'melee-attack-damage)))))
|
262
|
262
|
|
263
|
263
|
(defmethod bash-up ((object player-character) map)
|
264
|
264
|
(let* ((location (- (slot-value object 'location) (game-map-width map)))
|
265
|
|
- (potential-target (gethash location (game-map-mobiles map)))
|
266
|
|
- (target (and potential-target (typep potential-target 'mobile))))
|
267
|
|
- (when target
|
|
265
|
+ (target (gethash location (game-map-mobiles map))))
|
|
266
|
+ (when (and target (typep target 'mobile))
|
268
|
267
|
(decf (slot-value target 'health) (slot-value object 'melee-attack-damage)))))
|
269
|
268
|
|
270
|
269
|
(defmethod bash-down ((object player-character) map)
|
271
|
270
|
(let* ((location (+ (slot-value object 'location) (game-map-width map)))
|
272
|
|
- (potential-target (gethash location (game-map-mobiles map)))
|
273
|
|
- (target (and potential-target (typep potential-target 'mobile))))
|
274
|
|
- (when target
|
|
271
|
+ (target (gethash location (game-map-mobiles map))))
|
|
272
|
+ (when (and target (typep target 'mobile))
|
275
|
273
|
(decf (slot-value target 'health) (slot-value object 'melee-attack-damage)))))
|
276
|
274
|
|
277
|
275
|
(defun intro-message ()
|
|
@@ -442,24 +440,26 @@
|
442
|
440
|
(set-location floor x y map)
|
443
|
441
|
(setf (gethash (calc-location x y map) terrain) floor)))))))))
|
444
|
442
|
|
|
443
|
+(defun room-center (room map)
|
|
444
|
+ (with-slots ((x1 crawler::x1) (x2 crawler::x2) (y1 crawler::y1) (y2 crawler::y2)) room
|
|
445
|
+ (calc-location (floor (+ x2 x1) 2) (floor (+ y2 y1) 2) map)))
|
|
446
|
+
|
445
|
447
|
(defun spawn-enemies (map player)
|
446
|
448
|
(loop for room in (crawler::rooms (game-map-dungeon map))
|
447
|
449
|
when (not (equal room (find-room (get-location player) map))) do
|
448
|
|
- (with-slots ((x1 crawler::x1) (x2 crawler::x2) (y1 crawler::y1) (y2 crawler::y2)) room
|
449
|
|
- (dotimes (times (random 3))
|
450
|
|
- (let* ((location (nearest-open-tile (gethash (calc-location x1 y1 map) (game-map-terrain map)) map))
|
451
|
|
- (enemy (make-instance 'enemy :location location)))
|
452
|
|
- (when location
|
453
|
|
- (setf (gethash location (game-map-mobiles map)) enemy)))))))
|
|
450
|
+ (dotimes (times (random 3))
|
|
451
|
+ (let* ((location (nearest-open-tile (gethash (room-center room map) (game-map-terrain map)) map))
|
|
452
|
+ (enemy (make-instance 'enemy :location location)))
|
|
453
|
+ (when location
|
|
454
|
+ (setf (gethash location (game-map-mobiles map)) enemy))))))
|
454
|
455
|
|
455
|
456
|
(defun spawn-tombs (map)
|
456
|
457
|
(loop for room in (crawler::rooms (game-map-dungeon map)) do
|
457
|
|
- (with-slots ((x1 crawler::x1) (x2 crawler::x2) (y1 crawler::y1) (y2 crawler::y2)) room
|
458
|
|
- (when (= 2 (random 5))
|
459
|
|
- (let* ((location (nearest-open-tile (gethash (calc-location x2 y2 map) (game-map-terrain map)) map))
|
460
|
|
- (tomb (make-instance 'tomb :location location)))
|
461
|
|
- (when location
|
462
|
|
- (setf (gethash location (game-map-terrain map)) tomb)))))))
|
|
458
|
+ (when (= 2 (random 3))
|
|
459
|
+ (let* ((location (nearest-open-tile (gethash (room-center room map) (game-map-terrain map)) map))
|
|
460
|
+ (tomb (make-instance 'tomb :location location)))
|
|
461
|
+ (when location
|
|
462
|
+ (setf (gethash location (game-map-terrain map)) tomb))))))
|
463
|
463
|
|
464
|
464
|
(defun initialize-map (map player)
|
465
|
465
|
(fill-map-from-crawler map player)
|
|
@@ -545,6 +545,31 @@
|
545
|
545
|
(setf height (game-map-height map)))
|
546
|
546
|
(make-instance 'viewport :width width :height height)))
|
547
|
547
|
|
|
548
|
+(defun find-tomb-rooms-with-tomb (map)
|
|
549
|
+ (labels ((tombp (tile) (typep tile 'tomb)))
|
|
550
|
+ (let ((tombs (remove-if-not #'tombp (alexandria:hash-table-values (game-map-terrain map)))))
|
|
551
|
+ (loop for tomb in tombs
|
|
552
|
+ as room = (find-room (get-location tomb) map)
|
|
553
|
+ as pair = (list tomb room)
|
|
554
|
+ collect pair))))
|
|
555
|
+
|
|
556
|
+(defun spawn-minion (tomb map)
|
|
557
|
+ (let* ((location (nearest-open-tile tomb map))
|
|
558
|
+ (minion (make-instance 'minion :location location)))
|
|
559
|
+ (setf (gethash location (game-map-mobiles map)) minion)))
|
|
560
|
+
|
|
561
|
+(defun wake-up-the-dead (map player)
|
|
562
|
+ (let ((player-room (find-room (get-location player) map))
|
|
563
|
+ (tomb-rooms (find-tomb-rooms-with-tomb map)))
|
|
564
|
+ (loop for tomb-room in tomb-rooms
|
|
565
|
+ when (and player-room
|
|
566
|
+ tomb-room
|
|
567
|
+ (equal player-room (cadr tomb-room))
|
|
568
|
+ (not (awakened (car tomb-room)))) do
|
|
569
|
+ (let ((tomb (car tomb-room)))
|
|
570
|
+ (setf (awakened tomb) t)
|
|
571
|
+ (spawn-minion tomb map)))))
|
|
572
|
+
|
548
|
573
|
(defun end-of-turn-tasks (player map)
|
549
|
574
|
(maphash (lambda (location object)
|
550
|
575
|
(when (typep object 'mobile)
|
|
@@ -553,20 +578,23 @@
|
553
|
578
|
(setf (slot-value object 'location) nil)
|
554
|
579
|
(remhash location (game-map-mobiles map)))
|
555
|
580
|
(end-of-turn object)))) (game-map-mobiles map))
|
|
581
|
+ (wake-up-the-dead map player)
|
556
|
582
|
(make-dijkstra-map (list player) 'player-map-value (game-map-terrain map))
|
557
|
583
|
(make-dijkstra-map
|
558
|
584
|
(remove-if-not #'enemy-p
|
559
|
585
|
(alexandria:hash-table-values (game-map-mobiles map)))
|
560
|
586
|
'enemy-map-value (game-map-terrain map)))
|
561
|
587
|
|
562
|
|
-(defun write-status-to-terminal (player prev-key)
|
|
588
|
+(defun write-status-to-terminal (player prev-key map)
|
563
|
589
|
(declare (ignore prev-key))
|
564
|
590
|
(multiple-value-bind (width height) (get-window-size)
|
565
|
591
|
(declare (ignore width))
|
566
|
|
- (terminal-color (color-from-name "white"))
|
567
|
|
- (terminal-print 0 (1- height) (format nil "H: ~d M: ~d"
|
568
|
|
- (slot-value player 'health)
|
569
|
|
- (slot-value player 'mana)))))
|
|
592
|
+ (multiple-value-bind (x y) (calc-coord (get-location player) map)
|
|
593
|
+ (terminal-color (color-from-name "white"))
|
|
594
|
+ (terminal-print 0 (1- height) (format nil "Health: ~d Mana: ~d Location: (~d, ~d)"
|
|
595
|
+ (slot-value player 'health)
|
|
596
|
+ (slot-value player 'mana)
|
|
597
|
+ x y)))))
|
570
|
598
|
|
571
|
599
|
(defun display-lose ()
|
572
|
600
|
(terminal-clear)
|
|
@@ -603,7 +631,7 @@
|
603
|
631
|
(end-of-turn-tasks player map))
|
604
|
632
|
(terminal-clear)
|
605
|
633
|
(write-map-to-terminal player map viewport)
|
606
|
|
- (write-status-to-terminal player prev-key)
|
|
634
|
+ (write-status-to-terminal player prev-key map)
|
607
|
635
|
(terminal-refresh))
|
608
|
636
|
until (or (= key bearlibterminal-ffi:+tk-close+)
|
609
|
637
|
(= key bearlibterminal-ffi:+tk-escape+)
|