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 <json-c/json.h>
19 #include <errno.h>
20 #include <limits.h>
21 #include <string.h>
23 #include "isscrolls.h"
25 void
26 cmd_undertake_a_journey(char *cmd)
27 {
28 struct character *curchar = get_current_character();
29 char *ep;
30 long lval;
31 int ival[2] = { -1, -1 };
32 int ret;
34 if (curchar == NULL) {
35 printf("No character loaded. Use 'cd' to load a character\n");
36 return;
37 }
39 ival[0] = curchar->wits;
40 if (strlen(cmd) > 0) {
41 errno = 0;
42 lval = strtol(cmd, &ep, 10);
43 if (cmd[0] == '\0' || *ep != '\0') {
44 printf("Please provide a number as argument\n");
45 return;
46 }
47 if ((errno == ERANGE || lval <= 0 || lval > 10)) {
48 printf("Please provide a number between 1 and 10\n");
49 return;
50 }
52 ival[1] = lval;
53 log_debug("Arg provided %d\n", ival[1]);
54 }
56 if (curchar->journey_active == 0) {
57 ask_for_journey_difficulty();
58 curchar->journey_active = 1;
59 }
61 ret = action_roll(ival);
62 if (ret == 8) {
63 printf("You reach a waypoint and can choose one option -> Rulebook\n");
64 mark_journey_progress();
65 } else if (ret == 4) {
66 printf("You reach a waypoint, but suffer -1 supply\n");
67 change_char_value("supply", DECREASE, 1);
68 mark_journey_progress();
69 } else
70 printf("Pay the price -> Rulebook\n");
72 update_prompt();
73 }
75 void
76 cmd_reach_your_destination(char *cmd)
77 {
78 struct character *curchar = get_current_character();
79 double dval[2] = { -1.0, -1.0 };
80 int ret;
82 if (curchar == NULL) {
83 printf("No character loaded. Use 'cd' to load a character\n");
84 return;
85 }
87 if (curchar->journey_active == 0) {
88 printf("You must start a journey with 'undertakeajourney' first\n");
89 return;
90 }
92 dval[0] = curchar->j->progress;
93 dval[1] = get_int_from_cmd(cmd);
95 ret = progress_roll(dval);
96 if (ret == 8) {
97 printf("You reach your destination and the situation favors you -> "\
98 "Rulebook\n");
99 curchar->journey_active = 0;
100 curchar->j->progress = 0;
101 delete_journey(curchar->id);
102 } else if (ret == 4) {
103 printf("You reach your destination but face an unforseen complication "\
104 "-> Rulebook\n");
105 curchar->journey_active = 0;
106 curchar->j->progress = 0;
107 delete_journey(curchar->id);
108 } else {
109 reach_your_destination_failed();
112 update_prompt();
115 void
116 mark_journey_progress()
118 struct character *curchar = get_current_character();
120 if (curchar == NULL) {
121 log_debug("No character loaded. Cannot calculate progress\n");
122 return;
125 if (curchar->journey_active == 0) {
126 printf("You need start a journey before you can mark progress\n");
127 return;
130 switch (curchar->j->difficulty) {
131 case 1:
132 curchar->j->progress += 3;
133 break;
134 case 2:
135 curchar->j->progress += 2;
136 break;
137 case 3:
138 curchar->j->progress += 1;
139 break;
140 case 4:
141 curchar->j->progress += 0.5;
142 break;
143 case 5:
144 curchar->j->progress += 0.25;
145 break;
146 default:
147 curchar->j->difficulty = 1;
148 log_errx(1, "Unknown difficulty. This should not happen. Set it to 1\n");
151 if (curchar->j->progress > 10) {
152 printf("Your reached all milestones of your journey. Consider ending it\n");
153 curchar->j->progress = 10;
156 update_prompt();
159 void
160 reach_your_destination_failed()
162 struct character *curchar = get_current_character();
163 int a;
165 if (curchar == NULL) {
166 log_debug("No character loaded.\n");
167 return;
170 if (curchar->journey_active == 0) {
171 log_debug("No active journey.\n");
172 return;
175 printf("Please decide what to do\n\n");
176 printf("1\t - End your journey and pay the price -> Rulebook\n");
177 printf("2\t - Continue your journey -> progress is lost, difficulty +1\n");
179 a = ask_for_value("Enter a value between 1 and 2: ", 2);
180 if (a == 1) {
181 curchar->journey_active = 0;
182 curchar->j->progress = 0;
183 delete_journey(curchar->id);
184 } else {
185 curchar->j->progress = 0;
186 if (curchar->j->difficulty <= 5)
187 curchar->j->difficulty += 1;
191 void
192 save_journey()
194 struct character *curchar = get_current_character();
195 char path[_POSIX_PATH_MAX];
196 json_object *root, *items, *id;
197 int temp_n, i;
199 if (curchar == NULL) {
200 log_debug("No character loaded. No journey to save.\n");
201 return;
204 if (curchar->journey_active == 0) {
205 log_debug("No active journey to save.\n");
206 return;
209 json_object *cobj = json_object_new_object();
210 json_object_object_add(cobj, "id", json_object_new_int(curchar->id));
211 json_object_object_add(cobj, "difficulty",
212 json_object_new_int(curchar->j->difficulty));
213 json_object_object_add(cobj, "progress",
214 json_object_new_double(curchar->j->progress));
216 snprintf(path, sizeof(path), "%s/journey.json", get_isscrolls_dir());
217 if ((root = json_object_from_file(path)) == NULL) {
218 log_debug("No journey JSON file found\n");
219 root = json_object_new_object();
220 if (!root)
221 log_errx(1, "Cannot create journey JSON object\n");
223 items = json_object_new_array();
224 json_object_array_add(items, cobj);
225 json_object_object_add(root, "journey", items);
226 } else {
227 /* Get existing character array from JSON */
228 if (!json_object_object_get_ex(root, "journey", &items)) {
229 log_debug("Cannot find a [journey] array in %s\n", path);
230 items = json_object_new_array();
231 json_object_object_add(root, "journey", items);
234 temp_n = json_object_array_length(items);
235 for (i = 0; i < temp_n; i++) {
236 json_object *temp = json_object_array_get_idx(items, i);
237 json_object_object_get_ex(temp, "id", &id);
238 if (curchar->id == json_object_get_int(id)) {
239 log_debug("Update journey entry for %s\n", curchar->name);
240 json_object_array_del_idx(items, i, 1);
241 json_object_array_add(items, cobj);
242 goto out;
245 log_debug("No journey entry for %s found, adding new one\n", curchar->name);
246 json_object_array_add(items, cobj);
249 out:
250 if (json_object_to_file(path, root))
251 printf("Error saving %s\n", path);
252 else
253 log_debug("Successfully saved %s\n", path);
255 json_object_put(root);
258 void
259 delete_journey(int id)
261 char path[_POSIX_PATH_MAX];
262 json_object *root, *lid;
263 int temp_n, i;
265 snprintf(path, sizeof(path), "%s/journey.json", get_isscrolls_dir());
266 if ((root = json_object_from_file(path)) == NULL) {
267 log_debug("No journey JSON file found\n");
268 return;
271 json_object *journey;
272 if (!json_object_object_get_ex(root, "journey", &journey)) {
273 log_debug("Cannot find a [journey] array in %s\n", path);
274 return;
277 temp_n = json_object_array_length(journey);
278 for (i = 0; i < temp_n; i++) {
279 json_object *temp = json_object_array_get_idx(journey, i);
280 json_object_object_get_ex(temp, "id", &lid);
281 if (id == json_object_get_int(lid)) {
282 json_object_array_del_idx(journey, i, 1);
283 log_debug("Deleted journey entry for %d\n", id);
287 if (json_object_to_file(path, root))
288 printf("Error saving %s\n", path);
289 else
290 log_debug("Successfully saved %s\n", path);
292 json_object_put(root);
295 void
296 load_journey(int id)
298 struct character *curchar = get_current_character();
299 char path[_POSIX_PATH_MAX];
300 json_object *root, *lid;
301 int temp_n, i;
303 if (curchar == NULL) {
304 log_debug("No character loaded\n");
305 return;
308 snprintf(path, sizeof(path), "%s/journey.json", get_isscrolls_dir());
309 if ((root = json_object_from_file(path)) == NULL) {
310 log_debug("No journey JSON file found\n");
311 return;
314 json_object *journey;
315 if (!json_object_object_get_ex(root, "journey", &journey)) {
316 log_debug("Cannot find a [journey] array in %s\n", path);
317 return;
320 temp_n = json_object_array_length(journey);
321 for (i=0; i < temp_n; i++) {
322 json_object *temp = json_object_array_get_idx(journey, i);
323 json_object_object_get_ex(temp, "id", &lid);
324 if (id == json_object_get_int(lid)) {
325 log_debug("Loading journey for id: %d\n", json_object_get_int(lid));
327 json_object *cval;
328 json_object_object_get_ex(temp, "difficulty", &cval);
329 curchar->j->difficulty = json_object_get_int(cval);
330 json_object_object_get_ex(temp, "progress", &cval);
331 curchar->j->progress = json_object_get_double(cval);
335 json_object_put(root);