home · contact · privacy
Use bit shifting instead of magic number in rrand().
[plomrogue] / src / map_objects.c
1 /* map_objects.c */
2
3 #include "map_objects.h"
4 #include <stdlib.h> /* for malloc(), calloc(), free(), atoi() */
5 #include <stdio.h> /* for FILE typedef */
6 #include <string.h> /* for strchr(), strlen(), memcpy()  */
7 #include "readwrite.h" /* for all the map object (def) loading/saving */
8 #include "misc.h" /* for textfile_sizes(), find_passable_pos() */
9 #include "main.h" /* for World struct */
10
11
12
13 /* Return pointer to newly allocated map object struct of size "size". If first
14  * in map object chain ("first" pointing to !0), point "start" to it.
15  */
16 static struct MapObj * get_next_map_obj(void * start, char * first,
17                                         size_t size, struct MapObj * map_obj);
18
19
20
21 static struct MapObj * get_next_map_obj(void * start, char * first,
22                                         size_t size, struct MapObj * map_obj)
23 {
24     if (* first)
25     {
26         struct MapObj * * z = start;
27         map_obj = malloc(size);
28         * z = map_obj;
29         * first = 0;
30     }
31     else
32     {
33         map_obj->next = malloc(size);
34         map_obj = map_obj->next;
35     }
36     return map_obj;
37 }
38
39
40
41 extern void init_map_object_defs(struct World * world, char * filename)
42 {
43     world->item_def = 0;
44     world->monster_def = 0;
45     FILE *                file    = fopen(filename, "r");
46     uint16_t              linemax;
47     textfile_sizes (file, &linemax, NULL);
48     struct MapObjDef      mod;
49     struct ItemDef        id;
50     struct MonsterDef     md;
51     struct ItemDef    * * p_p_id  = &world->item_def;
52     struct MonsterDef * * p_p_md  = &world->monster_def;
53     char *                defline = malloc(linemax);
54     char *                line_p;
55     char                  m_or_i;
56     while (fgets(defline, linemax, file))
57     {
58         mod.next    = 0;
59         mod.id      = atoi(defline);
60         line_p      = strchr(defline, ' ') + 1;
61         m_or_i      = * line_p;
62         mod.mapchar = * (line_p + 2);
63         if ('i' == m_or_i)
64         {
65             line_p = line_p + 5;
66         }
67         else
68         {
69             md.hitpoints_start = atoi   (line_p + 4);
70             line_p             = strchr (line_p + 4, ' ') + 1;
71         }
72         mod.desc = calloc (strlen (line_p), sizeof(char));
73         memcpy (mod.desc, line_p, strlen(line_p) - 1);
74         if ('i' == m_or_i)
75         {
76             id.map_obj_def = mod;
77             * p_p_id       = malloc(sizeof(struct ItemDef));
78             * * p_p_id     = id;
79             p_p_id         = (struct ItemDef    * *) * p_p_id;
80         }
81         else
82         {
83             md.map_obj_def = mod;
84             * p_p_md       = malloc(sizeof(struct MonsterDef));
85             * * p_p_md     = md;
86             p_p_md         = (struct MonsterDef * *) * p_p_md;
87         }
88     }
89     free(defline);
90     fclose(file);
91 };
92
93
94
95 extern void write_map_objects(void * start, FILE * file,
96                               void (* w_typedata) (void *, FILE *) )
97 {
98     struct MapObj * map_obj;
99     for (map_obj = start; map_obj != 0; map_obj = map_obj->next)
100     {
101         write_uint16_bigendian(map_obj->pos.y + 1, file);
102         write_uint16_bigendian(map_obj->pos.x + 1, file);
103         fputc(map_obj->type, file);
104         if (w_typedata)
105         {
106             w_typedata (map_obj, file);
107         }
108     }
109     write_uint16_bigendian(0, file);
110 }
111
112
113
114 extern void read_map_objects(void * start, FILE * file, size_t size,
115                              void (* r_typedata) (void *, FILE *) )
116 {
117     struct MapObj * map_obj;
118     uint16_t test;
119     char first = 1;
120     while (1)
121     {
122         test = read_uint16_bigendian(file);
123         if (0 == test)
124         {
125             break;
126         }
127         map_obj = get_next_map_obj(start, &first, size, map_obj);
128         map_obj->pos.y = test - 1;
129         map_obj->pos.x = read_uint16_bigendian(file) - 1;
130         map_obj->type = fgetc(file);
131         if (r_typedata)
132         {
133             r_typedata(map_obj, file);
134         }
135     }
136     if (!first)
137     {
138         map_obj->next = 0;
139     }
140 }
141
142
143
144 extern void write_map_objects_monsterdata(void * start, FILE * file)
145 {
146   struct Monster * m = (struct Monster *) start;
147   fputc(m->hitpoints, file);
148 }
149
150
151
152 extern void read_map_objects_monsterdata (void * start, FILE * file)
153 {
154   struct Monster * m = (struct Monster *) start;
155   m->hitpoints = fgetc(file);
156 }
157
158
159
160 extern void * build_map_objects(struct World * world, void * start, char def_id,
161                                 unsigned char n, size_t size,
162                                 void (* b_typedata) (struct MapObjDef *,
163                                                      void *))
164 {
165     unsigned char i;
166     struct MapObj * mo;
167     char first = 1;
168     struct MapObjDef * mod = get_map_obj_def(world, def_id);
169     for (i = 0; i < n; i++)
170     {
171         mo = get_next_map_obj(start, &first, size, mo);
172         mo->pos = find_passable_pos(world->map);
173         b_typedata(mod, mo);
174     }
175     if (!first)
176     {
177         mo->next = 0;
178     }
179     return &mo->next;
180 }
181
182
183
184 extern void build_map_objects_itemdata(struct MapObjDef * map_obj_def,
185                                        void * start)
186 {
187   struct Item * i = (struct Item *) start;
188   i->map_obj.type = map_obj_def->id;
189 }
190
191
192
193 extern void build_map_objects_monsterdata(struct MapObjDef * map_obj_def,
194                                           void * start)
195 {
196     struct Monster * m = (struct Monster *) start;
197     m->map_obj.type = map_obj_def->id;
198     struct MonsterDef * md = (struct MonsterDef *) map_obj_def;
199     m->hitpoints = md->hitpoints_start;
200 }
201
202
203
204 extern struct MapObjDef * get_map_obj_def (struct World * world, char def_id)
205 {
206     struct MapObjDef * d = NULL;
207     for (d = (struct MapObjDef *) world->monster_def;
208          d->id != def_id && 0 != d->next;
209          d = d->next);
210     if (d->id != def_id)
211     {
212         for (d = (struct MapObjDef *) world->item_def;
213              d->id != def_id && 0 != d->next;
214              d = d->next);
215     }
216     return d;
217 }