home · contact · privacy
New animate map objects are never placed on a square with other animated map objects...
[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     world->last_map_obj = mo;
100 }
101
102
103
104 extern void add_map_object(struct World * world, uint8_t type)
105 {
106     char * f_name = "add_map_object";
107     struct MapObjDef * mod = get_map_object_def(world, type);
108     struct MapObj * mo = try_malloc(sizeof(struct MapObj), world, f_name);
109     mo->id = world->map_obj_count;
110     world->map_obj_count++;
111     mo->type = mod->id;
112     mo->lifepoints = mod->lifepoints;
113     while (1)
114     {
115         struct yx_uint16 pos = find_passable_pos(world->map);
116         struct MapObj * mo_ptr;
117         uint8_t clear = 1;
118         for (mo_ptr = world->map_objs;
119              mo_ptr != NULL;
120              mo_ptr = mo_ptr->next)
121         {
122             if (yx_uint16_cmp(&pos, &mo_ptr->pos) && 0 != mo_ptr->lifepoints)
123             {
124                 clear = 0;
125                 break;
126             }
127         }
128         if (1 == clear)
129         {
130             mo->pos = pos;
131             break;
132         }
133     }
134     mo->next = NULL;
135     if (NULL == world->last_map_obj)
136     {
137         world->map_objs = mo;
138     }
139     else
140     {
141         world->last_map_obj->next = mo;
142     }
143     world->last_map_obj = mo;
144 }
145
146
147
148 extern void add_map_objects(struct World * world, uint8_t type, uint8_t n)
149 {
150     uint8_t i;
151     for (i = 0; i < n; i++)
152     {
153         add_map_object(world, type);
154     }
155 }
156
157
158
159 extern void free_map_objects(struct MapObj * mo_start)
160 {
161     if (NULL == mo_start)
162     {
163         return;
164     }
165     free_map_objects(mo_start->next);
166     free(mo_start);
167 }
168
169
170
171 extern struct MapObj * get_player(struct World * world)
172 {
173     struct MapObj * ptr = world->map_objs;
174     while (1)
175     {
176         if (NULL == ptr)
177         {
178             return ptr;
179         }
180         if (0 == ptr->id)
181         {
182             return ptr;
183         }
184         ptr = ptr->next;
185     }
186 }
187
188
189
190 extern struct MapObjDef * get_map_object_def(struct World * w, uint8_t id)
191 {
192     struct MapObjDef * mod = w->map_obj_defs;
193     while (id != mod->id)
194     {
195         mod = mod->next;
196     }
197     return mod;
198 }