Blob


1 /*
2 * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "isscrolls.h"
19 #include <json-c/json.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <string.h>
25 static char oracle_is_names[200][MAX_NAME_LEN];
26 static char oracle_elf_names[100][MAX_NAME_LEN];
27 static char oracle_giant_names[100][MAX_NAME_LEN];
28 static char oracle_varou_names[100][MAX_NAME_LEN];
29 static char oracle_troll_names[100][MAX_NAME_LEN];
31 static char oracle_action[100][MAX_NAME_LEN];
32 static char oracle_theme[100][MAX_NAME_LEN];
34 static char oracle_rank[100][MAX_RANK_LEN];
35 static char oracle_combat_action[100][MAX_PLOT_LEN];
36 static char oracle_plot_twist[100][MAX_PLOT_LEN];
37 static char oracle_mystic_backslash[100][MAX_MYSTIC_LEN];
39 static char oracle_regions[100][MAX_PLACES_LEN];
40 static char oracle_locations[100][MAX_PLACES_LEN];
41 static char oracle_location_descriptions[100][MAX_PLACES_LEN];
42 static char oracle_coastal_locations[100][MAX_PLACES_LEN];
44 static char oracle_pay_the_price[100][MAX_PTP_LEN];
46 static int read_names = 0;
47 static int read_action = 0;
48 static int read_turning = 0;
49 static int read_places = 0;
50 static int read_moves = 0;
52 static void read_names_from_json(void);
53 static void read_moves_from_json(void);
54 static void read_action_from_json(void);
55 static void read_turning_from_json(void);
56 static void read_places_from_json(void);
58 enum oracle_codes {
59 ORACLE_IS_NAMES,
60 ORACLE_ELF_NAMES,
61 ORACLE_GIANT_NAMES,
62 ORACLE_VAROU_NAMES,
63 ORACLE_TROLL_NAMES,
64 ORACLE_ACTIONS,
65 ORACLE_THEMES,
66 ORACLE_RANKS,
67 ORACLE_COMBAT_ACTIONS,
68 ORACLE_PLOT_TWISTS,
69 ORACLE_MYSTIC_BACKSLASH,
70 ORACLE_REGION,
71 ORACLE_LOCATION ,
72 ORACLE_COASTAL,
73 ORACLE_DESCRIPTION,
74 ORACLE_PAYTHEPRICE,
75 };
77 static void
78 add_to_array(int what, int id, const char *value)
79 {
80 log_debug("%d, %d, %s\n", what, id, value);
82 switch (what) {
83 case -1:
84 log_debug("Unknown array\n");
85 return;
86 case ORACLE_IS_NAMES:
87 if (id < 0 || id > 200)
88 return;
89 snprintf(oracle_is_names[id], MAX_NAME_LEN, "%s", value);
90 break;
91 case ORACLE_ELF_NAMES:
92 if (id < 0 || id > 100)
93 return;
94 snprintf(oracle_elf_names[id], MAX_NAME_LEN, "%s", value);
95 break;
96 case ORACLE_GIANT_NAMES:
97 if (id < 0 || id > 100)
98 return;
99 snprintf(oracle_giant_names[id], MAX_NAME_LEN, "%s", value);
100 break;
101 case ORACLE_VAROU_NAMES:
102 if (id < 0 || id > 100)
103 return;
104 snprintf(oracle_varou_names[id], MAX_NAME_LEN, "%s", value);
105 break;
106 case ORACLE_TROLL_NAMES:
107 if (id < 0 || id > 100)
108 return;
109 snprintf(oracle_troll_names[id], MAX_NAME_LEN, "%s", value);
110 break;
111 /* -------------------------------------------------------------------- */
112 case ORACLE_ACTIONS:
113 if (id < 0 || id > 100)
114 return;
115 snprintf(oracle_action[id], MAX_NAME_LEN, "%s", value);
116 break;
117 case ORACLE_THEMES:
118 if (id < 0 || id > 100)
119 return;
120 snprintf(oracle_theme[id], MAX_NAME_LEN, "%s", value);
121 break;
122 /* -------------------------------------------------------------------- */
123 case ORACLE_RANKS:
124 if (id < 0 || id > 100)
125 return;
126 snprintf(oracle_rank[id], MAX_RANK_LEN, "%s", value);
127 break;
128 case ORACLE_COMBAT_ACTIONS:
129 if (id < 0 || id > 100)
130 return;
131 snprintf(oracle_combat_action[id], MAX_PLOT_LEN, "%s", value);
132 break;
133 case ORACLE_PLOT_TWISTS:
134 if (id < 0 || id > 100)
135 return;
136 snprintf(oracle_plot_twist[id], MAX_PLOT_LEN, "%s", value);
137 break;
138 case ORACLE_MYSTIC_BACKSLASH:
139 if (id < 0 || id > 100)
140 return;
141 snprintf(oracle_mystic_backslash[id], MAX_MYSTIC_LEN, "%s", value);
142 break;
143 /* -------------------------------------------------------------------- */
144 case ORACLE_REGION:
145 if (id < 0 || id > 100)
146 return;
147 snprintf(oracle_regions[id], MAX_PLACES_LEN, "%s", value);
148 break;
149 case ORACLE_LOCATION:
150 if (id < 0 || id > 100)
151 return;
152 snprintf(oracle_locations[id], MAX_PLACES_LEN, "%s", value);
153 break;
154 case ORACLE_COASTAL:
155 if (id < 0 || id > 100)
156 return;
157 snprintf(oracle_coastal_locations[id], MAX_PLACES_LEN, "%s", value);
158 break;
159 case ORACLE_DESCRIPTION:
160 if (id < 0 || id > 100)
161 return;
162 snprintf(oracle_location_descriptions[id], MAX_PLACES_LEN, "%s", value);
163 break;
164 /* -------------------------------------------------------------------- */
165 case ORACLE_PAYTHEPRICE:
166 if (id < 0 || id > 100)
167 return;
168 snprintf(oracle_pay_the_price[id], MAX_PTP_LEN, "%s", value);
169 break;
170 default:
171 log_errx(1, "add_to_array: This should not happen\n");
176 static void
177 read_names_from_json()
179 char path[_POSIX_PATH_MAX];
180 json_object *root, *oracles, *temp, *table, *name, *desc, *chance;
181 int n_oracles, n_entries, i, j, what;
183 snprintf(path, sizeof(path), "%s/ironsworn_oracles_names.json", _PATH_SHARE_DIR);
185 if ((root = json_object_from_file(path)) == NULL) {
186 log_errx(1, "Cannot open %s\n", path);
189 if (!json_object_object_get_ex(root, "Oracles", &oracles)) {
190 log_debug("Cannot find a [Oracles] array in %s\n", path);
191 return;
194 n_oracles = json_object_array_length(oracles);
196 log_debug("number of oracles: %d\n", n_oracles);
197 for (i = 0; i < n_oracles; i++) {
198 temp = json_object_array_get_idx(oracles, i);
199 json_object_object_get_ex(temp, "Oracle Table", &table);
200 json_object_object_get_ex(temp, "Name", &name);
201 log_debug("Name %s\n", json_object_get_string(name));
203 if ((strcmp(json_object_get_string(name), "Ironlander Names") == 0))
204 what = ORACLE_IS_NAMES;
205 else if ((strcmp(json_object_get_string(name), "Elf Names") == 0))
206 what = ORACLE_ELF_NAMES;
207 else if ((strcmp(json_object_get_string(name), "Giant Names") == 0))
208 what = ORACLE_GIANT_NAMES;
209 else if ((strcmp(json_object_get_string(name), "Varou Names") == 0))
210 what = ORACLE_VAROU_NAMES;
211 else if ((strcmp(json_object_get_string(name), "Troll Names") == 0))
212 what = ORACLE_TROLL_NAMES;
213 else {
214 what = -1;
215 continue;
218 n_entries = json_object_array_length(table);
219 for (j = 0; j < n_entries; j++) {
220 temp = json_object_array_get_idx(table, j);
221 json_object_object_get_ex(temp, "Description", &desc);
222 json_object_object_get_ex(temp, "Chance", &chance);
223 add_to_array(what, json_object_get_int(chance), json_object_get_string(desc));
227 /* Decrement the reference count of json_object and free if it reaches zero. */
228 json_object_put(root);
230 read_names = 1;
233 static void
234 read_moves_from_json()
236 char path[_POSIX_PATH_MAX];
237 json_object *root, *oracles, *temp, *table, *name, *desc, *chance;
238 int n_oracles, n_entries, i, j, what;
240 snprintf(path, sizeof(path), "%s/ironsworn_move_oracles.json", _PATH_SHARE_DIR);
242 if ((root = json_object_from_file(path)) == NULL) {
243 log_errx(1, "Cannot open %s\n", path);
246 if (!json_object_object_get_ex(root, "Oracles", &oracles)) {
247 log_debug("Cannot find a [Oracles] array in %s\n", path);
248 return;
251 n_oracles = json_object_array_length(oracles);
253 log_debug("number of oracles: %d\n", n_oracles);
254 for (i = 0; i < n_oracles; i++) {
255 temp = json_object_array_get_idx(oracles, i);
256 json_object_object_get_ex(temp, "Oracle Table", &table);
257 json_object_object_get_ex(temp, "Name", &name);
258 log_debug("Name %s\n", json_object_get_string(name));
260 if ((strcmp(json_object_get_string(name), "Pay the Price") == 0))
261 what = ORACLE_PAYTHEPRICE;
262 else {
263 what = -1;
264 continue;
267 n_entries = json_object_array_length(table);
268 for (j = 0; j < n_entries; j++) {
269 temp = json_object_array_get_idx(table, j);
270 json_object_object_get_ex(temp, "Description", &desc);
271 json_object_object_get_ex(temp, "Chance", &chance);
272 add_to_array(what, json_object_get_int(chance), json_object_get_string(desc));
276 /* Decrement the reference count of json_object and free if it reaches zero. */
277 json_object_put(root);
279 read_moves = 1;
282 static void
283 read_action_from_json()
285 char path[_POSIX_PATH_MAX];
286 json_object *root, *oracles, *temp, *table, *name, *desc, *chance;
287 int n_oracles, n_entries, i, j, what;
289 snprintf(path, sizeof(path), "%s/ironsworn_oracles_prompts.json", _PATH_SHARE_DIR);
291 if ((root = json_object_from_file(path)) == NULL) {
292 log_errx(1, "Cannot open %s\n", path);
295 if (!json_object_object_get_ex(root, "Oracles", &oracles)) {
296 log_debug("Cannot find a [Oracles] array in %s\n", path);
297 return;
300 n_oracles = json_object_array_length(oracles);
302 log_debug("number of oracles: %d\n", n_oracles);
303 for (i = 0; i < n_oracles; i++) {
304 temp = json_object_array_get_idx(oracles, i);
305 json_object_object_get_ex(temp, "Oracle Table", &table);
306 json_object_object_get_ex(temp, "Name", &name);
307 log_debug("Name %s\n", json_object_get_string(name));
309 if ((strcmp(json_object_get_string(name), "Action") == 0))
310 what = ORACLE_ACTIONS;
311 else if ((strcmp(json_object_get_string(name), "Theme") == 0))
312 what = ORACLE_THEMES;
313 /* The following oracles are not yet supported */
314 else if ((strcmp(json_object_get_string(name), "Feature") == 0))
315 continue;
316 else if ((strcmp(json_object_get_string(name), "Focus") == 0))
317 continue;
318 else if ((strcmp(json_object_get_string(name), "Trap") == 0))
319 continue;
320 else if ((strcmp(json_object_get_string(name), "Combat Event") == 0))
321 continue;
322 else {
323 what = -1;
324 continue;
327 n_entries = json_object_array_length(table);
328 for (j = 0; j < n_entries; j++) {
329 temp = json_object_array_get_idx(table, j);
330 json_object_object_get_ex(temp, "Description", &desc);
331 json_object_object_get_ex(temp, "Chance", &chance);
332 add_to_array(what, json_object_get_int(chance), json_object_get_string(desc));
336 /* Decrement the reference count of json_object and free if it reaches zero. */
337 json_object_put(root);
339 read_action = 1;
342 static void
343 read_turning_from_json()
345 char path[_POSIX_PATH_MAX];
346 json_object *root, *oracles, *temp, *table, *name, *desc, *chance;
347 int n_oracles, n_entries, i, j, what;
349 snprintf(path, sizeof(path), "%s/ironsworn_oracles_turning_point.json", _PATH_SHARE_DIR);
351 if ((root = json_object_from_file(path)) == NULL) {
352 log_errx(1, "Cannot open %s\n", path);
355 if (!json_object_object_get_ex(root, "Oracles", &oracles)) {
356 log_debug("Cannot find a [Oracles] array in %s\n", path);
357 return;
360 n_oracles = json_object_array_length(oracles);
362 log_debug("number of oracles: %d\n", n_oracles);
363 for (i = 0; i < n_oracles; i++) {
364 temp = json_object_array_get_idx(oracles, i);
365 json_object_object_get_ex(temp, "Oracle Table", &table);
366 json_object_object_get_ex(temp, "Name", &name);
367 log_debug("Name %s\n", json_object_get_string(name));
369 if ((strcmp(json_object_get_string(name), "Challenge Rank") == 0))
370 what = ORACLE_RANKS;
371 else if ((strcmp(json_object_get_string(name), "Combat Action") == 0))
372 what = ORACLE_COMBAT_ACTIONS;
373 else if ((strcmp(json_object_get_string(name), "Major Plot Twist") == 0))
374 what = ORACLE_PLOT_TWISTS;
375 else if ((strcmp(json_object_get_string(name), "Mystic Backlash") == 0))
376 what = ORACLE_MYSTIC_BACKSLASH;
377 else {
378 what = -1;
379 continue;
382 n_entries = json_object_array_length(table);
383 for (j = 0; j < n_entries; j++) {
384 temp = json_object_array_get_idx(table, j);
385 json_object_object_get_ex(temp, "Description", &desc);
386 json_object_object_get_ex(temp, "Chance", &chance);
387 add_to_array(what, json_object_get_int(chance), json_object_get_string(desc));
391 /* Decrement the reference count of json_object and free if it reaches zero. */
392 json_object_put(root);
394 read_turning = 1;
397 static void
398 read_places_from_json()
400 char path[_POSIX_PATH_MAX];
401 json_object *root, *oracles, *temp, *table, *name, *desc, *chance;
402 int n_oracles, n_entries, i, j, what;
404 snprintf(path, sizeof(path), "%s/ironsworn_oracles_place.json", _PATH_SHARE_DIR);
406 if ((root = json_object_from_file(path)) == NULL) {
407 log_errx(1, "Cannot open %s\n", path);
410 if (!json_object_object_get_ex(root, "Oracles", &oracles)) {
411 log_debug("Cannot find a [Oracles] array in %s\n", path);
412 return;
415 n_oracles = json_object_array_length(oracles);
417 log_debug("number of oracles: %d\n", n_oracles);
418 for (i = 0; i < n_oracles; i++) {
419 temp = json_object_array_get_idx(oracles, i);
420 json_object_object_get_ex(temp, "Oracle Table", &table);
421 json_object_object_get_ex(temp, "Name", &name);
422 log_debug("Name %s\n", json_object_get_string(name));
424 if ((strcmp(json_object_get_string(name), "Region") == 0))
425 what = ORACLE_REGION;
426 else if ((strcmp(json_object_get_string(name), "Location") == 0))
427 what = ORACLE_LOCATION;
428 else if ((strcmp(json_object_get_string(name), "Coastal Waters Location") == 0))
429 what = ORACLE_COASTAL;
430 else if ((strcmp(json_object_get_string(name), "Location Descriptors") == 0))
431 what = ORACLE_DESCRIPTION;
432 else {
433 what = -1;
434 continue;
437 n_entries = json_object_array_length(table);
438 for (j = 0; j < n_entries; j++) {
439 temp = json_object_array_get_idx(table, j);
440 json_object_object_get_ex(temp, "Description", &desc);
441 json_object_object_get_ex(temp, "Chance", &chance);
442 add_to_array(what, json_object_get_int(chance), json_object_get_string(desc));
446 /* Decrement the reference count of json_object and free if it reaches zero. */
447 json_object_put(root);
449 read_places = 1;
452 void
453 cmd_show_iron_name(__attribute__((unused))char *unused)
455 show_info_from_oracle(ORACLE_IS_NAMES, 200);
458 void
459 cmd_show_elf_name(__attribute__((unused))char *unused)
461 show_info_from_oracle(ORACLE_ELF_NAMES, 100);
464 void
465 cmd_show_giant_name(__attribute__((unused))char *unused)
467 show_info_from_oracle(ORACLE_GIANT_NAMES, 100);
470 void
471 cmd_show_varou_name(__attribute__((unused))char *unused)
473 show_info_from_oracle(ORACLE_VAROU_NAMES, 100);
476 void
477 cmd_show_troll_name(__attribute__((unused))char *unused)
479 show_info_from_oracle(ORACLE_TROLL_NAMES, 100);
482 void
483 cmd_show_action(__attribute__((unused))char *unused)
485 show_info_from_oracle(ORACLE_ACTIONS, 100);
488 void
489 cmd_show_theme(__attribute__((unused))char *unused)
491 show_info_from_oracle(ORACLE_THEMES, 100);
494 void
495 cmd_show_rank(__attribute__((unused))char *unused)
497 show_info_from_oracle(ORACLE_RANKS, 100);
500 void
501 cmd_show_combat_action(__attribute__((unused))char *unused)
503 show_info_from_oracle(ORACLE_COMBAT_ACTIONS, 100);
506 void
507 cmd_show_plot_twist(__attribute__((unused))char *unused)
509 show_info_from_oracle(ORACLE_PLOT_TWISTS, 100);
512 void
513 cmd_show_mystic_backshlash(__attribute__((unused))char *unused)
515 show_info_from_oracle(ORACLE_MYSTIC_BACKSLASH, 100);
518 void
519 cmd_show_location(__attribute__((unused))char *unused)
521 show_info_from_oracle(ORACLE_LOCATION, 100);
524 void
525 cmd_show_location_description(__attribute__((unused))char *unused)
527 show_info_from_oracle(ORACLE_DESCRIPTION, 100);
530 void
531 cmd_show_coastal_location(__attribute__((unused))char *unused)
533 show_info_from_oracle(ORACLE_COASTAL, 100);
536 void
537 cmd_show_region(__attribute__((unused))char *unused)
539 show_info_from_oracle(ORACLE_REGION, 100);
542 void
543 cmd_show_pay_the_price(__attribute__((unused))char *unused)
545 show_info_from_oracle(ORACLE_PAYTHEPRICE, 100);
548 void
549 show_info_from_oracle(int what, int max)
551 char temp[255];
552 long die, die2, saved_die;
554 die = saved_die = roll_oracle_die();
555 if (die < 0 || die >= max)
556 return;
558 memset(temp, 0, sizeof(temp));
560 if (read_names == 0)
561 read_names_from_json();
562 if (read_action == 0)
563 read_action_from_json();
564 if (read_turning == 0)
565 read_turning_from_json();
566 if (read_places == 0)
567 read_places_from_json();
568 if (read_moves == 0)
569 read_moves_from_json();
571 switch(what) {
572 case ORACLE_IS_NAMES:
573 die2 = roll_oracle_die();
574 die += die2;
575 snprintf(temp, sizeof(temp), "%s", oracle_is_names[die]);
576 break;
577 case ORACLE_ELF_NAMES:
578 while (strlen(oracle_elf_names[die]) == 0)
579 die++;
580 snprintf(temp, sizeof(temp), "%s", oracle_elf_names[die]);
581 break;
582 case ORACLE_GIANT_NAMES:
583 while (strlen(oracle_giant_names[die]) == 0)
584 die++;
585 snprintf(temp, sizeof(temp), "%s", oracle_giant_names[die]);
586 break;
587 case ORACLE_VAROU_NAMES:
588 while (strlen(oracle_varou_names[die]) == 0)
589 die++;
590 snprintf(temp, sizeof(temp), "%s", oracle_varou_names[die]);
591 break;
592 case ORACLE_TROLL_NAMES:
593 while (strlen(oracle_troll_names[die]) == 0)
594 die++;
595 snprintf(temp, sizeof(temp), "%s", oracle_troll_names[die]);
596 break;
597 case ORACLE_ACTIONS:
598 while (strlen(oracle_action[die]) == 0)
599 die++;
600 snprintf(temp, sizeof(temp), "%s", oracle_action[die]);
601 break;
602 case ORACLE_THEMES:
603 while (strlen(oracle_theme[die]) == 0)
604 die++;
605 snprintf(temp, sizeof(temp), "%s", oracle_theme[die]);
606 break;
607 case ORACLE_RANKS:
608 while (strlen(oracle_rank[die]) == 0)
609 die++;
610 snprintf(temp, sizeof(temp), "%s", oracle_rank[die]);
611 break;
612 case ORACLE_COMBAT_ACTIONS:
613 while (strlen(oracle_combat_action[die]) == 0)
614 die++;
615 snprintf(temp, sizeof(temp), "%s", oracle_combat_action[die]);
616 break;
617 case ORACLE_PLOT_TWISTS:
618 while (strlen(oracle_plot_twist[die]) == 0)
619 die++;
620 snprintf(temp, sizeof(temp), "%s", oracle_plot_twist[die]);
621 break;
622 case ORACLE_MYSTIC_BACKSLASH:
623 while (strlen(oracle_mystic_backslash[die]) == 0)
624 die++;
625 snprintf(temp, sizeof(temp), "%s", oracle_mystic_backslash[die]);
626 break;
627 case ORACLE_REGION:
628 while (strlen(oracle_regions[die]) == 0)
629 die++;
630 snprintf(temp, sizeof(temp), "%s", oracle_regions[die]);
631 break;
632 case ORACLE_LOCATION:
633 while (strlen(oracle_locations[die]) == 0)
634 die++;
635 snprintf(temp, sizeof(temp), "%s", oracle_locations[die]);
636 break;
637 case ORACLE_COASTAL:
638 while (strlen(oracle_coastal_locations[die]) == 0)
639 die++;
640 snprintf(temp, sizeof(temp), "%s", oracle_coastal_locations[die]);
641 break;
642 case ORACLE_DESCRIPTION:
643 while (strlen(oracle_location_descriptions[die]) == 0)
644 die++;
645 snprintf(temp, sizeof(temp), "%s", oracle_location_descriptions[die]);
646 break;
647 case ORACLE_PAYTHEPRICE:
648 while (strlen(oracle_pay_the_price[die]) == 0)
649 die++;
650 snprintf(temp, sizeof(temp), "%s", oracle_pay_the_price[die]);
651 break;
654 printf("%s (%ld)\n", temp, saved_die);