-
Notifications
You must be signed in to change notification settings - Fork 1
/
drawing.clj
145 lines (128 loc) · 4.53 KB
/
drawing.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
(ns ruin.drawing
(:use [ruin.state :only [game]]
[ruin.buildings :only [get-building-sheet]])
(:require [lanterna.screen :as s]))
(def SIDEBAR-WIDTH 35)
(def STATUS-HEIGHT 10)
(defmulti draw-ui
"Draw the UI to the console. Does not clear or refresh."
(fn [ui]
(:kind ui)))
(defmethod draw-ui :start [ui]
(io!
(s/put-sheet (:screen @game) 0 0
[" _____ _ _ _____ _ _"
"| __ \\| | | |_ _| \\ | |"
"| |__) | | | | | | | \\| |"
"| _ /| | | | | | | . ` |"
"| | \\ \\| |__| |_| |_| |\\ |"
"|_| \\_\\\\____/|_____|_| \\_|"
""
"press any key to begin..."])))
(defmethod draw-ui :win [ui]
(io!
(s/put-sheet (:screen @game) 0 0
["Congratulations, you've won!"
""
"press any key to continue..."])))
(defmethod draw-ui :lose [ui]
(io!
(s/put-sheet (:screen @game) 0 0
["Sorry, you lost."
""
"press any key to continue..."])))
(defn draw-entities []
(let [[ox oy] (:viewport-origin @game)
screen (:screen @game)
[cols rows] (s/get-size screen)
map-height rows
map-width (- cols (inc SIDEBAR-WIDTH))]
(doseq [entity (vals @(:entities @game))]
(let [{:keys [location glyph]} @entity
[x y] location
vx (- x ox)
vy (- y oy)]
(when (and (<= 0 vy (dec map-height))
(<= 0 vx (dec map-width)))
(s/put-string screen vx vy glyph))))))
(defn draw-buildings []
(let [[ox oy] (:viewport-origin @game)
screen (:screen @game)
[cols rows] (s/get-size screen)
map-height rows
map-width (- cols (inc SIDEBAR-WIDTH))]
(doseq [building (vals @(:buildings @game))]
(let [{:keys [location size]} @building
[x y] location
[width height] size
vx (- x ox)
vx' (+ vx width)
vy (- y oy)
vy' (+ vy height)]
(when (and (<= 0 vy')
(<= 0 vx')
(< vy map-height)
(< vx map-width))
(s/put-sheet screen vx vy (get-building-sheet @building)))))))
(defn draw-map []
(let [screen (:screen @game)
[cols rows] (s/get-size screen)
map-height rows
map-width (- cols (inc SIDEBAR-WIDTH))
row (apply str (repeat map-width \.))
]
(s/put-sheet screen 0 0
(repeat map-height row))))
(defn clear-sidebar []
(let [game @game
screen (:screen game)
[cols rows] (s/get-size screen)
x (- cols SIDEBAR-WIDTH 1)]
(s/put-sheet screen x 0
(repeat rows (repeat cols \space)))))
(defn draw-status []
(let [game @game
screen (:screen game)
[cols rows] (s/get-size screen)
x (- cols SIDEBAR-WIDTH)
total-building-aspect (fn [aspect kind]
(reduce + (map #(aspect @%)
(filter #(= kind (:type @%))
(vals @(:buildings game))))))
population (count (filter #(= :person (:type @%))
(vals @(:entities game))))
housing (total-building-aspect :capacity :house)
food (total-building-aspect :contents :silo)
food-storage (total-building-aspect :capacity :silo)
resources @(:resources game)
[score-peak score-current] @(:score game)]
(s/put-sheet screen x 0
["SCORE"
(str score-peak " - " score-current " = " (- score-peak score-current))
""
"STATUS"
"Time: Year 45, Month 12"
(str "Population: " population " / " housing)
(str "Food: " food " / " food-storage)
"Satisfaction: 80%"
(str "Resources: " resources)])))
(defn draw-main-menu []
(let [screen (:screen @game)
[cols rows] (s/get-size screen)
x (- cols SIDEBAR-WIDTH)
y (inc STATUS-HEIGHT)]
(s/put-sheet screen x y
["MENU"
"hjklyubn: move view"
"HJKLYUBN: move view faster"
"Q: quit game"])))
(defn draw-sidebar []
(clear-sidebar)
(draw-status)
(draw-main-menu))
(defmethod draw-ui :play [ui]
(io!
(draw-map)
(draw-buildings)
(draw-entities)
(draw-sidebar)))