1use serde_json::{json, Map, Value};
7
8pub const VIEW_LAYOUT_VERSION: u32 = 15;
11
12#[allow(missing_docs)]
26pub mod header {
27 pub const MINUTES: usize = 0;
28 pub const TOWER_REVISION: usize = 1;
29 pub const META_REVISION: usize = 2;
30 pub const MEAL_OVERLAY_REVISION: usize = 3;
31 pub const LOG_SEQ: usize = 4;
32 pub const MONEY: usize = 5;
33 pub const STAR: usize = 6;
34 pub const UNLOCKED: usize = 7;
35 pub const POPULATION: usize = 8;
36 pub const WEATHER: usize = 9;
37 pub const SANTA_FX_SEQ: usize = 10;
38 pub const EXPLOSION_FX_SEQ: usize = 11;
39 pub const EXPLOSION_FX_FLOOR: usize = 12;
40 pub const EXPLOSION_FX_X: usize = 13;
41 pub const THIEF_FX_SEQ: usize = 14;
42 pub const THIEF_FX_CAUGHT: usize = 15;
43 pub const THIEF_FX_FLOOR: usize = 16;
44 pub const TREASURE_FX_SEQ: usize = 17;
45 pub const TREASURE_FX_FLOOR: usize = 18;
46 pub const TREASURE_FX_X: usize = 19;
47 pub const VIP_FX_SEQ: usize = 20;
48 pub const FIRES_STARTED: usize = 21;
49 pub const FIRES_GUT_ROOMS: usize = 22;
50 pub const BOMBS_DETONATED: usize = 23;
51 pub const PENDING_CHOICE: usize = 24;
52 pub const ON_HOUR_RUNS: usize = 25;
53 pub const ROOMS: usize = 26;
54 pub const FULL: usize = 27;
55 pub const FRAME_SEQ: usize = 28;
56 pub const PEOPLE: usize = 29;
57 pub const UNITS: usize = 30;
58 pub const TRANSPORTS: usize = 31;
59 pub const DAY: usize = 32;
60 pub const DAY_OF_WEEK: usize = 33;
61 pub const IS_WEEKEND: usize = 34;
62 pub const QUARTER: usize = 35;
63 pub const YEAR: usize = 36;
64 pub const WEEK_DAYS: usize = 37;
65 pub const WEEKEND_DAYS: usize = 38;
66 pub const BOMB_SEARCH_SEQ: usize = 39;
67}
68
69pub const HEADER: usize = header::BOMB_SEARCH_SEQ + 1;
71
72#[allow(missing_docs)]
75pub mod person {
76 pub const ID: usize = 0;
77 pub const SEED: usize = 1;
78 pub const STAFF: usize = 2;
79 pub const STATE: usize = 3;
80 pub const FLOOR: usize = 4;
81 pub const X: usize = 5;
82 pub const FY: usize = 6;
83 pub const WAIT: usize = 7;
84}
85
86pub const PERSON_RECORD: usize = person::WAIT + 1;
88
89#[allow(missing_docs)]
93pub mod unit {
94 pub const SLOT: usize = 0;
95 pub const STATE: usize = 1;
96 pub const OCCUPANTS: usize = 2;
97 pub const CUSTOMERS_IN: usize = 3;
98 pub const HOTEL_CUSTOMERS_IN: usize = 4;
99 pub const OUT_FOR_MEAL: usize = 5;
100}
101
102pub const UNIT_RECORD: usize = unit::OUT_FOR_MEAL + 1;
104
105#[allow(missing_docs)]
109pub mod transport {
110 pub const ID: usize = 0;
111 pub const CARS: usize = 1;
112}
113
114pub const TRANSPORT_FIXED: usize = transport::CARS + 1;
116
117#[allow(missing_docs)]
120pub mod car {
121 pub const POSITION: usize = 0;
122 pub const LOAD: usize = 1;
123 pub const DIRECTION: usize = 2;
124}
125
126pub const CAR_RECORD: usize = car::DIRECTION + 1;
128
129#[allow(missing_docs)]
137pub mod structure {
138 pub const REVISION: usize = 0;
139 pub const ROOMS: usize = 1;
140 pub const RUNS: usize = 2;
141 pub const SHAFTS: usize = 3;
142 pub const HIGHEST_FLOOR: usize = 4;
143 pub const LOWEST_FLOOR: usize = 5;
144 pub const MODE: usize = 6;
145 pub const CALENDAR: usize = 7;
146 pub const SCENE_SEED: usize = 8;
147}
148
149pub const STRUCTURE_HEADER: usize = structure::SCENE_SEED + 1;
151
152#[allow(missing_docs)]
155pub mod room {
156 pub const ID: usize = 0;
157 pub const KIND: usize = 1;
158 pub const FLOOR: usize = 2;
159 pub const X: usize = 3;
160 pub const WIDTH: usize = 4;
161}
162
163pub const ROOM_RECORD: usize = room::WIDTH + 1;
165
166#[allow(missing_docs)]
171pub mod run {
172 pub const KIND: usize = 0;
173 pub const FLOOR: usize = 1;
174 pub const X: usize = 2;
175 pub const WIDTH: usize = 3;
176 pub const COUNT: usize = 4;
177 pub const STATE: usize = 5;
178 pub const OCCUPANTS: usize = 6;
179 pub const CUSTOMERS_IN: usize = 7;
180 pub const HOTEL_CUSTOMERS_IN: usize = 8;
181 pub const OUT_FOR_MEAL: usize = 9;
182}
183
184pub const RUN_RECORD: usize = run::OUT_FOR_MEAL + 1;
186
187#[allow(missing_docs)]
191pub mod shaft {
192 pub const ID: usize = 0;
193 pub const KIND: usize = 1;
194 pub const X: usize = 2;
195 pub const WIDTH: usize = 3;
196 pub const BOTTOM: usize = 4;
197 pub const TOP: usize = 5;
198 pub const CARS: usize = 6;
199 pub const SKIPS: usize = 7;
200}
201
202pub const SHAFT_FIXED: usize = shaft::SKIPS + 1;
204
205pub(crate) struct Table {
208 pub(crate) name: &'static str,
209 pub(crate) slots: &'static [(&'static str, usize)],
210 pub(crate) width_name: &'static str,
211 pub(crate) width: usize,
212}
213
214pub(crate) const TABLES: &[Table] = &[
216 Table {
217 name: "header",
218 slots: &[
219 ("minutes", header::MINUTES),
220 ("towerRevision", header::TOWER_REVISION),
221 ("metaRevision", header::META_REVISION),
222 ("mealOverlayRevision", header::MEAL_OVERLAY_REVISION),
223 ("logSeq", header::LOG_SEQ),
224 ("money", header::MONEY),
225 ("star", header::STAR),
226 ("unlocked", header::UNLOCKED),
227 ("population", header::POPULATION),
228 ("weather", header::WEATHER),
229 ("santaFxSeq", header::SANTA_FX_SEQ),
230 ("explosionFxSeq", header::EXPLOSION_FX_SEQ),
231 ("explosionFxFloor", header::EXPLOSION_FX_FLOOR),
232 ("explosionFxX", header::EXPLOSION_FX_X),
233 ("thiefFxSeq", header::THIEF_FX_SEQ),
234 ("thiefFxCaught", header::THIEF_FX_CAUGHT),
235 ("thiefFxFloor", header::THIEF_FX_FLOOR),
236 ("treasureFxSeq", header::TREASURE_FX_SEQ),
237 ("treasureFxFloor", header::TREASURE_FX_FLOOR),
238 ("treasureFxX", header::TREASURE_FX_X),
239 ("vipFxSeq", header::VIP_FX_SEQ),
240 ("firesStarted", header::FIRES_STARTED),
241 ("firesGutRooms", header::FIRES_GUT_ROOMS),
242 ("bombsDetonated", header::BOMBS_DETONATED),
243 ("pendingChoice", header::PENDING_CHOICE),
244 ("onHourRuns", header::ON_HOUR_RUNS),
245 ("rooms", header::ROOMS),
246 ("full", header::FULL),
247 ("frameSeq", header::FRAME_SEQ),
248 ("people", header::PEOPLE),
249 ("units", header::UNITS),
250 ("transports", header::TRANSPORTS),
251 ("day", header::DAY),
252 ("dayOfWeek", header::DAY_OF_WEEK),
253 ("isWeekend", header::IS_WEEKEND),
254 ("quarter", header::QUARTER),
255 ("year", header::YEAR),
256 ("weekDays", header::WEEK_DAYS),
257 ("weekendDays", header::WEEKEND_DAYS),
258 ("bombSearchSeq", header::BOMB_SEARCH_SEQ),
259 ],
260 width_name: "headerWidth",
261 width: HEADER,
262 },
263 Table {
264 name: "person",
265 slots: &[
266 ("id", person::ID),
267 ("seed", person::SEED),
268 ("staff", person::STAFF),
269 ("state", person::STATE),
270 ("floor", person::FLOOR),
271 ("x", person::X),
272 ("fy", person::FY),
273 ("wait", person::WAIT),
274 ],
275 width_name: "personWidth",
276 width: PERSON_RECORD,
277 },
278 Table {
279 name: "unit",
280 slots: &[
281 ("slot", unit::SLOT),
282 ("state", unit::STATE),
283 ("occupants", unit::OCCUPANTS),
284 ("customersIn", unit::CUSTOMERS_IN),
285 ("hotelCustomersIn", unit::HOTEL_CUSTOMERS_IN),
286 ("outForMeal", unit::OUT_FOR_MEAL),
287 ],
288 width_name: "unitWidth",
289 width: UNIT_RECORD,
290 },
291 Table {
292 name: "transport",
293 slots: &[("id", transport::ID), ("cars", transport::CARS)],
294 width_name: "transportFixed",
295 width: TRANSPORT_FIXED,
296 },
297 Table {
298 name: "car",
299 slots: &[
300 ("position", car::POSITION),
301 ("load", car::LOAD),
302 ("direction", car::DIRECTION),
303 ],
304 width_name: "carWidth",
305 width: CAR_RECORD,
306 },
307 Table {
308 name: "structure",
309 slots: &[
310 ("revision", structure::REVISION),
311 ("rooms", structure::ROOMS),
312 ("runs", structure::RUNS),
313 ("shafts", structure::SHAFTS),
314 ("highestFloor", structure::HIGHEST_FLOOR),
315 ("lowestFloor", structure::LOWEST_FLOOR),
316 ("mode", structure::MODE),
317 ("calendar", structure::CALENDAR),
318 ("sceneSeed", structure::SCENE_SEED),
319 ],
320 width_name: "structureWidth",
321 width: STRUCTURE_HEADER,
322 },
323 Table {
324 name: "room",
325 slots: &[
326 ("id", room::ID),
327 ("kind", room::KIND),
328 ("floor", room::FLOOR),
329 ("x", room::X),
330 ("width", room::WIDTH),
331 ],
332 width_name: "roomWidth",
333 width: ROOM_RECORD,
334 },
335 Table {
336 name: "run",
337 slots: &[
338 ("kind", run::KIND),
339 ("floor", run::FLOOR),
340 ("x", run::X),
341 ("width", run::WIDTH),
342 ("count", run::COUNT),
343 ("state", run::STATE),
344 ("occupants", run::OCCUPANTS),
345 ("customersIn", run::CUSTOMERS_IN),
346 ("hotelCustomersIn", run::HOTEL_CUSTOMERS_IN),
347 ("outForMeal", run::OUT_FOR_MEAL),
348 ],
349 width_name: "runWidth",
350 width: RUN_RECORD,
351 },
352 Table {
353 name: "shaft",
354 slots: &[
355 ("id", shaft::ID),
356 ("kind", shaft::KIND),
357 ("x", shaft::X),
358 ("width", shaft::WIDTH),
359 ("bottom", shaft::BOTTOM),
360 ("top", shaft::TOP),
361 ("cars", shaft::CARS),
362 ("skips", shaft::SKIPS),
363 ],
364 width_name: "shaftFixed",
365 width: SHAFT_FIXED,
366 },
367];
368
369pub(crate) const UNIT_STATES: [&str; 10] = [
371 "construction",
372 "empty",
373 "occupied",
374 "moving_in",
375 "vacating",
376 "asleep",
377 "dirty",
378 "infested",
379 "fire",
380 "gutted",
381];
382
383pub(crate) const PERSON_STATES: [&str; 7] = [
385 "toShaft", "waiting", "riding", "climbing", "toDest", "dwelling", "done",
386];
387
388pub(crate) const WEATHER: [&str; 3] = ["clear", "cloudy", "rain"];
390
391pub(crate) const MODES: [&str; 2] = ["classic", "modern"];
393
394pub(crate) const CALENDARS: [&str; 2] = ["canon", "realWorld"];
397
398pub(crate) const META_RECORD: [&str; 3] = ["id", "label", "subtype"];
401
402pub fn layout_json() -> Value {
409 let mut m = Map::new();
410 m.insert("version".into(), json!(VIEW_LAYOUT_VERSION));
411 for t in TABLES {
412 let slots: Map<String, Value> = t
413 .slots
414 .iter()
415 .map(|(name, slot)| ((*name).to_owned(), json!(slot)))
416 .collect();
417 m.insert(t.name.into(), Value::Object(slots));
418 m.insert(t.width_name.into(), json!(t.width));
419 }
420 let facilities = &crate::facilities::FACILITIES;
421 m.insert(
422 "kinds".into(),
423 json!(facilities.iter().map(|f| f.key).collect::<Vec<_>>()),
424 );
425 m.insert(
426 "names".into(),
427 json!(facilities.iter().map(|f| f.name).collect::<Vec<_>>()),
428 );
429 m.insert("unitStates".into(), json!(UNIT_STATES));
430 m.insert("personStates".into(), json!(PERSON_STATES));
431 m.insert("weather".into(), json!(WEATHER));
432 m.insert("modes".into(), json!(MODES));
433 m.insert("calendars".into(), json!(CALENDARS));
434 m.insert("metaRecord".into(), json!(META_RECORD));
435 Value::Object(m)
436}