1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "map.hh"
|
---|
10 | #include "saver.hh"
|
---|
11 | #include "tile.hh"
|
---|
12 | #include "g1_object.hh"
|
---|
13 | #include "path.hh"
|
---|
14 | #include "load3d.hh"
|
---|
15 | #include "m_flow.hh"
|
---|
16 | #include "player.hh"
|
---|
17 | #include "light.hh"
|
---|
18 | #include "remove_man.hh"
|
---|
19 | #include "g1_render.hh"
|
---|
20 | #include "saver_id.hh"
|
---|
21 | // #include "critical_graph.hh"
|
---|
22 | // #include "solvemap_astar.hh"
|
---|
23 |
|
---|
24 | #include "objs/old_ids.hh"
|
---|
25 | #include "height_info.hh"
|
---|
26 | #include "loaders/load.hh"
|
---|
27 | #include "map_man.hh"
|
---|
28 | #include "cwin_man.hh"
|
---|
29 |
|
---|
30 | #include "objs/map_piece.hh"
|
---|
31 | #include "lisp/li_load.hh"
|
---|
32 | #include "map_cell.hh"
|
---|
33 | #include "map_vert.hh"
|
---|
34 | #include "tick_count.hh"
|
---|
35 | #include "map_data.hh"
|
---|
36 |
|
---|
37 | void g1_map_class::save_objects(g1_saver_class *out)
|
---|
38 | {
|
---|
39 | g1_object_class *olist[G1_MAX_OBJECTS];
|
---|
40 | sw32 t=make_object_list(olist, G1_MAX_OBJECTS), ttypes=0, i;
|
---|
41 |
|
---|
42 | out->set_helpers(olist, t);
|
---|
43 |
|
---|
44 | // save the names of all the object types
|
---|
45 | out->mark_section(G1_SECTION_OBJECT_TYPES_V1);
|
---|
46 | out->write_32(g1_last_object_type+1);
|
---|
47 |
|
---|
48 | for (i=0; i<=g1_last_object_type; i++)
|
---|
49 | if (g1_object_type_array[i])
|
---|
50 | {
|
---|
51 | const char *name=g1_object_type_array[i]->name();
|
---|
52 | int len=strlen(name)+1;
|
---|
53 | out->write_16(len);
|
---|
54 | out->write((void*)name,len);
|
---|
55 | }
|
---|
56 | else out->write_16(0);
|
---|
57 |
|
---|
58 |
|
---|
59 | out->mark_section("golgotha object type info");
|
---|
60 | for (i=0; i<=g1_last_object_type; i++)
|
---|
61 | {
|
---|
62 | int han=out->mark_size();
|
---|
63 | if (g1_object_type_array[i])
|
---|
64 | g1_object_type_array[i]->save(out);
|
---|
65 | out->end_mark_size(han);
|
---|
66 | }
|
---|
67 |
|
---|
68 |
|
---|
69 | out->mark_section(G1_SECTION_OBJECTS_V1);
|
---|
70 | out->write_32(t);
|
---|
71 |
|
---|
72 | // if objects change at a base level (g1_object_class) then a new section
|
---|
73 | // should be created here
|
---|
74 | out->mark_section(G1_SECTION_OBJECT_BASE_V1);
|
---|
75 | for (i=0; i<t; i++)
|
---|
76 | {
|
---|
77 | out->mark_section(G1_SECTION_OBJECT_LIST + i);
|
---|
78 | out->write_16(olist[i]->id);
|
---|
79 | olist[i]->save(out);
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | void g1_map_class::save(g1_saver_class *out, w32 sections)
|
---|
84 | {
|
---|
85 | w32 i,j,k, tobjs=0;
|
---|
86 |
|
---|
87 | out->mark_section("li_type_info");
|
---|
88 | li_save_type_info(out,0);
|
---|
89 |
|
---|
90 | // need to save the width and height of the map if saves cells or verts
|
---|
91 | if (sections & (G1_MAP_CELLS | G1_MAP_VERTS))
|
---|
92 | {
|
---|
93 | out->mark_section(G1_SECTION_MAP_DIMENSIONS_V1);
|
---|
94 | out->write_16(width());
|
---|
95 | out->write_16(height());
|
---|
96 | }
|
---|
97 |
|
---|
98 | if (sections & G1_MAP_SKY)
|
---|
99 | save_sky(out);
|
---|
100 |
|
---|
101 |
|
---|
102 | if (sections & G1_MAP_TICK)
|
---|
103 | {
|
---|
104 | out->mark_section(G1_SECTION_TICK);
|
---|
105 | out->write_32(get_tick());
|
---|
106 | }
|
---|
107 |
|
---|
108 |
|
---|
109 | if (sections & G1_MAP_CELLS)
|
---|
110 | {
|
---|
111 | // this so if the tiles get moved around after save, we can match them back up
|
---|
112 | out->mark_section(G1_SECTION_TILE_MATCHUP_V1);
|
---|
113 | out->write_32(g1_tile_man.total());
|
---|
114 |
|
---|
115 | for (i=0; i<g1_tile_man.total(); i++)
|
---|
116 | out->write_32(g1_tile_man.get(i)->filename_checksum);
|
---|
117 |
|
---|
118 | g1_save_map_cells(cells, width() * height(), out);
|
---|
119 | }
|
---|
120 |
|
---|
121 | if (sections & G1_MAP_VERTS)
|
---|
122 | g1_save_map_verts(verts, (w+1)*(h+1), out, i4_T);
|
---|
123 |
|
---|
124 | if (sections & G1_MAP_SELECTED_VERTS)
|
---|
125 | {
|
---|
126 | out->mark_section("golgotha selected verts");
|
---|
127 |
|
---|
128 | int l=(w+1)*(h+1);
|
---|
129 | g1_map_vertex_class *v=verts;
|
---|
130 |
|
---|
131 | for (i=0; i<l; i++, v++)
|
---|
132 | if (v->need_undo())
|
---|
133 | {
|
---|
134 | out->write_16(i);
|
---|
135 | g1_save_map_verts(v, 1, out, i4_F);
|
---|
136 | }
|
---|
137 |
|
---|
138 | out->write_16(0xffff);
|
---|
139 | }
|
---|
140 |
|
---|
141 | if (sections & G1_MAP_PLAYERS)
|
---|
142 | {
|
---|
143 | out->mark_section(G1_SECTION_PLAYER_INFO);
|
---|
144 | g1_player_man.save(out);
|
---|
145 | }
|
---|
146 |
|
---|
147 | if (sections & G1_MAP_OBJECTS)
|
---|
148 | save_objects(out);
|
---|
149 |
|
---|
150 |
|
---|
151 | if (sections & G1_MAP_LIGHTS)
|
---|
152 | g1_lights.save(out);
|
---|
153 |
|
---|
154 |
|
---|
155 | if ((sections & G1_MAP_MOVIE) && current_movie)
|
---|
156 | {
|
---|
157 | out->mark_section(G1_SECTION_MOVIE);
|
---|
158 | current_movie->save(out);
|
---|
159 | }
|
---|
160 |
|
---|
161 | // if ((sections & G1_MAP_CRITICAL_POINTS) && critical_graph)
|
---|
162 | // {
|
---|
163 | // out->mark_section(G1_SECTION_CRITICAL_POINTS_V1);
|
---|
164 | // critical_graph->save_points(out);
|
---|
165 | // }
|
---|
166 |
|
---|
167 | // if ((sections & G1_MAP_CRITICAL_DATA) && critical_graph)
|
---|
168 | // {
|
---|
169 | // out->mark_section(G1_SECTION_CRITICAL_GRAPH_V1);
|
---|
170 | // critical_graph->save_graph(out);
|
---|
171 |
|
---|
172 | // out->mark_section(G1_SECTION_CRITICAL_MAP_V1);
|
---|
173 | // save_critical_map(out);
|
---|
174 | // }
|
---|
175 |
|
---|
176 | if (sections & G1_MAP_VIEW_POSITIONS)
|
---|
177 | g1_cwin_man->save_views(out);
|
---|
178 |
|
---|
179 | for (g1_map_data_class *md=g1_map_data_class::first; md; md=md->next)
|
---|
180 | md->save(out, sections);
|
---|
181 |
|
---|
182 | }
|
---|
183 |
|
---|
184 |
|
---|
185 | struct tile_matchup
|
---|
186 | {
|
---|
187 | w16 old_tile_number;
|
---|
188 | w32 old_checksum;
|
---|
189 | };
|
---|
190 |
|
---|
191 | int tile_matchup_compare(const void *a, const void *b)
|
---|
192 | {
|
---|
193 | if ( ((tile_matchup *)a)->old_checksum<((tile_matchup *)b)->old_checksum)
|
---|
194 | return -1;
|
---|
195 | else if ( ((tile_matchup *)a)->old_checksum>((tile_matchup *)b)->old_checksum)
|
---|
196 | return 1;
|
---|
197 | else
|
---|
198 | return 0;
|
---|
199 | }
|
---|
200 |
|
---|
201 | // this will create a remap array which maps the tiles saved previously into the
|
---|
202 | // currently tile, so we can added and remove tiles from our list without screwing
|
---|
203 | // up previously saved maps
|
---|
204 | static w16 *g1_map_get_tile_remap(g1_loader_class *fp) // returns 0 on failure
|
---|
205 | {
|
---|
206 | if (!fp->goto_section(G1_SECTION_TILE_MATCHUP_V1))
|
---|
207 | return 0;
|
---|
208 | w32 i,t=fp->read_32(); // how many tile types there were when sved
|
---|
209 |
|
---|
210 | tile_matchup *tl=(tile_matchup *)i4_malloc(t*sizeof(tile_matchup), "tile matchup");
|
---|
211 | for (i=0; i<t; i++)
|
---|
212 | {
|
---|
213 | tl[i].old_tile_number=i;
|
---|
214 | tl[i].old_checksum=fp->read_32();
|
---|
215 | }
|
---|
216 |
|
---|
217 | // sort so we can do a binary search for faster matchup
|
---|
218 | qsort(tl, t, sizeof(tile_matchup), tile_matchup_compare);
|
---|
219 |
|
---|
220 | w16 *remap=(w16 *)i4_malloc(t*sizeof(w16), "tile remap");
|
---|
221 | memset(remap, 0, t*sizeof(w16));
|
---|
222 |
|
---|
223 | for (i=0; i< g1_tile_man.total(); i++)
|
---|
224 | {
|
---|
225 | w32 find_id=g1_tile_man.get(i)->filename_checksum,cur;
|
---|
226 | w32 lo=0,hi=t,mid;
|
---|
227 | i4_bool done=i4_F;
|
---|
228 | mid=(hi+lo+1)/2;
|
---|
229 |
|
---|
230 | do
|
---|
231 | {
|
---|
232 | cur=tl[mid].old_checksum;
|
---|
233 | if (cur==find_id)
|
---|
234 | {
|
---|
235 | done=i4_T;
|
---|
236 | remap[tl[mid].old_tile_number]=i;
|
---|
237 | }
|
---|
238 | else
|
---|
239 | {
|
---|
240 | if (cur<find_id)
|
---|
241 | lo=mid;
|
---|
242 | else hi=mid;
|
---|
243 |
|
---|
244 | w32 last_mid=mid;
|
---|
245 | mid=(hi+lo)/2;
|
---|
246 | if (last_mid==mid)
|
---|
247 | done=i4_T;
|
---|
248 | }
|
---|
249 |
|
---|
250 | } while (!done);
|
---|
251 | }
|
---|
252 | i4_free(tl);
|
---|
253 | return remap;
|
---|
254 | }
|
---|
255 |
|
---|
256 | i4_bool g1_map_class::load_sky(g1_loader_class *fp)
|
---|
257 | {
|
---|
258 | if (sky_name)
|
---|
259 | delete sky_name;
|
---|
260 |
|
---|
261 | if (fp->goto_section(G1_SECTION_SKY_V1))
|
---|
262 | sky_name=fp->read_counted_str();
|
---|
263 |
|
---|
264 | return i4_T;
|
---|
265 | }
|
---|
266 |
|
---|
267 | void g1_map_class::save_sky(g1_saver_class *fp)
|
---|
268 | {
|
---|
269 | fp->mark_section(G1_SECTION_SKY_V1);
|
---|
270 |
|
---|
271 | if (sky_name)
|
---|
272 | fp->write_counted_str(*sky_name);
|
---|
273 | }
|
---|
274 |
|
---|
275 |
|
---|
276 | struct g1_sorted_obj_struct
|
---|
277 | {
|
---|
278 | const char *name;
|
---|
279 | w16 type;
|
---|
280 | };
|
---|
281 |
|
---|
282 | int g1_sorted_obj_struct_compare(const g1_sorted_obj_struct *a, const g1_sorted_obj_struct *b)
|
---|
283 | {
|
---|
284 | return strcmp(a->name, b->name);
|
---|
285 | }
|
---|
286 |
|
---|
287 |
|
---|
288 | extern w32 g1_num_objs_in_view; // from map_fast
|
---|
289 |
|
---|
290 | //returns a list of objects
|
---|
291 | g1_object_class **g1_map_class::load_objects(g1_loader_class *fp, w32 &tobjs)
|
---|
292 | {
|
---|
293 | int i;
|
---|
294 | tobjs=0;
|
---|
295 | g1_object_class **obj_list=0;
|
---|
296 |
|
---|
297 | g1_object_type *o_remap=0;
|
---|
298 |
|
---|
299 | for (i=0; i<G1_MAX_PLAYERS; i++)
|
---|
300 | g1_player_man.get(i)->owned_objects.clear();
|
---|
301 |
|
---|
302 | if (fp->goto_section(G1_SECTION_OBJECT_TYPES_V1))
|
---|
303 | {
|
---|
304 | i4_array<g1_sorted_obj_struct> sorted_objs(g1_last_object_type+1, 0);
|
---|
305 | for (i=0; i<=g1_last_object_type; i++)
|
---|
306 | if (g1_object_type_array[i])
|
---|
307 | {
|
---|
308 | g1_sorted_obj_struct o;
|
---|
309 | o.name=g1_object_type_array[i]->name();
|
---|
310 | o.type=i;
|
---|
311 | sorted_objs.add(o);
|
---|
312 | }
|
---|
313 |
|
---|
314 | sorted_objs.sort(g1_sorted_obj_struct_compare);
|
---|
315 |
|
---|
316 | int old_total=fp->read_32();
|
---|
317 | o_remap=(g1_object_type *)i4_malloc(sizeof(g1_object_type) * old_total, "obj remap");
|
---|
318 |
|
---|
319 | char name[512];
|
---|
320 | for (i=0; i<old_total; i++)
|
---|
321 | {
|
---|
322 | int nlen=fp->read_16();
|
---|
323 |
|
---|
324 | if (nlen)
|
---|
325 | {
|
---|
326 | fp->read(name, nlen);
|
---|
327 |
|
---|
328 | g1_sorted_obj_struct o;
|
---|
329 | o.name=name;
|
---|
330 |
|
---|
331 | int find=sorted_objs.binary_search(&o, g1_sorted_obj_struct_compare);
|
---|
332 | if (find==-1)
|
---|
333 | {
|
---|
334 | i4_warning("No match for old object type %s", name);
|
---|
335 | o_remap[i]=-1;
|
---|
336 | }
|
---|
337 | else
|
---|
338 | o_remap[i]=sorted_objs[find].type;
|
---|
339 | }
|
---|
340 | else
|
---|
341 | o_remap[i]=-1;
|
---|
342 | }
|
---|
343 |
|
---|
344 | if (fp->goto_section("golgotha object type info"))
|
---|
345 | {
|
---|
346 | for (i=0; i<old_total; i++)
|
---|
347 | {
|
---|
348 | w32 size=fp->read_32();
|
---|
349 | if (o_remap[i]==-1) // skip over types we don't know about
|
---|
350 | fp->seek(fp->tell()+size);
|
---|
351 | else
|
---|
352 | g1_object_type_array[o_remap[i]]->load(fp);
|
---|
353 | }
|
---|
354 | }
|
---|
355 | }
|
---|
356 |
|
---|
357 |
|
---|
358 | if (fp->goto_section(G1_SECTION_OBJECTS_V1))
|
---|
359 | {
|
---|
360 | think_head=think_tail=0;
|
---|
361 |
|
---|
362 | // reset the global id list
|
---|
363 | g1_global_id.init();
|
---|
364 | g1_global_id.claim_freespace();
|
---|
365 |
|
---|
366 |
|
---|
367 |
|
---|
368 | if (!o_remap)
|
---|
369 | o_remap=g1_get_old_object_type_remap();
|
---|
370 |
|
---|
371 | tobjs=fp->read_32();
|
---|
372 | //tobjs=0;
|
---|
373 | if (tobjs)
|
---|
374 | {
|
---|
375 | w16 bomber_type = g1_get_object_type("bomber"); //(OLI) bomber hack for demo
|
---|
376 |
|
---|
377 | obj_list=(g1_object_class **)i4_malloc(sizeof(g1_object_class *) * tobjs, "tmp object list");
|
---|
378 |
|
---|
379 | fp->set_remap(tobjs);
|
---|
380 | if (fp->goto_section(G1_SECTION_OBJECT_BASE_V1))
|
---|
381 | {
|
---|
382 | for (i=0; i<tobjs; i++)
|
---|
383 | {
|
---|
384 | fp->goto_section(G1_SECTION_OBJECT_LIST + i);
|
---|
385 | sw16 obj_type=o_remap[fp->read_16()];
|
---|
386 |
|
---|
387 | if (obj_type==bomber_type) //(OLI) bomber hack for demo
|
---|
388 | obj_type=-1;
|
---|
389 |
|
---|
390 | if (obj_type>=0 && obj_type<=g1_last_object_type && g1_object_type_array[obj_type])
|
---|
391 | {
|
---|
392 | g1_object_class *o=g1_object_type_array[obj_type]->create_object(obj_type,fp);
|
---|
393 |
|
---|
394 | g1_map_piece_class *mp = g1_map_piece_class::cast(o);
|
---|
395 |
|
---|
396 | if (o->global_id==g1_global_id.invalid_id())
|
---|
397 | {
|
---|
398 | i4_warning("object has invalid id for itself");
|
---|
399 | delete o;
|
---|
400 | o=0;
|
---|
401 | }
|
---|
402 | // else if (mp)
|
---|
403 | // {
|
---|
404 | // delete o;
|
---|
405 | // o=0;
|
---|
406 | // }
|
---|
407 | else
|
---|
408 | if (o->player_num>=G1_MAX_PLAYERS)
|
---|
409 | {
|
---|
410 | i4_warning("map load : object '%s' deleted, bad player number",
|
---|
411 | g1_object_type_array[obj_type]->name());
|
---|
412 | delete o;
|
---|
413 | o=0;
|
---|
414 | } else if (o->x<0 || o->y<0 || o->x>=width() || o->y>=height() || o->id!=obj_type)
|
---|
415 | {
|
---|
416 | i4_warning("map load : object '%s' deleted, off map or loaded wrong",
|
---|
417 | g1_object_type_array[obj_type]->name());
|
---|
418 | delete o;
|
---|
419 | o=0;
|
---|
420 | }
|
---|
421 |
|
---|
422 | obj_list[i]=o;
|
---|
423 | }
|
---|
424 | else
|
---|
425 | {
|
---|
426 | obj_list[i]=0;
|
---|
427 | }
|
---|
428 | }
|
---|
429 | }
|
---|
430 | fp->end_remap();
|
---|
431 | // now the object will convert all of there refernces to other objects from w16 to
|
---|
432 | // pointers
|
---|
433 |
|
---|
434 | fp->set_helpers(obj_list, tobjs);
|
---|
435 |
|
---|
436 | fp->convert_references();
|
---|
437 | }
|
---|
438 |
|
---|
439 | }
|
---|
440 |
|
---|
441 | if (o_remap)
|
---|
442 | i4_free(o_remap);
|
---|
443 |
|
---|
444 | return obj_list;
|
---|
445 |
|
---|
446 | }
|
---|
447 |
|
---|
448 | // returns the sections that were actually read
|
---|
449 | w32 g1_map_class::load(g1_loader_class *fp, w32 sections)
|
---|
450 | {
|
---|
451 | sw32 i, ret=0;
|
---|
452 | g1_object_class **obj_list=0;
|
---|
453 |
|
---|
454 | g1_map_class *old_current=g1_current_map_PRIVATE;
|
---|
455 | g1_set_map(this);
|
---|
456 |
|
---|
457 | w32 tobjs=0;
|
---|
458 | sw32 lw,lh;
|
---|
459 | i4_bool load_cells=(sections & G1_MAP_CELLS)!=0;
|
---|
460 | i4_bool load_verts=(sections & G1_MAP_VERTS)!=0;
|
---|
461 |
|
---|
462 | if (sections & G1_MAP_RES_FILENAME && fp->goto_section("golgotha map res filename"))
|
---|
463 | {
|
---|
464 | i4_str *res = fp->read_counted_str();
|
---|
465 | //(OLI) what do we do with this string?
|
---|
466 | delete res;
|
---|
467 | }
|
---|
468 |
|
---|
469 | if (fp->goto_section("li_type_info"))
|
---|
470 | fp->li_remap=li_load_type_info(fp,0);
|
---|
471 |
|
---|
472 | if (sections & (G1_MAP_CELLS | G1_MAP_VERTS))
|
---|
473 | {
|
---|
474 | if (!fp->goto_section(G1_SECTION_MAP_DIMENSIONS_V1))
|
---|
475 | return 0;
|
---|
476 |
|
---|
477 | lw=fp->read_16();
|
---|
478 | lh=fp->read_16();
|
---|
479 |
|
---|
480 | // must load cells and verts together if new load
|
---|
481 | if (load_cells != load_verts &&
|
---|
482 | (cells!=0 || verts!=0) &&
|
---|
483 | (lw!=w || lh!=h))
|
---|
484 | {
|
---|
485 | i4_warning("trying to merge in cells or verts of differnt map size");
|
---|
486 | sections &= ~(G1_MAP_CELLS | G1_MAP_VERTS); // don't try to load these
|
---|
487 | }
|
---|
488 | }
|
---|
489 |
|
---|
490 |
|
---|
491 | if (sections & G1_MAP_SKY)
|
---|
492 | {
|
---|
493 | if (load_sky(fp))
|
---|
494 | ret|=G1_MAP_SKY;
|
---|
495 | }
|
---|
496 |
|
---|
497 | if ((sections & G1_MAP_TICK) && (fp->goto_section(G1_SECTION_TICK)))
|
---|
498 | {
|
---|
499 | g1_tick_counter=fp->read_32();
|
---|
500 | ret|=G1_MAP_TICK;
|
---|
501 | }
|
---|
502 |
|
---|
503 |
|
---|
504 | g1_object_class *olist[G1_MAX_OBJECTS];
|
---|
505 | sw32 t_old_objects=0;
|
---|
506 |
|
---|
507 | if (cells) // if old cells in map get all the objects off the map before proceeding
|
---|
508 | {
|
---|
509 | t_old_objects=make_object_list(olist, G1_MAX_OBJECTS);
|
---|
510 | for (i=0; i<t_old_objects; i++)
|
---|
511 | olist[i]->unoccupy_location();
|
---|
512 | }
|
---|
513 |
|
---|
514 | if (sections & G1_MAP_CELLS)
|
---|
515 | {
|
---|
516 | if (cells)
|
---|
517 | {
|
---|
518 | i4_free(cells);
|
---|
519 | cells=0;
|
---|
520 | }
|
---|
521 |
|
---|
522 | if (load_cells == load_verts)
|
---|
523 | {
|
---|
524 | w=lw;
|
---|
525 | h=lh;
|
---|
526 | g1_map_width=w;
|
---|
527 | g1_map_height=h;
|
---|
528 | }
|
---|
529 |
|
---|
530 | int a_size=w * h *sizeof(g1_map_cell_class);
|
---|
531 | cells=(g1_map_cell_class *)i4_malloc(a_size,"map");
|
---|
532 | g1_cells=cells;
|
---|
533 | memset(cells, 0, a_size);
|
---|
534 |
|
---|
535 | w16 *tile_remap=g1_map_get_tile_remap(fp);
|
---|
536 | if (!tile_remap)
|
---|
537 | return i4_F;
|
---|
538 |
|
---|
539 | if (g1_load_map_cells(cells, w*h, tile_remap, fp))
|
---|
540 | ret|=G1_MAP_CELLS;
|
---|
541 |
|
---|
542 |
|
---|
543 | i4_free(tile_remap);
|
---|
544 |
|
---|
545 | recalc|=G1_RECALC_PAD_LIST;
|
---|
546 | }
|
---|
547 |
|
---|
548 |
|
---|
549 |
|
---|
550 | if (sections & G1_MAP_VERTS)
|
---|
551 | {
|
---|
552 | if (verts)
|
---|
553 | i4_free(verts);
|
---|
554 |
|
---|
555 | int size=(lw+1)*(lh+1)*sizeof(g1_map_vertex_class);
|
---|
556 | verts=(g1_map_vertex_class *)i4_malloc(size,"");
|
---|
557 | g1_verts=verts;
|
---|
558 |
|
---|
559 | g1_load_map_verts(verts, (lw+1)*(lh+1), fp, 1);
|
---|
560 | ret|=G1_MAP_VERTS;
|
---|
561 | }
|
---|
562 | else if (sections & G1_MAP_SELECTED_VERTS)
|
---|
563 | {
|
---|
564 | if (fp->goto_section("golgotha selected verts"))
|
---|
565 | {
|
---|
566 | i=fp->read_16();
|
---|
567 | while (i!=0xffff)
|
---|
568 | {
|
---|
569 | g1_load_map_verts(verts+i, 1, fp, 0);
|
---|
570 | i=fp->read_16();
|
---|
571 | }
|
---|
572 |
|
---|
573 | ret|=G1_MAP_SELECTED_VERTS;
|
---|
574 | }
|
---|
575 | }
|
---|
576 |
|
---|
577 | if ((sections & G1_MAP_PLAYERS) && fp->goto_section(G1_SECTION_PLAYER_INFO))
|
---|
578 | {
|
---|
579 | if (g1_player_man.load(fp))
|
---|
580 | ret|=G1_MAP_PLAYERS;
|
---|
581 | }
|
---|
582 |
|
---|
583 | if (sections & G1_MAP_OBJECTS)
|
---|
584 | {
|
---|
585 | for (i=0; i<t_old_objects; i++)
|
---|
586 | {
|
---|
587 | request_remove(olist[i]);
|
---|
588 | g1_remove_man.process_requests();
|
---|
589 | }
|
---|
590 | t_old_objects=0;
|
---|
591 |
|
---|
592 |
|
---|
593 | obj_list=load_objects(fp, tobjs);
|
---|
594 | ret|=G1_MAP_OBJECTS;
|
---|
595 | }
|
---|
596 |
|
---|
597 | if (sections & G1_MAP_LIGHTS)
|
---|
598 | {
|
---|
599 | if (g1_lights.load(fp))
|
---|
600 | ret|=G1_MAP_LIGHTS;
|
---|
601 | }
|
---|
602 |
|
---|
603 | if ((sections & G1_MAP_MOVIE) && (fp->goto_section(G1_SECTION_MOVIE)))
|
---|
604 | {
|
---|
605 | if (current_movie)
|
---|
606 | delete current_movie;
|
---|
607 |
|
---|
608 | current_movie=g1_load_movie_flow(fp);
|
---|
609 |
|
---|
610 |
|
---|
611 | ret|=G1_MAP_MOVIE;
|
---|
612 | }
|
---|
613 |
|
---|
614 | if (sections & G1_MAP_VIEW_POSITIONS)
|
---|
615 | g1_cwin_man->load_views(fp);
|
---|
616 | else if (sections & G1_MAP_OBJECTS)
|
---|
617 | g1_cwin_man->load_views(0);
|
---|
618 |
|
---|
619 | if (obj_list)
|
---|
620 | {
|
---|
621 | for (i=0; i<tobjs; i++)
|
---|
622 | if (obj_list[i])
|
---|
623 | {
|
---|
624 | g1_object_class *o=obj_list[i];
|
---|
625 |
|
---|
626 | o->occupy_location();
|
---|
627 | o->grab_old(); // is this ok? currently, this is needed to get all ground
|
---|
628 | // rolls and pitches correct in the level
|
---|
629 |
|
---|
630 | if (o->get_flag(g1_object_class::THINKING))
|
---|
631 | request_think(o);
|
---|
632 |
|
---|
633 | g1_player_man.get(o->player_num)->add_object(o->global_id);
|
---|
634 | }
|
---|
635 |
|
---|
636 | fp->convert_references();
|
---|
637 | fp->set_helpers(0,0); // make sure no one tries to use this later
|
---|
638 |
|
---|
639 | // validate everyone's data, especially if other objects have been deleted
|
---|
640 | for (i=0; i<tobjs; i++)
|
---|
641 | if (obj_list[i])
|
---|
642 | obj_list[i]->validate();
|
---|
643 |
|
---|
644 | i4_free(obj_list);
|
---|
645 | }
|
---|
646 | else if (fp->references_were_loaded())
|
---|
647 | i4_error("could not convert references because objects not loaded");
|
---|
648 |
|
---|
649 | // add previously removed object into the map if we aren't loading them later
|
---|
650 | if (t_old_objects)
|
---|
651 | {
|
---|
652 | if (sections & G1_MAP_OBJECTS) // delete these object, they were supposedly loaded
|
---|
653 | {
|
---|
654 | for (i=0; i<t_old_objects; i++)
|
---|
655 | {
|
---|
656 | request_remove(olist[i]);
|
---|
657 | g1_remove_man.process_requests();
|
---|
658 | }
|
---|
659 | }
|
---|
660 | else // otherwise add them back into the map
|
---|
661 | {
|
---|
662 |
|
---|
663 | for (i=0; i<t_old_objects; i++)
|
---|
664 | olist[i]->occupy_location();
|
---|
665 | }
|
---|
666 | }
|
---|
667 |
|
---|
668 | for (g1_map_data_class *md=g1_map_data_class::first; md; md=md->next)
|
---|
669 | md->load(fp, sections);
|
---|
670 |
|
---|
671 |
|
---|
672 | g1_map_vertex_class *v[4];
|
---|
673 | i4_3d_vector v0,v1,v2,v3,vec1,vec2,vec3;
|
---|
674 | sw32 cx,cy;
|
---|
675 |
|
---|
676 | for (cy=0; cy<height(); cy++)
|
---|
677 | for (cx=0; cx<width(); cx++)
|
---|
678 | {
|
---|
679 | g1_map_cell_class *cell = cells+cx+cy*width();
|
---|
680 |
|
---|
681 | v[0] = verts + cx + cy * (width()+1); //v[0] v[1]
|
---|
682 | v[1] = v[0]+1; //v[3] v[2]
|
---|
683 | v[2] = v[1]+width()+1;
|
---|
684 | v[3] = v[2]-1;
|
---|
685 |
|
---|
686 | v0.x = cx;
|
---|
687 | v0.y = cy;
|
---|
688 | v0.z = v[0]->get_height();
|
---|
689 |
|
---|
690 | v1.x = cx+1;
|
---|
691 | v1.y = cx;
|
---|
692 | v1.z = v[1]->get_height();
|
---|
693 |
|
---|
694 | v2.x = cx+1;
|
---|
695 | v2.y = cy+1;
|
---|
696 | v2.z = v[2]->get_height();
|
---|
697 |
|
---|
698 | v3.x = cx;
|
---|
699 | v3.y = cy+1;
|
---|
700 | v3.z = v[3]->get_height();
|
---|
701 |
|
---|
702 | vec1.x = v1.x - v0.x;
|
---|
703 | vec1.y = v1.y - v0.y;
|
---|
704 | vec1.z = v1.z - v0.z;
|
---|
705 |
|
---|
706 | vec2.x = v2.x - v0.x;
|
---|
707 | vec2.y = v2.y - v0.y;
|
---|
708 | vec2.z = v2.z - v0.z;
|
---|
709 |
|
---|
710 | vec3.cross(vec1,vec2);
|
---|
711 |
|
---|
712 | i4_float dist = vec3.dot(v0);
|
---|
713 |
|
---|
714 | if (fabs(vec3.dot(v3) - dist) < 0.00000001) cell->flags |= g1_map_cell_class::PLANAR;
|
---|
715 | }
|
---|
716 |
|
---|
717 | recalc_static_stuff();
|
---|
718 | tick_time.get();
|
---|
719 |
|
---|
720 | g1_set_map(old_current);
|
---|
721 |
|
---|
722 | if (fp->li_remap)
|
---|
723 | {
|
---|
724 | li_free_type_info(fp->li_remap);
|
---|
725 | fp->li_remap=0;
|
---|
726 | }
|
---|
727 |
|
---|
728 |
|
---|
729 | return i4_T;
|
---|
730 | }
|
---|
731 |
|
---|
732 | void g1_map_class::reload()
|
---|
733 | {
|
---|
734 | i4_file_class *in=i4_open(*filename);
|
---|
735 | if (in)
|
---|
736 | {
|
---|
737 | g1_loader_class *l=g1_open_save_file(in);
|
---|
738 | if (l)
|
---|
739 | {
|
---|
740 | load(l, G1_MAP_ALL);
|
---|
741 | delete l;
|
---|
742 | }
|
---|
743 | }
|
---|
744 | }
|
---|
745 |
|
---|
746 | // void g1_map_class::save_critical_map(g1_saver_class *f)
|
---|
747 | // {
|
---|
748 | // int i,j,k;
|
---|
749 | // g1_map_cell_class *c=cell(0,0);
|
---|
750 |
|
---|
751 | // for (j=0; j<height(); j++)
|
---|
752 | // for (i=0; i<width(); i++, c++)
|
---|
753 | // f->write(c->nearest_critical, sizeof(c->nearest_critical));
|
---|
754 | // }
|
---|
755 |
|
---|
756 | // void g1_map_class::load_critical_map(g1_loader_class *f)
|
---|
757 | // {
|
---|
758 | // int i,j,k;
|
---|
759 | // g1_map_cell_class *c=&cell(0,0);
|
---|
760 |
|
---|
761 | // for (j=0; j<height(); j++)
|
---|
762 | // for (i=0; i<width(); i++, c++)
|
---|
763 | // f->read(c->nearest_critical, sizeof(c->nearest_critical));
|
---|
764 | // }
|
---|
765 |
|
---|