Line data Source code
1 : /*
2 : Created by Daniel Monteiro on 2019-07-26.
3 : */
4 : #include <stddef.h>
5 :
6 : #ifdef __MWERKS__
7 : #define CLI_BUILD
8 : #endif
9 :
10 : #ifndef SMD
11 :
12 : #include <assert.h>
13 : #include <stdlib.h>
14 : #include <stdio.h>
15 : #include <string.h>
16 :
17 : #ifdef WIN32
18 : #include "Win32Int.h"
19 : #else
20 :
21 : #include <stdint.h>
22 :
23 : #endif
24 : #else
25 : #include <genesis.h>
26 : #endif
27 :
28 : #include "Enums.h"
29 : #include "Common.h"
30 : #include "Core.h"
31 :
32 : #define WALK_STEP 1
33 :
34 : /**
35 : * there's an implicit dummy first
36 : */
37 : int roomCount = 1;
38 : /**
39 : *
40 : */
41 : struct Room rooms[TOTAL_ROOMS];
42 : /**
43 : *
44 : */
45 : uint8_t itemsCount = 0;
46 : /**
47 : *
48 : */
49 : struct Item item[TOTAL_ITEMS];
50 : /*
51 : *
52 : */
53 : struct ObjectNode objectNodes[TOTAL_ITEMS];
54 : /**
55 : *
56 : */
57 : struct ObjectNode collectedObjectHead;
58 : /**
59 : *
60 : */
61 : struct ObjectNode roomObjectHeads[TOTAL_ROOMS];
62 : /**
63 : *
64 : */
65 : struct ObjectNode *collectedObject = NULL;
66 : /**
67 : *
68 : */
69 : uint8_t playerLocation = 1;
70 : /**
71 : *
72 : */
73 : enum EDirection playerDirection;
74 : /**
75 : *
76 : */
77 : uint8_t playerRank;
78 : /**
79 : *
80 : */
81 : enum EGameStates gameStatus;
82 : /**
83 : *
84 : */
85 : struct WorldPosition playerPosition;
86 : /**
87 : *
88 : */
89 : ErrorHandlerCallback errorHandlerCallback = NULL;
90 :
91 8 : void writeToLog(const char *errorMsg) {
92 : #ifdef HAS_STDIO
93 : if (errorHandlerCallback == NULL) {
94 : puts("-------");
95 : puts(errorMsg);
96 : puts("--!!---");
97 : } else {
98 : errorHandlerCallback(errorMsg);
99 : }
100 : #else
101 : /* We assume the error handler was already set. If you don't have stdio, you probably know what you're doing */
102 8 : errorHandlerCallback(errorMsg);
103 : #endif
104 8 : }
105 :
106 2 : void cantBeUsedCallback(struct Item *item) {
107 : (void)item;
108 2 : defaultLogger("You can't use it like this.");
109 2 : }
110 :
111 1 : void cantBeUsedWithOthersCallback(struct Item *item1, struct Item *item2) {
112 : (void)item1;
113 : (void)item2;
114 1 : defaultLogger("Nothing happens.");
115 1 : }
116 :
117 1866 : struct Item *addItem(const char *description,
118 : #ifdef INCLUDE_ITEM_DESCRIPTIONS
119 : const char *info,
120 : #endif
121 : #ifdef ITEMS_HAVE_WEIGHT
122 : uint8_t weight,
123 : #endif
124 : uint8_t pickable,
125 : int8_t positionX,
126 : int8_t positionY) {
127 :
128 1866 : struct Item *toReturn = &item[itemsCount];
129 :
130 1866 : toReturn->index = itemsCount++;
131 1866 : toReturn->name = description;
132 : #ifdef INCLUDE_ITEM_DESCRIPTIONS
133 : toReturn->info = info;
134 : #endif
135 1866 : toReturn->pickable = pickable;
136 1866 : toReturn->position.x = positionX;
137 1866 : toReturn->position.y = positionY;
138 :
139 1866 : toReturn->useCallback = cantBeUsedCallback;
140 1866 : toReturn->useWithCallback = cantBeUsedWithOthersCallback;
141 :
142 1866 : return toReturn;
143 : }
144 :
145 1219 : struct Room *addRoom(
146 : const char *name,
147 : #ifdef INCLUDE_ROOM_DESCRIPTIONS
148 : const char *info,
149 : #endif
150 : uint8_t sizeX, uint8_t sizeY, uint8_t chanceOfRandomBattle, const int8_t connections[6]) {
151 :
152 1219 : struct Room *toReturn = &rooms[roomCount];
153 1219 : toReturn->name = name;
154 : #ifdef INCLUDE_ROOM_DESCRIPTIONS
155 : toReturn->info = info;
156 : #endif
157 1219 : toReturn->sizeX = sizeX;
158 1219 : toReturn->sizeY = sizeY;
159 1219 : toReturn->chanceOfRandomBattle = chanceOfRandomBattle;
160 :
161 1219 : memCopyToFrom((void*)toReturn->connections, (void*)connections, 6);
162 :
163 : /* add list head to make manipulations easier */
164 1219 : toReturn->itemsPresent = &roomObjectHeads[roomCount++];
165 1219 : memFill(toReturn->itemsPresent, 0, sizeof(struct ObjectNode));
166 :
167 1219 : return toReturn;
168 : }
169 :
170 : LogDelegate defaultLogger = writeToLog;
171 :
172 59 : void setErrorHandlerCallback(ErrorHandlerCallback callback) {
173 59 : errorHandlerCallback = callback;
174 59 : }
175 :
176 146 : struct WorldPosition *getPlayerPosition(void) {
177 146 : return &playerPosition;
178 : }
179 :
180 4 : void setPlayerPosition(struct WorldPosition *pos) {
181 4 : playerPosition.x = pos->x;
182 4 : playerPosition.y = pos->y;
183 4 : }
184 :
185 : #ifndef CAN_PICK_OBJECT_AT_ANY_DISTANCE
186 129 : uint8_t isCloseToObject(struct WorldPosition *pos, struct Item *_item) {
187 129 : return (abs(pos->x - _item->position.x) + abs(pos->y - _item->position.y)) <= 1;
188 : }
189 : #endif
190 :
191 14 : enum EGameStates getGameStatus(void) {
192 14 : return gameStatus;
193 : }
194 :
195 24 : struct ObjectNode *getPlayerItems(void) {
196 24 : return collectedObject->next;
197 : }
198 :
199 104 : struct Item *getItemNamed(const char *name) {
200 : uint8_t c;
201 :
202 1221 : for (c = 0; c < itemsCount; ++c) {
203 1220 : if (!strcmp(item[c].name, name)) {
204 103 : return &item[c];
205 : }
206 : }
207 :
208 1 : return NULL;
209 : }
210 :
211 : #ifdef MORE_OBJECTS
212 17 : uint8_t getRoomIdByName(const char *name) {
213 : uint8_t c;
214 :
215 17 : if (name != NULL) {
216 215 : for (c = 1; c < roomCount; ++c) {
217 214 : if (!strcmp(rooms[c].name, name)) {
218 15 : return c;
219 : }
220 : }
221 : }
222 :
223 2 : return 0;
224 : }
225 : #endif
226 :
227 87 : struct Room *getRoomByName(const char *name) {
228 : uint8_t c;
229 :
230 87 : if (name != NULL) {
231 724 : for (c = 1; c < roomCount; ++c) {
232 723 : if (!strcmp(rooms[c].name, name)) {
233 86 : return &rooms[c];
234 : }
235 : }
236 : }
237 :
238 1 : return NULL;
239 : }
240 :
241 1714 : void addObjectToList(struct Item *itemToAdd, struct ObjectNode *listHead) {
242 1714 : struct ObjectNode *head = listHead;
243 :
244 2697 : while (head->next != NULL) {
245 984 : if (getItem(head->item) == itemToAdd) {
246 : /* Object already belongs to the list! */
247 1 : return;
248 : }
249 :
250 983 : head = head->next;
251 : }
252 :
253 1713 : head->next = &objectNodes[itemToAdd->index];
254 1713 : memFill(head->next, 0, sizeof(struct ObjectNode));
255 1713 : head->next->item = itemToAdd->index;
256 : }
257 :
258 49 : void removeObjectFromList(struct Item *itemToRemove, struct ObjectNode *listHead) {
259 49 : struct ObjectNode *head = listHead->next;
260 49 : struct ObjectNode *prev = listHead;
261 :
262 134 : while (head != NULL) {
263 134 : if (head->item == itemToRemove->index) {
264 49 : prev->next = head->next;
265 49 : return;
266 : }
267 :
268 85 : prev = head;
269 85 : head = head->next;
270 : }
271 : /* Object doesn't belong to the list! */
272 : }
273 :
274 1712 : void removeObjectFromRoom(struct Item *itemToRemove) {
275 1712 : if (itemToRemove->roomId != 0) {
276 38 : removeObjectFromList(itemToRemove, rooms[itemToRemove->roomId].itemsPresent);
277 38 : itemToRemove->roomId = 0;
278 : }
279 1712 : }
280 :
281 :
282 1583 : void addObjectToRoom(uint8_t roomId, struct Item *itemToAdd) {
283 1583 : struct Room *roomToAddObject = &rooms[roomId];
284 1583 : removeObjectFromRoom(itemToAdd);
285 1583 : addObjectToList(itemToAdd, roomToAddObject->itemsPresent);
286 1583 : itemToAdd->roomId = roomId;
287 1583 : }
288 :
289 11 : void dropObjectToRoom(uint8_t roomId, struct Item *itemToDrop) {
290 : #ifdef CLI_BUILD
291 11 : if (itemToDrop->roomId != 0) {
292 0 : defaultLogger("Object not present to drop");
293 : }
294 : #endif
295 :
296 11 : if (!itemToDrop->pickable) {
297 0 : defaultLogger("Can't drop this");
298 0 : return;
299 : }
300 :
301 11 : removeObjectFromList(itemToDrop, collectedObject);
302 11 : addObjectToRoom(roomId, itemToDrop);
303 :
304 11 : if (itemToDrop->dropCallback != NULL) {
305 7 : itemToDrop->dropCallback(itemToDrop);
306 : }
307 : }
308 :
309 129 : void pickObject(struct Item *itemToPick) {
310 : #ifndef CAN_PICK_OBJECT_AT_ANY_DISTANCE
311 129 : if (!isCloseToObject(getPlayerPosition(), itemToPick)) {
312 0 : return;
313 : }
314 : #endif
315 :
316 129 : if (!itemToPick->pickable) {
317 1 : defaultLogger("Can't pick it up");
318 1 : return;
319 : }
320 :
321 128 : removeObjectFromRoom(itemToPick);
322 128 : addObjectToList(itemToPick, collectedObject);
323 :
324 128 : if (itemToPick->pickCallback != NULL) {
325 14 : itemToPick->pickCallback(itemToPick);
326 : }
327 : }
328 :
329 10 : uint8_t getPlayerRank(void) {
330 10 : return playerRank;
331 : }
332 :
333 28 : void setPlayerRank(uint8_t newRank) {
334 28 : playerRank = newRank;
335 28 : }
336 :
337 18 : void moveBy(uint8_t direction) {
338 : uint8_t c;
339 18 : uint8_t previousLocation = playerLocation;
340 :
341 18 : struct Room *room = &rooms[playerLocation];
342 25 : if (direction <= 5 && room->connections[direction] != 0) {
343 14 : struct Item *coupling = getItemNamed("magnetic-coupling");
344 14 : room = &rooms[playerLocation];
345 :
346 14 : if (rooms[room->connections[direction]].rankRequired > playerRank) {
347 3 : defaultLogger("Insufficient rank to enter room");
348 3 : return;
349 : }
350 :
351 11 : if (room == getRoomByName("hangar") && coupling->active && direction == 0) {
352 0 : defaultLogger("The magnetic coupling is\nengaged. The door won't open.");
353 0 : return;
354 : }
355 :
356 11 : playerLocation = room->connections[direction];
357 11 : room = &rooms[playerLocation];
358 :
359 11 : if (direction < 4) {
360 49 : for (c = 0; c < 6; ++c) {
361 42 : if (room->connections[c] == previousLocation) {
362 7 : direction = c;
363 : }
364 : }
365 : } else {
366 4 : return;
367 : }
368 :
369 7 : switch (direction) {
370 5 : case 2:
371 5 : playerPosition.x = rooms[playerLocation].sizeX / 2;
372 5 : playerPosition.y = rooms[playerLocation].sizeY - 1;
373 5 : break;
374 :
375 1 : case 3:
376 1 : playerPosition.x = 0;
377 1 : playerPosition.y = rooms[playerLocation].sizeY / 2;
378 1 : break;
379 :
380 0 : case 1:
381 0 : playerPosition.x = rooms[playerLocation].sizeX - 1;
382 0 : playerPosition.y = rooms[playerLocation].sizeY / 2;
383 0 : break;
384 1 : case 0:
385 : default:
386 1 : playerPosition.x = rooms[playerLocation].sizeX / 2;
387 1 : playerPosition.y = 0;
388 1 : break;
389 : }
390 : #ifdef CLI_BUILD
391 4 : } else if ( errorHandlerCallback) {
392 2 : errorHandlerCallback("Please specify a valid direction");
393 : #endif
394 : }
395 : }
396 :
397 24 : void pickObjectByName(const char *objName) {
398 24 : struct Room *room = &rooms[playerLocation];
399 24 : struct ObjectNode *itemToPick = room->itemsPresent->next;
400 :
401 84 : while (itemToPick != NULL) {
402 83 : if (!strcmp(getItem(itemToPick->item)->name, objName)) {
403 : #ifdef MOVE_TO_OBJECT_POSITION_WHEN_PICKING
404 23 : playerPosition = getItem(itemToPick->item)->position;
405 : #endif
406 23 : pickObject(getItem(itemToPick->item));
407 23 : return;
408 : }
409 60 : itemToPick = itemToPick->next;
410 : }
411 : }
412 :
413 12 : void dropObjectByName(const char *objName) {
414 12 : struct ObjectNode *itemToPick = collectedObject->next;
415 :
416 :
417 37 : while (itemToPick != NULL) {
418 36 : if (!strcmp(getItem(itemToPick->item)->name, objName)) {
419 11 : dropObjectToRoom(playerLocation, getItem(itemToPick->item));
420 11 : return;
421 : }
422 25 : itemToPick = itemToPick->next;
423 : }
424 :
425 : #ifdef CLI_BUILD
426 1 : errorHandlerCallback("Unable to locate object");
427 : #endif
428 :
429 : }
430 :
431 68 : uint8_t hasItemInRoom(const char *roomName, const char *itemName) {
432 : struct ObjectNode *itemToPick;
433 :
434 : #ifdef CLI_BUILD
435 : struct Room* room;
436 :
437 68 : if (roomName == NULL || itemName == NULL || strlen(roomName) == 0 || strlen(itemName) == 0) {
438 4 : defaultLogger("Either the object name or the room name are null. Check your stuff");
439 4 : return 0;
440 : }
441 : #endif
442 :
443 : #ifdef CLI_BUILD
444 64 : room = getRoomByName(roomName);
445 :
446 64 : if (room != NULL) {
447 63 : itemToPick = room->itemsPresent->next;
448 : } else {
449 1 : errorHandlerCallback("Invalid room name");
450 1 : return 0;
451 : }
452 : #else
453 : itemToPick = getRoomByName(roomName)->itemsPresent->next;
454 : #endif
455 :
456 199 : while (itemToPick != NULL) {
457 167 : struct Item *pick = getItem(itemToPick->item);
458 167 : if (!strcmp(pick->name, itemName)) {
459 31 : return 1;
460 : }
461 136 : itemToPick = itemToPick->next;
462 : }
463 :
464 32 : return 0;
465 : }
466 :
467 91 : uint8_t playerHasObject(const char *itemName) {
468 91 : struct ObjectNode *itemToPick = collectedObject->next;
469 :
470 322 : while (itemToPick != NULL) {
471 255 : if (!strcmp(getItem(itemToPick->item)->name, itemName)) {
472 24 : return 1;
473 : }
474 231 : itemToPick = itemToPick->next;
475 : }
476 67 : return 0;
477 : }
478 :
479 :
480 11 : uint8_t isPlayerAtRoom(const char *roomName) {
481 11 : struct Room *room = &rooms[playerLocation];
482 11 : const char *name = room->name;
483 11 : uint8_t returnValue = !strcmp(name, roomName);
484 11 : return returnValue;
485 : }
486 :
487 0 : const char *getRoomDescription(void) {
488 0 : struct Room *room = &rooms[playerLocation];
489 0 : return room->name;
490 : }
491 :
492 53 : struct Room *getRoom(uint8_t index) {
493 53 : return &rooms[index];
494 : }
495 :
496 1710 : struct Item *getItem(uint8_t index) {
497 1710 : return &item[index];
498 : }
499 :
500 51 : uint8_t getPlayerRoom(void) {
501 51 : return playerLocation;
502 : }
503 :
504 23 : void useObjectNamed(const char *operand) {
505 23 : struct ObjectNode *itemToPick = getPlayerItems();
506 :
507 69 : while (itemToPick != NULL) {
508 49 : struct Item *_item = getItem(itemToPick->item);
509 49 : if (!strcmp(_item->name, operand)) {
510 3 : if (_item->useCallback != NULL) {
511 3 : _item->useCallback(_item);
512 : }
513 3 : return;
514 : }
515 46 : itemToPick = itemToPick->next;
516 : }
517 :
518 20 : itemToPick = getRoom(playerLocation)->itemsPresent->next;
519 :
520 36 : while (itemToPick != NULL) {
521 33 : struct Item *_item = getItem(itemToPick->item);
522 33 : if (!strcmp(_item->name, operand)) {
523 17 : if (_item->useCallback != NULL) {
524 17 : _item->useCallback(_item);
525 : }
526 17 : return;
527 : }
528 16 : itemToPick = itemToPick->next;
529 : }
530 : }
531 :
532 : #ifdef CLI_BUILD
533 4 : void walkTo(const char *operands) {
534 : struct WorldPosition pos;
535 : char *xStr;
536 : char *yStr;
537 : int8_t x;
538 : int8_t y;
539 :
540 4 : xStr = (char*)operands;
541 4 : yStr = strtok(NULL, "\n ");
542 4 : x = atoi(xStr);
543 4 : y = atoi(yStr);
544 4 : pos.x = x;
545 4 : pos.y = y;
546 4 : setPlayerPosition(&pos);
547 4 : }
548 :
549 : #ifdef INCLUDE_ITEM_DESCRIPTIONS
550 : void infoAboutItemNamed(const char *itemName) {
551 :
552 : struct ObjectNode *object1 = collectedObject->next;
553 : struct Room *room = &rooms[playerLocation];
554 : struct ObjectNode *object2 = room->itemsPresent->next;
555 :
556 : if (itemName == NULL || strlen(itemName) == 0) {
557 : #ifdef INCLUDE_ROOM_DESCRIPTIONS
558 : defaultLogger(room->info);
559 : #endif
560 : return;
561 : }
562 :
563 : while (object1 != NULL) {
564 : struct Item* item = getItem(object1->item);
565 : assert(item->name != NULL);
566 :
567 : if (!strcmp(item->name, itemName)) {
568 : defaultLogger(item->info);
569 : return;
570 : }
571 : object1 = object1->next;
572 : }
573 :
574 : while (object2 != NULL) {
575 : struct Item* item = getItem(object2->item);
576 : assert(item->name != NULL);
577 :
578 : if (!strcmp(item->name, itemName)) {
579 : defaultLogger(item->info);
580 : return;
581 : }
582 : object2 = object2->next;
583 : }
584 : #ifdef CLI_BUILD
585 : defaultLogger("No such item could be found");
586 : #endif
587 : }
588 : #endif
589 :
590 2 : void useObjectsTogether(const char *operands) {
591 :
592 2 : struct ObjectNode *object1 = collectedObject->next;
593 2 : struct Room *room = &rooms[playerLocation];
594 2 : struct ObjectNode *object2 = room->itemsPresent->next;
595 :
596 2 : char *operand1 = (char*)operands;
597 2 : char *operand2 = strtok(NULL, "\n ");
598 :
599 2 : if (!playerHasObject(operand1)) {
600 : #ifdef CLI_BUILD
601 0 : defaultLogger("You do not have this object");
602 : #endif
603 0 : return;
604 : }
605 :
606 2 : if (!hasItemInRoom(getRoom(playerLocation)->name, operand2)) {
607 : #ifdef CLI_BUILD
608 0 : defaultLogger("That object is not present in the room");
609 : #endif
610 0 : return;
611 : }
612 :
613 6 : while (object1 != NULL) {
614 6 : struct Item* _item = getItem(object1->item);
615 6 : assert(_item->name != NULL);
616 :
617 6 : if (!strcmp(_item->name, operand1)) {
618 2 : goto got_first_object;
619 : }
620 4 : object1 = object1->next;
621 : }
622 :
623 0 : got_first_object:
624 5 : while (object2 != NULL) {
625 5 : struct Item* _item = getItem(object2->item);
626 5 : assert(_item->name != NULL);
627 :
628 5 : if (!strcmp(_item->name, operand2)) {
629 2 : goto got_second_object;
630 : }
631 3 : object2 = object2->next;
632 : }
633 :
634 0 : got_second_object:
635 2 : if (object1 != NULL){
636 2 : struct Item* _item = getItem(object1->item);
637 :
638 2 : if (_item != NULL && _item->useWithCallback != NULL && object2 != NULL) {
639 2 : _item->useWithCallback(_item, getItem(object2->item));
640 : }
641 : }
642 : }
643 : #endif
644 :
645 4 : void turnLeft(void) {
646 4 : uint8_t pDir = (uint8_t) playerDirection;
647 4 : pDir--;
648 :
649 4 : pDir = pDir & 3;
650 4 : playerDirection = (enum EDirection)pDir;
651 4 : }
652 :
653 4 : void turnRight(void) {
654 4 : uint8_t pDir = (uint8_t) playerDirection;
655 4 : pDir++;
656 :
657 4 : pDir = pDir & 3;
658 4 : playerDirection = (enum EDirection)pDir;
659 4 : }
660 :
661 18 : void setPlayerLocation(uint8_t location) {
662 18 : playerLocation = location;
663 18 : }
664 :
665 19 : void walkBy(uint8_t direction) {
666 :
667 19 : switch (direction) {
668 5 : case 1:
669 5 : switch (playerDirection) {
670 1 : case 1:
671 1 : playerPosition.y += WALK_STEP;
672 1 : break;
673 1 : case 2:
674 1 : playerPosition.x -= WALK_STEP;
675 1 : break;
676 1 : case 3:
677 1 : playerPosition.y -= WALK_STEP;
678 1 : break;
679 2 : case 0:
680 : default:
681 2 : playerPosition.x += WALK_STEP;
682 2 : break;
683 : }
684 5 : break;
685 5 : case 2:
686 5 : switch (playerDirection) {
687 1 : case 1:
688 1 : playerPosition.x -= WALK_STEP;
689 1 : break;
690 1 : case 2:
691 1 : playerPosition.y -= WALK_STEP;
692 1 : break;
693 1 : case 3:
694 1 : playerPosition.x += WALK_STEP;
695 1 : break;
696 2 : case 0:
697 : default:
698 2 : playerPosition.y += WALK_STEP;
699 2 : break;
700 : }
701 5 : break;
702 5 : case 3:
703 5 : switch (playerDirection) {
704 1 : case 1:
705 1 : playerPosition.y -= WALK_STEP;
706 1 : break;
707 1 : case 2:
708 1 : playerPosition.x += WALK_STEP;
709 1 : break;
710 1 : case 3:
711 1 : playerPosition.y += WALK_STEP;
712 1 : break;
713 2 : case 0:
714 : default:
715 2 : playerPosition.x -= WALK_STEP;
716 2 : break;
717 : }
718 5 : break;
719 4 : case 0:
720 : default:
721 4 : switch (playerDirection) {
722 1 : case 1:
723 1 : playerPosition.x += WALK_STEP;
724 1 : break;
725 1 : case 2:
726 1 : playerPosition.y += WALK_STEP;
727 1 : break;
728 1 : case 3:
729 1 : playerPosition.x -= WALK_STEP;
730 1 : break;
731 1 : case 0:
732 : default:
733 1 : playerPosition.y -= WALK_STEP;
734 1 : break;
735 : }
736 4 : break;
737 : }
738 :
739 : #ifdef CLI_BUILD
740 19 : if (playerPosition.x < 0) {
741 1 : playerPosition.x = 0;
742 : }
743 :
744 19 : if (playerPosition.y < 0) {
745 0 : playerPosition.y = 0;
746 : }
747 :
748 :
749 19 : if (playerPosition.x >= rooms[playerLocation].sizeX) {
750 1 : playerPosition.x = rooms[playerLocation].sizeX - 1;
751 : }
752 :
753 19 : if (playerPosition.y >= rooms[playerLocation].sizeY) {
754 1 : playerPosition.y = rooms[playerLocation].sizeY - 1;
755 : }
756 : #endif
757 19 : }
758 :
759 10 : enum EDirection getPlayerDirection(void) {
760 10 : return playerDirection;
761 : }
762 :
763 1565 : void addToRoom(const char *roomName, struct Item *itemName) {
764 : uint8_t r;
765 :
766 : #ifdef CLI_BUILD
767 1565 : if (roomName == NULL || itemName == NULL || strlen(roomName) == 0) {
768 3 : defaultLogger("Either the object name or the room name are null. Check your stuff");
769 3 : return;
770 : }
771 : #endif
772 :
773 18532 : for (r = 1; r < TOTAL_ROOMS; ++r) {
774 18531 : const char *desc = rooms[r].name;
775 :
776 18531 : if (desc != NULL && !strcmp(desc, roomName)) {
777 1561 : addObjectToRoom(r, itemName);
778 1561 : return;
779 : }
780 : }
781 :
782 : #ifdef CLI_BUILD
783 1 : defaultLogger("It was not possible to determine the room to add object");
784 : #endif
785 : }
786 :
787 38 : void setLoggerDelegate(LogDelegate newDelegate) {
788 38 : defaultLogger = newDelegate;
789 38 : }
790 :
791 :
792 1 : void setPlayerDirection(enum EDirection direction) {
793 1 : playerDirection = direction;
794 1 : }
795 :
796 7 : void setGameStatus(enum EGameStates newStatus) {
797 7 : gameStatus = newStatus;
798 7 : }
799 :
800 53 : void initCore(void) {
801 53 : defaultLogger = writeToLog;
802 : /* prepare for a single player in the game */
803 53 : memFill(&playerPosition, 0, sizeof(struct WorldPosition));
804 53 : setErrorHandlerCallback(NULL);
805 :
806 53 : collectedObject = &collectedObjectHead;
807 53 : memFill(collectedObject, 0, sizeof(struct ObjectNode));
808 53 : playerLocation = 1;
809 53 : itemsCount = 0;
810 53 : roomCount = 1; /* there's an implicit dummy first */
811 53 : playerRank = 0;
812 53 : gameStatus = kNormalGameplay;
813 53 : playerDirection = kNorth;
814 53 : playerPosition.x = 15;
815 53 : playerPosition.y = 15;
816 :
817 53 : memFill(&rooms, 0, TOTAL_ROOMS * sizeof(struct Room));
818 53 : memFill(&item, 0, TOTAL_ITEMS * sizeof(struct Item));
819 53 : }
820 :
821 :
822 :
823 :
|