home · contact · privacy
ed41d93ac62f30ab65c5fd194182782a8d034156
[plomrogue] / src / map_objects.c
1 /* map_objects.c */
2
3 #include "map_objects.h"
4 #include <stdlib.h> /* for free(), atoi() */
5 #include <stdint.h> /* for uint8_t */
6 #include <stdio.h> /* for FILE typedef */
7 #include <string.h> /* for strchr(), strlen(), memcpy(), strtok() */
8 #include "readwrite.h" /* for get_linemax(), try_fopen(), try_fclose()
9                         * [read/write]_uint[8/16/23][_bigendian]()
10                         */
11 #include "misc.h" /* for try_malloc(), try_calloc(), find_passable_pos() */
12 #include "main.h" /* for World struct */
13 #include "rexit.h" /* for err_exit() */
14 #include "yx_uint16.h" /* for yx_uint16 struct, yx_uint16_cmp() */
15
16
17
18 extern void init_map_object_defs(struct World * world, char * filename)
19 {
20     char * f_name = "init_map_object_defs()";
21     FILE * file = try_fopen(filename, "r", world, f_name);
22     uint16_t linemax = get_linemax(file, world, f_name);
23     struct MapObjDef ** last_mod_ptr_ptr = &world->map_obj_defs;
24     char * delim = " ";
25     char line[linemax + 1];
26     while (try_fgets(line, linemax + 1, file, world, f_name))
27     {
28         struct MapObjDef * mod;
29         mod = try_malloc(sizeof(struct MapObjDef), world, f_name);
30         mod->next = NULL;
31         mod->id = atoi(strtok(line, delim));
32         mod->corpse_id = atoi(strtok(NULL, delim));
33         mod->char_on_map = * strtok(NULL, delim);
34         mod->lifepoints = atoi(strtok(NULL, delim));
35         char * name = strtok(NULL, "\n");
36         mod->name = try_malloc(strlen(name) + 1, world, f_name);
37         memcpy(mod->name, name, strlen(name) + 1);
38         * last_mod_ptr_ptr = mod;
39         last_mod_ptr_ptr = &mod->next;
40     }
41     try_fclose(file, world, f_name);
42 }
43
44
45
46 extern void free_map_object_defs(struct MapObjDef * mod_start)
47 {
48     if (NULL == mod_start)
49     {
50         return;
51     }
52     free_map_object_defs(mod_start->next);
53     free(mod_start->name);
54     free(mod_start);
55 }
56
57
58
59 extern void write_map_objects(struct World * world, FILE * file)
60 {
61     char * f_name = "write_map_objects()";
62     struct MapObj * mo = world->map_objs;
63     uint8_t size = 3 + 1 + 3 + 1 + 3 + 1 + 5 + 1 + 5 + 1;
64     char line[size];
65     while (NULL != mo)
66     {
67         sprintf(line, "%d %d %d %d %d\n",
68                 mo->id, mo->type, mo->lifepoints, mo->pos.y, mo->pos.x);
69         try_fwrite(line, strlen(line), 1, file, world, f_name);
70         mo = mo->next;
71     }
72 }
73
74
75
76 extern void read_map_objects(struct World * world, FILE * file, char * line,
77                               int linemax)
78 {
79     char * f_name = "read_map_objects()";
80     struct MapObj ** mo_ptr_ptr = &world->map_objs;
81     char * delim = " ";
82     struct MapObj * mo;
83     while (try_fgets(line, linemax + 1, file, world, f_name))
84     {
85         mo = malloc(sizeof(struct MapObj));
86         mo->next = NULL;
87         mo->id = atoi(strtok(line, delim));
88         if (mo->id > world->map_obj_count)
89         {
90             world->map_obj_count = mo->id;
91         }
92         mo->type = atoi(strtok(NULL, delim));
93         mo->lifepoints = atoi(strtok(NULL, delim));
94         mo->pos.y = atoi(strtok(NULL, delim));
95         mo->pos.x = atoi(strtok(NULL, delim));
96         * mo_ptr_ptr = mo;
97         mo_ptr_ptr = &mo->next;
98     }
99 }
100
101
102
103 extern void add_map_object(struct World * world, uint8_t type)
104 {
105     char * f_name = "add_map_object";
106     struct MapObjDef * mod = get_map_object_def(world, type);
107     struct MapObj * mo = try_malloc(sizeof(struct MapObj), world, f_name);
108     mo->id = world->map_obj_count;
109     world->map_obj_count++;
110     mo->type = mod->id;
111     mo->lifepoints = mod->lifepoints;
112     while (1)
113     {
114         struct yx_uint16 pos = find_passable_pos(world->map);
115         struct MapObj * mo_ptr;
116         uint8_t clear = 1;
117         for (mo_ptr = world->map_objs;
118              mo_ptr != NULL;
119              mo_ptr = mo_ptr->next)
120         {
121             if (yx_uint16_cmp(&pos, &mo_ptr->pos) && 0 != mo_ptr->lifepoints)
122             {
123                 clear = 0;
124                 break;
125             }
126         }
127         if (1 == clear)
128         {
129             mo->pos = pos;
130             break;
131         }
132     }
133     mo->next = NULL;
134     struct MapObj ** last_ptr_ptr = &world->map_objs;
135     struct MapObj * mo_ptr;
136     while (NULL != * last_ptr_ptr)
137     {
138         mo_ptr = * last_ptr_ptr;
139         last_ptr_ptr = & mo_ptr->next;
140     }
141     * last_ptr_ptr = mo;
142 }
143
144
145
146 extern void add_map_objects(struct World * world, uint8_t type, uint8_t n)
147 {
148     uint8_t i;
149     for (i = 0; i < n; i++)
150     {
151         add_map_object(world, type);
152     }
153 }
154
155
156
157 extern void free_map_objects(struct MapObj * mo_start)
158 {
159     if (NULL == mo_start)
160     {
161         return;
162     }
163     free_map_objects(mo_start->next);
164     free(mo_start);
165 }
166
167
168
169 extern struct MapObj * get_player(struct World * world)
170 {
171     struct MapObj * ptr = world->map_objs;
172     while (1)
173     {
174         if (NULL == ptr)
175         {
176             return ptr;
177         }
178         if (0 == ptr->id)
179         {
180             return ptr;
181         }
182         ptr = ptr->next;
183     }
184 }
185
186
187
188 extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id)
189 {
190     struct MapObjDef * mod = w->map_obj_defs;
191     while (id != mod->id)
192     {
193         mod = mod->next;
194     }
195     return mod;
196 }