1 //----------------------------------------------------------------------------
2 // EDGE Data Definition File Code (Linedefs)
3 //----------------------------------------------------------------------------
4 //
5 // Copyright (c) 1999-2011 The EDGE Team.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 //----------------------------------------------------------------------------
18 //
19 // Line Definitions Setup and Parser Code
20 //
21 // -KM- 1998/09/01 Written.
22 // -ACB- 1998/09/06 Beautification: cleaned up so I can read it :).
23 // -KM- 1998/10/29 New types of linedefs added: colourmap, sound, friction, gravity
24 // auto, singlesided, music, lumpcheck
25 // Removed sector movement to ddf_main.c, so can be accesed by
26 // ddf_sect.c
27 //
28 // -ACB- 2001/02/04 DDF_GetSecHeightReference moved to p_plane.c
29 //
30
31 #include "local.h"
32
33 #include <limits.h>
34
35 #include "line.h"
36
37 #undef DF
38 #define DF DDF_FIELD
39
40 #define DDF_LineHashFunc(x) (((x) + LOOKUP_CACHESIZE) % LOOKUP_CACHESIZE)
41
42 // -KM- 1999/01/29 Improved scrolling.
43 // Scrolling
44 typedef enum
45 {
46 dir_none = 0,
47 dir_vert = 1,
48 dir_up = 2,
49 dir_horiz = 4,
50 dir_left = 8
51 }
52 scrolldirs_e;
53
54 linetype_container_c linetypes; // <-- User-defined
55
56 static linetype_c *default_linetype;
57
58 static void DDF_LineGetTrigType(const char *info, void *storage);
59 static void DDF_LineGetActivators(const char *info, void *storage);
60 static void DDF_LineGetSecurity(const char *info, void *storage);
61 static void DDF_LineGetScroller(const char *info, void *storage);
62 static void DDF_LineGetScrollPart(const char *info, void *storage);
63 static void DDF_LineGetExtraFloor(const char *info, void *storage);
64 static void DDF_LineGetEFControl(const char *info, void *storage);
65 static void DDF_LineGetTeleportSpecial(const char *info, void *storage);
66 static void DDF_LineGetRadTrig(const char *info, void *storage);
67 static void DDF_LineGetSpecialFlags(const char *info, void *storage);
68 static void DDF_LineGetSlideType(const char *info, void *storage);
69 static void DDF_LineGetLineEffect(const char *info, void *storage);
70 static void DDF_LineGetSectorEffect(const char *info, void *storage);
71 static void DDF_LineGetPortalEffect(const char *info, void *storage);
72 static void DDF_LineGetSlopeType(const char *info, void *storage);
73
74 static void DDF_LineMakeCrush(const char *info);
75
76
77 #undef DDF_CMD_BASE
78 #define DDF_CMD_BASE dummy_floor
79 static movplanedef_c dummy_floor;
80
81 const commandlist_t floor_commands[] =
82 {
83 DF("TYPE", type, DDF_SectGetMType),
84 DF("SPEED_UP", speed_up, DDF_MainGetFloat),
85 DF("SPEED_DOWN", speed_down, DDF_MainGetFloat),
86 DF("DEST_REF", destref, DDF_SectGetDestRef),
87 DF("DEST_OFFSET", dest, DDF_MainGetFloat),
88 DF("OTHER_REF", otherref, DDF_SectGetDestRef),
89 DF("OTHER_OFFSET", other, DDF_MainGetFloat),
90 DF("CRUSH_DAMAGE", crush_damage, DDF_MainGetNumeric),
91 DF("TEXTURE", tex, DDF_MainGetLumpName),
92 DF("PAUSE_TIME", wait, DDF_MainGetTime),
93 DF("WAIT_TIME", prewait, DDF_MainGetTime),
94 DF("SFX_START", sfxstart, DDF_MainLookupSound),
95 DF("SFX_UP", sfxup, DDF_MainLookupSound),
96 DF("SFX_DOWN", sfxdown, DDF_MainLookupSound),
97 DF("SFX_STOP", sfxstop, DDF_MainLookupSound),
98 DF("SCROLL_ANGLE", scroll_angle,DDF_MainGetAngle),
99 DF("SCROLL_SPEED", scroll_speed,DDF_MainGetFloat),
100 DF("IGNORE_TEXTURE", ignore_texture, DDF_MainGetBoolean),
101
102 DDF_CMD_END
103 };
104
105 #undef DDF_CMD_BASE
106 #define DDF_CMD_BASE dummy_ladder
107 static ladderdef_c dummy_ladder;
108
109 const commandlist_t ladder_commands[] =
110 {
111 DF("HEIGHT", height, DDF_MainGetFloat),
112 DDF_CMD_END
113 };
114
115 #undef DDF_CMD_BASE
116 #define DDF_CMD_BASE dummy_slider
117 static sliding_door_c dummy_slider;
118
119 const commandlist_t slider_commands[] =
120 {
121 DF("TYPE", type, DDF_LineGetSlideType),
122 DF("SPEED", speed, DDF_MainGetFloat),
123 DF("PAUSE_TIME", wait, DDF_MainGetTime),
124 DF("SEE_THROUGH", see_through, DDF_MainGetBoolean),
125 DF("DISTANCE", distance, DDF_MainGetPercent),
126 DF("SFX_START", sfx_start, DDF_MainLookupSound),
127 DF("SFX_OPEN", sfx_open, DDF_MainLookupSound),
128 DF("SFX_CLOSE", sfx_close, DDF_MainLookupSound),
129 DF("SFX_STOP", sfx_stop, DDF_MainLookupSound),
130
131 DDF_CMD_END
132 };
133
134
135 static linetype_c *dynamic_line;
136
137 // these bits logically belong with buffer_line:
138 static float scrolling_speed;
139 static scrolldirs_e scrolling_dir;
140
141 #undef DDF_CMD_BASE
142 #define DDF_CMD_BASE dummy_line
143 static linetype_c dummy_line;
144
145 static const commandlist_t linedef_commands[] =
146 {
147 // sub-commands
148 DDF_SUB_LIST("FLOOR", f, floor_commands),
149 DDF_SUB_LIST("CEILING", c, floor_commands),
150 DDF_SUB_LIST("SLIDER", s, slider_commands),
151 DDF_SUB_LIST("LADDER", ladder, ladder_commands),
152
153 DF("NEWTRIGGER", newtrignum, DDF_MainGetNumeric),
154 DF("ACTIVATORS", obj, DDF_LineGetActivators),
155 DF("TYPE", type, DDF_LineGetTrigType),
156 DF("KEYS", keys, DDF_LineGetSecurity),
157 DF("FAILED_MESSAGE", failedmessage, DDF_MainGetString),
158 DF("FAILED_SFX", failed_sfx, DDF_MainLookupSound),
159 DF("COUNT", count, DDF_MainGetNumeric),
160
161 DF("DONUT", d.dodonut, DDF_MainGetBoolean),
162 DF("DONUT_IN_SFX", d.d_sfxin, DDF_MainLookupSound),
163 DF("DONUT_IN_SFXSTOP", d.d_sfxinstop, DDF_MainLookupSound),
164 DF("DONUT_OUT_SFX", d.d_sfxout, DDF_MainLookupSound),
165 DF("DONUT_OUT_SFXSTOP", d.d_sfxoutstop, DDF_MainLookupSound),
166
167 DF("TELEPORT", t.teleport, DDF_MainGetBoolean),
168 DF("TELEPORT_DELAY", t.delay, DDF_MainGetTime),
169 DF("TELEIN_EFFECTOBJ", t.inspawnobj_ref, DDF_MainGetString),
170 DF("TELEOUT_EFFECTOBJ", t.outspawnobj_ref, DDF_MainGetString),
171 DF("TELEPORT_SPECIAL", t.special, DDF_LineGetTeleportSpecial),
172
173 DF("LIGHT_TYPE", l.type, DDF_SectGetLighttype),
174 DF("LIGHT_LEVEL", l.level, DDF_MainGetNumeric),
175 DF("LIGHT_DARK_TIME", l.darktime, DDF_MainGetTime),
176 DF("LIGHT_BRIGHT_TIME", l.brighttime, DDF_MainGetTime),
177 DF("LIGHT_CHANCE", l.chance, DDF_MainGetPercent),
178 DF("LIGHT_SYNC", l.sync, DDF_MainGetTime),
179 DF("LIGHT_STEP", l.step, DDF_MainGetNumeric),
180 DF("EXIT", e_exit, DDF_SectGetExit),
181 DF("HUB_EXIT", hub_exit, DDF_MainGetNumeric),
182
183 DF("SCROLL_XSPEED", s_xspeed, DDF_MainGetFloat),
184 DF("SCROLL_YSPEED", s_yspeed, DDF_MainGetFloat),
185 DF("SCROLL_PARTS", scroll_parts, DDF_LineGetScrollPart),
186 DF("USE_COLOURMAP", use_colourmap, DDF_MainGetColourmap),
187 DF("GRAVITY", gravity, DDF_MainGetFloat),
188 DF("FRICTION", friction, DDF_MainGetFloat),
189 DF("VISCOSITY", viscosity, DDF_MainGetFloat),
190 DF("DRAG", drag, DDF_MainGetFloat),
191 DF("AMBIENT_SOUND", ambient_sfx, DDF_MainLookupSound),
192 DF("ACTIVATE_SOUND", activate_sfx, DDF_MainLookupSound),
193 DF("MUSIC", music, DDF_MainGetNumeric),
194 DF("AUTO", autoline, DDF_MainGetBoolean),
195 DF("SINGLESIDED", singlesided, DDF_MainGetBoolean),
196 DF("EXTRAFLOOR_TYPE", ef.type, DDF_LineGetExtraFloor),
197 DF("EXTRAFLOOR_CONTROL", ef.control, DDF_LineGetEFControl),
198 DF("TRANSLUCENCY", translucency, DDF_MainGetPercent),
199 DF("WHEN_APPEAR", appear, DDF_MainGetWhenAppear),
200 DF("SPECIAL", special_flags, DDF_LineGetSpecialFlags),
201 DF("RADIUS_TRIGGER", trigger_effect, DDF_LineGetRadTrig),
202 DF("LINE_EFFECT", line_effect, DDF_LineGetLineEffect),
203 DF("LINE_PARTS", line_parts, DDF_LineGetScrollPart),
204 DF("SECTOR_EFFECT", sector_effect, DDF_LineGetSectorEffect),
205 DF("PORTAL_TYPE", portal_effect, DDF_LineGetPortalEffect),
206 DF("SLOPE_TYPE", slope_type, DDF_LineGetSlopeType),
207 DF("COLOUR", fx_color, DDF_MainGetRGB),
208
209 // -AJA- backwards compatibility cruft...
210 DF("EXTRAFLOOR_TRANSLUCENCY", translucency, DDF_MainGetPercent),
211
212 DDF_CMD_END
213 };
214
215
216 typedef struct
217 {
218 const char *s;
219 scrolldirs_e dir;
220 }
221 scroll_kludge_t;
222
223 static scroll_kludge_t s_scroll[] =
224 {
225 { "NONE", dir_none },
226 { "UP", (scrolldirs_e)(dir_vert | dir_up) },
227 { "DOWN", dir_vert },
228 { "LEFT", (scrolldirs_e)(dir_horiz | dir_left) },
229 { "RIGHT", dir_horiz },
230 { NULL, dir_none }
231 };
232
233
234 static struct // FIXME: APPLIES TO NEXT 3 TABLES !
235 {
236 const char *s;
237 int n;
238 }
239
240 // FIXME: use keytype_names (in ddf_mobj.c)
241 s_keys[] =
242 {
243 { "NONE", KF_NONE },
244
245 { "BLUE_CARD", KF_BlueCard },
246 { "YELLOW_CARD", KF_YellowCard },
247 { "RED_CARD", KF_RedCard },
248 { "BLUE_SKULL", KF_BlueSkull },
249 { "YELLOW_SKULL", KF_YellowSkull },
250 { "RED_SKULL", KF_RedSkull },
251 { "GREEN_CARD", KF_GreenCard },
252 { "GREEN_SKULL", KF_GreenSkull },
253
254 { "GOLD_KEY", KF_GoldKey },
255 { "SILVER_KEY", KF_SilverKey },
256 { "BRASS_KEY", KF_BrassKey },
257 { "COPPER_KEY", KF_CopperKey },
258 { "STEEL_KEY", KF_SteelKey },
259 { "WOODEN_KEY", KF_WoodenKey },
260 { "FIRE_KEY", KF_FireKey },
261 { "WATER_KEY", KF_WaterKey },
262
263 // backwards compatibility
264 { "REQUIRES_ALL", KF_STRICTLY_ALL |
265 KF_BlueCard | KF_YellowCard | KF_RedCard |
266 KF_BlueSkull | KF_YellowSkull | KF_RedSkull }
267 }
268 ,
269
270 s_trigger[] =
271 {
272 { "WALK", line_walkable },
273 { "PUSH", line_pushable },
274 { "SHOOT", line_shootable },
275 { "MANUAL", line_manual }
276 }
277 ,
278
279 s_activators[] =
280 {
281 { "PLAYER", trig_player } ,
282 { "MONSTER", trig_monster },
283 { "OTHER", trig_other },
284 { "NOBOT", trig_nobot } ,
285
286 // obsolete stuff
287 { "MISSILE", 0 }
288 };
289
290 //
291 // DDF PARSE ROUTINES
292 //
293
LinedefStartEntry(const char * name,bool extend)294 static void LinedefStartEntry(const char *name, bool extend)
295 {
296 int number = MAX(0, atoi(name));
297
298 if (number == 0)
299 DDF_Error("Bad linetype number in lines.ddf: %s\n", name);
300
301 scrolling_dir = dir_none;
302 scrolling_speed = 1.0f;
303
304 dynamic_line = linetypes.Lookup(number);
305
306 if (extend)
307 {
308 if (! dynamic_line)
309 DDF_Error("Unknown linetype to extend: %s\n", name);
310 return;
311 }
312
313 // replaces an existing entry?
314 if (dynamic_line)
315 {
316 dynamic_line->Default();
317 return;
318 }
319
320 // not found, create a new one
321 dynamic_line = new linetype_c;
322 dynamic_line->number = number;
323
324 linetypes.Insert(dynamic_line);
325 }
326
327
LinedefDoTemplate(const char * contents)328 static void LinedefDoTemplate(const char *contents)
329 {
330 int number = MAX(0, atoi(contents));
331 if (number == 0)
332 DDF_Error("Bad linetype number for template: %s\n", contents);
333
334 linetype_c *other = linetypes.Lookup(number);
335
336 if (!other || other == dynamic_line)
337 DDF_Error("Unknown linetype template: '%s'\n", contents);
338
339 dynamic_line->CopyDetail(*other);
340 }
341
342
LinedefParseField(const char * field,const char * contents,int index,bool is_last)343 static void LinedefParseField(const char *field, const char *contents,
344 int index, bool is_last)
345 {
346 #if (DEBUG_DDF)
347 I_Debugf("LINEDEF_PARSE: %s = %s;\n", field, contents);
348 #endif
349
350 if (DDF_CompareName(field, "TEMPLATE") == 0)
351 {
352 LinedefDoTemplate(contents);
353 return;
354 }
355
356 // ignored for backwards compatibility
357 if (DDF_CompareName(field, "SECSPECIAL") == 0)
358 return;
359
360 // -AJA- backwards compatibility cruft...
361 if (DDF_CompareName(field, "CRUSH") == 0)
362 {
363 DDF_LineMakeCrush(contents);
364 return;
365 }
366 else if (DDF_CompareName(field, "SCROLL") == 0)
367 {
368 DDF_LineGetScroller(contents, &scrolling_dir);
369 return;
370 }
371 else if (DDF_CompareName(field, "SCROLLING_SPEED") == 0)
372 {
373 scrolling_speed = atof(contents);
374 return;
375 }
376
377 if (DDF_MainParseField(linedef_commands, field, contents, (byte *)dynamic_line))
378 return; // OK
379
380 DDF_WarnError("Unknown lines.ddf command: %s\n", field);
381 }
382
383
LinedefFinishEntry(void)384 static void LinedefFinishEntry(void)
385 {
386 // -KM- 1999/01/29 Convert old style scroller to new.
387 if (scrolling_dir & dir_vert)
388 {
389 if (scrolling_dir & dir_up)
390 dynamic_line->s_yspeed = scrolling_speed;
391 else
392 dynamic_line->s_yspeed = -scrolling_speed;
393 }
394
395 if (scrolling_dir & dir_horiz)
396 {
397 if (scrolling_dir & dir_left)
398 dynamic_line->s_xspeed = scrolling_speed;
399 else
400 dynamic_line->s_xspeed = -scrolling_speed;
401 }
402
403 // backwards compat: COUNT=0 means no limit on triggering
404 if (dynamic_line->count == 0)
405 dynamic_line->count = -1;
406
407 if (dynamic_line->hub_exit > 0)
408 dynamic_line->e_exit = EXIT_Hub;
409
410 // check stuff...
411
412 if (dynamic_line->ef.type != EXFL_None)
413 {
414 // AUTO is no longer needed for extrafloors
415 dynamic_line->autoline = false;
416
417 if ((dynamic_line->ef.type & EXFL_Flooder) && (dynamic_line->ef.type & EXFL_NoShade))
418 {
419 DDF_WarnError("FLOODER and NOSHADE tags cannot be used together.\n");
420 dynamic_line->ef.type = (extrafloor_type_e)(dynamic_line->ef.type & ~EXFL_Flooder);
421 }
422
423 if (! (dynamic_line->ef.type & EXFL_Present))
424 {
425 DDF_WarnError("Extrafloor type missing THIN, THICK or LIQUID.\n");
426 dynamic_line->ef.type = EXFL_None;
427 }
428 }
429
430 if (dynamic_line->friction != FLO_UNUSED && dynamic_line->friction < 0.05f)
431 {
432 DDF_WarnError("Friction value too low (%1.2f), it would prevent "
433 "all movement.\n", dynamic_line->friction);
434 dynamic_line->friction = 0.05f;
435 }
436
437 if (dynamic_line->viscosity != FLO_UNUSED && dynamic_line->viscosity > 0.95f)
438 {
439 DDF_WarnError("Viscosity value too high (%1.2f), it would prevent "
440 "all movement.\n", dynamic_line->viscosity);
441 dynamic_line->viscosity = 0.95f;
442 }
443
444 // TODO: check more stuff...
445 }
446
447
LinedefClearAll(void)448 static void LinedefClearAll(void)
449 {
450 // 100% safe to delete all the linetypes
451 linetypes.Reset();
452 }
453
454 //
455 // DDF_ReadLines
456 //
DDF_ReadLines(void * data,int size)457 bool DDF_ReadLines(void *data, int size)
458 {
459 readinfo_t lines;
460
461 lines.memfile = (char*)data;
462 lines.memsize = size;
463 lines.tag = "LINES";
464 lines.entries_per_dot = 6;
465
466 if (lines.memfile)
467 {
468 lines.message = NULL;
469 lines.filename = NULL;
470 lines.lumpname = "DDFLINE";
471 }
472 else
473 {
474 lines.message = "DDF_InitLinedefs";
475 lines.filename = "lines.ddf";
476 lines.lumpname = NULL;
477 }
478
479 lines.start_entry = LinedefStartEntry;
480 lines.parse_field = LinedefParseField;
481 lines.finish_entry = LinedefFinishEntry;
482 lines.clear_all = LinedefClearAll;
483
484 return DDF_MainReadFile(&lines);
485 }
486
487 //
488 // DDF_LinedefInit
489 //
DDF_LinedefInit(void)490 void DDF_LinedefInit(void)
491 {
492 linetypes.Reset();
493
494 default_linetype = new linetype_c();
495 default_linetype->number = 0;
496 }
497
498 //
499 // DDF_LinedefCleanUp
500 //
DDF_LinedefCleanUp(void)501 void DDF_LinedefCleanUp(void)
502 {
503 epi::array_iterator_c it;
504 linetype_c *l;
505
506 for (it=linetypes.GetBaseIterator(); it.IsValid(); it++)
507 {
508 l = ITERATOR_TO_TYPE(it, linetype_c*);
509
510 cur_ddf_entryname = epi::STR_Format("[%d] (lines.ddf)", l->number);
511
512 l->t.inspawnobj = l->t.inspawnobj_ref ?
513 mobjtypes.Lookup(l->t.inspawnobj_ref) : NULL;
514
515 l->t.outspawnobj = l->t.outspawnobj_ref ?
516 mobjtypes.Lookup(l->t.outspawnobj_ref) : NULL;
517
518 cur_ddf_entryname.clear();
519 }
520
521 linetypes.Trim();
522 }
523
524 //
525 // DDF_LineGetScroller
526 //
527 // Check for scroll types
528 //
DDF_LineGetScroller(const char * info,void * storage)529 void DDF_LineGetScroller(const char *info, void *storage)
530 {
531 for (int i = 0; s_scroll[i].s; i++)
532 {
533 if (DDF_CompareName(info, s_scroll[i].s) == 0)
534 {
535 scrolling_dir = (scrolldirs_e)(scrolling_dir | s_scroll[i].dir);
536 return;
537 }
538 }
539 DDF_WarnError("Unknown scroll direction %s\n", info);
540 }
541
542 //
543 // DDF_LineGetSecurity
544 //
545 // Get Red/Blue/Yellow
546 //
DDF_LineGetSecurity(const char * info,void * storage)547 void DDF_LineGetSecurity(const char *info, void *storage)
548 {
549 keys_e *var = (keys_e *)storage;
550
551 bool required = false;
552
553 if (info[0] == '+')
554 {
555 required = true;
556 info++;
557 }
558 else if (*var & KF_STRICTLY_ALL)
559 {
560 // -AJA- when there is at least one required key, then the
561 // non-required keys don't have any effect.
562 return;
563 }
564
565 for (int i = sizeof(s_keys) / sizeof(s_keys[0]); i--; )
566 {
567 if (DDF_CompareName(info, s_keys[i].s) == 0)
568 {
569 *var = (keys_e)(*var | s_keys[i].n);
570
571 if (required)
572 *var = (keys_e)(*var | KF_STRICTLY_ALL);
573
574 return;
575 }
576 }
577
578 DDF_WarnError("Unknown key type %s\n", info);
579 }
580
581 //
582 // DDF_LineGetTrigType
583 //
584 // Check for walk/push/shoot
585 //
DDF_LineGetTrigType(const char * info,void * storage)586 void DDF_LineGetTrigType(const char *info, void *storage)
587 {
588 trigger_e *var = (trigger_e *)storage;
589
590 for (int i = sizeof(s_trigger) / sizeof(s_trigger[0]); i--; )
591 {
592 if (DDF_CompareName(info, s_trigger[i].s) == 0)
593 {
594 #if 0 // DISABLED FOR NOW
595 if (global_flags.edge_compat && (trigger_e)s_trigger[i].n == line_manual)
596 {
597 *var = line_pushable;
598 return;
599 }
600 #endif
601 *var = (trigger_e)s_trigger[i].n;
602 return;
603 }
604 }
605
606 DDF_WarnError("Unknown Trigger type %s\n", info);
607 }
608
609 //
610 // DDF_LineGetActivators
611 //
612 // Get player/monsters/missiles
613 //
DDF_LineGetActivators(const char * info,void * storage)614 void DDF_LineGetActivators(const char *info, void *storage)
615 {
616 trigacttype_e *var = (trigacttype_e *)storage;
617
618 for (int i = sizeof(s_activators) / sizeof(s_activators[0]); i--; )
619 {
620 if (DDF_CompareName(info, s_activators[i].s) == 0)
621 {
622 *var = (trigacttype_e)(*var | s_activators[i].n);
623 return;
624 }
625 }
626
627 DDF_WarnError("Unknown Activator type %s\n", info);
628 }
629
630 static specflags_t extrafloor_types[] =
631 {
632 // definers:
633 {"THIN", EF_DEF_THIN, 0},
634 {"THICK", EF_DEF_THICK, 0},
635 {"LIQUID", EF_DEF_LIQUID, 0},
636
637 // modifiers:
638 {"SEE_THROUGH", EXFL_SeeThrough, 0},
639 {"WATER", EXFL_Water, 0},
640 {"SHADE", EXFL_NoShade, 1},
641 {"FLOODER", EXFL_Flooder, 0},
642 {"SIDE_UPPER", EXFL_SideUpper, 0},
643 {"SIDE_LOWER", EXFL_SideLower, 0},
644 {"SIDE_MIDY", EXFL_SideMidY, 0},
645 {"BOOMTEX", EXFL_BoomTex, 0},
646
647 // backwards compatibility...
648 {"FALL_THROUGH", EXFL_Liquid, 0},
649 {"SHOOT_THROUGH", 0, 0},
650 {NULL, 0, 0}
651 };
652
653 //
654 // DDF_LineGetExtraFloor
655 //
656 // Gets the extra floor type(s).
657 //
658 // -AJA- 1999/06/21: written.
659 // -AJA- 2000/03/27: updated for simpler system.
660 //
DDF_LineGetExtraFloor(const char * info,void * storage)661 void DDF_LineGetExtraFloor(const char *info, void *storage)
662 {
663 extrafloor_type_e *var = (extrafloor_type_e *)storage;
664
665 if (DDF_CompareName(info, "NONE") == 0)
666 {
667 *var = EXFL_None;
668 return;
669 }
670
671 int flag_value;
672
673 switch (DDF_MainCheckSpecialFlag(info, extrafloor_types,
674 &flag_value, true, false))
675 {
676 case CHKF_Positive:
677 *var = (extrafloor_type_e)(*var | flag_value);
678 break;
679
680 case CHKF_Negative:
681 *var = (extrafloor_type_e)(*var & ~flag_value);
682 break;
683
684 case CHKF_User:
685 case CHKF_Unknown:
686 DDF_WarnError("Unknown Extrafloor Type: %s\n", info);
687 break;
688 }
689 }
690
691 static specflags_t ef_control_types[] =
692 {
693 {"NONE", EFCTL_None, 0},
694 {"REMOVE", EFCTL_Remove, 0},
695 {NULL, 0, 0}
696 };
697
698 //
699 // DDF_LineGetEFControl
700 //
DDF_LineGetEFControl(const char * info,void * storage)701 void DDF_LineGetEFControl(const char *info, void *storage)
702 {
703 extrafloor_control_e *var = (extrafloor_control_e *)storage;
704
705 int flag_value;
706
707 switch (DDF_MainCheckSpecialFlag(info, ef_control_types, &flag_value,
708 false, false))
709 {
710 case CHKF_Positive:
711 case CHKF_Negative:
712 *var = (extrafloor_control_e) flag_value;
713 break;
714
715 case CHKF_User:
716 case CHKF_Unknown:
717 DDF_WarnError("Unknown CONTROL_EXTRAFLOOR tag: %s", info);
718 break;
719 }
720 }
721
722 #define TELSP_AllSame \
723 ((teleportspecial_e)(TELSP_Relative | TELSP_SameHeight | \
724 TELSP_SameSpeed | TELSP_SameOffset))
725
726 #define TELSP_Preserve \
727 ((teleportspecial_e)(TELSP_SameAbsDir | TELSP_SameHeight | TELSP_SameSpeed))
728
729 static specflags_t teleport_specials[] =
730 {
731 {"RELATIVE", TELSP_Relative, 0},
732 {"SAME_HEIGHT",TELSP_SameHeight, 0},
733 {"SAME_SPEED", TELSP_SameSpeed, 0},
734 {"SAME_OFFSET",TELSP_SameOffset, 0},
735 {"ALL_SAME", TELSP_AllSame, 0},
736
737 {"LINE", TELSP_Line, 0},
738 {"FLIPPED", TELSP_Flipped, 0},
739 {"SILENT", TELSP_Silent, 0},
740
741 // these modes are deprecated (kept for B.C.)
742 {"SAME_DIR", TELSP_SameAbsDir, 0},
743 {"ROTATE", TELSP_Rotate, 0},
744 {"PRESERVE", TELSP_Preserve, 0},
745
746 {NULL, 0, 0}
747 };
748
749 //
750 // DDF_LineGetTeleportSpecial
751 //
752 // Gets the teleporter special flags.
753 //
754 // -AJA- 1999/07/12: written.
755 //
DDF_LineGetTeleportSpecial(const char * info,void * storage)756 void DDF_LineGetTeleportSpecial(const char *info, void *storage)
757 {
758 teleportspecial_e *var = (teleportspecial_e *)storage;
759
760 int flag_value;
761
762 switch (DDF_MainCheckSpecialFlag(info, teleport_specials,
763 &flag_value, true, false))
764 {
765 case CHKF_Positive:
766 *var = (teleportspecial_e)(*var | flag_value);
767 break;
768
769 case CHKF_Negative:
770 *var = (teleportspecial_e)(*var & ~flag_value);
771 break;
772
773 case CHKF_User:
774 case CHKF_Unknown:
775 DDF_WarnError("DDF_LineGetTeleportSpecial: Unknown Special: %s\n", info);
776 break;
777 }
778 }
779
780 static specflags_t scrollpart_specials[] =
781 {
782 {"RIGHT_UPPER", SCPT_RightUpper, 0},
783 {"RIGHT_MIDDLE", SCPT_RightMiddle, 0},
784 {"RIGHT_LOWER", SCPT_RightLower, 0},
785 {"RIGHT", SCPT_RIGHT, 0},
786 {"LEFT_UPPER", SCPT_LeftUpper, 0},
787 {"LEFT_MIDDLE", SCPT_LeftMiddle, 0},
788 {"LEFT_LOWER", SCPT_LeftLower, 0},
789 {"LEFT", SCPT_LEFT, 0},
790 {"LEFT_REVERSE_X", SCPT_LeftRevX, 0},
791 {"LEFT_REVERSE_Y", SCPT_LeftRevY, 0},
792 {NULL, 0, 0}
793 };
794
795 //
796 // DDF_LineGetScrollPart
797 //
798 // Gets the scroll part flags.
799 //
800 // -AJA- 1999/07/12: written.
801 //
DDF_LineGetScrollPart(const char * info,void * storage)802 void DDF_LineGetScrollPart(const char *info, void *storage)
803 {
804 int flag_value;
805 scroll_part_e *dest = (scroll_part_e *)storage;
806
807 if (DDF_CompareName(info, "NONE") == 0)
808 {
809 (*dest) = SCPT_None;
810 return;
811 }
812
813 switch (DDF_MainCheckSpecialFlag(info, scrollpart_specials,
814 &flag_value, true, false))
815 {
816 case CHKF_Positive:
817 (*dest) = (scroll_part_e)((*dest) | flag_value);
818 break;
819
820 case CHKF_Negative:
821 (*dest) = (scroll_part_e)((*dest) & ~flag_value);
822 break;
823
824 case CHKF_User:
825 case CHKF_Unknown:
826 DDF_WarnError("DDF_LineGetScrollPart: Unknown Part: %s", info);
827 break;
828 }
829 }
830
831 //----------------------------------------------------------------------------
832
833 static specflags_t line_specials[] =
834 {
835 {"MUST_REACH", LINSP_MustReach, 0},
836 {"SWITCH_SEPARATE", LINSP_SwitchSeparate, 0},
837 {"BACK_SECTOR", LINSP_BackSector, 0},
838 {NULL, 0, 0}
839 };
840
841 //
842 // DDF_LineGetSpecialFlags
843 //
844 // Gets the line special flags.
845 //
DDF_LineGetSpecialFlags(const char * info,void * storage)846 void DDF_LineGetSpecialFlags(const char *info, void *storage)
847 {
848 line_special_e *var = (line_special_e *)storage;
849
850 int flag_value;
851
852 switch (DDF_MainCheckSpecialFlag(info, line_specials, &flag_value,
853 true, false))
854 {
855 case CHKF_Positive:
856 *var = (line_special_e)(*var | flag_value);
857 break;
858
859 case CHKF_Negative:
860 *var = (line_special_e)(*var & ~flag_value);
861 break;
862
863 case CHKF_User:
864 case CHKF_Unknown:
865 DDF_WarnError("Unknown line special: %s", info);
866 break;
867 }
868 }
869
870 //
871 // DDF_LineGetRadTrig
872 //
873 // Gets the line's radius trigger effect.
874 //
DDF_LineGetRadTrig(const char * info,void * storage)875 static void DDF_LineGetRadTrig(const char *info, void *storage)
876 {
877 int *trigger_effect = (int *)storage;
878
879 if (DDF_CompareName(info, "ENABLE_TAGGED") == 0)
880 {
881 *trigger_effect = +1;
882 return;
883 }
884 if (DDF_CompareName(info, "DISABLE_TAGGED") == 0)
885 {
886 *trigger_effect = -1;
887 return;
888 }
889
890 DDF_WarnError("DDF_LineGetRadTrig: Unknown effect: %s\n", info);
891 }
892
893 static const specflags_t slidingdoor_names[] =
894 {
895 {"NONE", SLIDE_None, 0},
896 {"LEFT", SLIDE_Left, 0},
897 {"RIGHT", SLIDE_Right, 0},
898 {"CENTER", SLIDE_Center, 0},
899 {"CENTRE", SLIDE_Center, 0}, // synonym
900 {NULL, 0, 0}
901 };
902
903 //
904 // DDF_LineGetSlideType
905 //
DDF_LineGetSlideType(const char * info,void * storage)906 static void DDF_LineGetSlideType(const char *info, void *storage)
907 {
908 if (CHKF_Positive != DDF_MainCheckSpecialFlag(info,
909 slidingdoor_names, (int *) storage, false, false))
910 {
911 DDF_WarnError("DDF_LineGetSlideType: Unknown slider: %s\n", info);
912 }
913 }
914
915 static specflags_t line_effect_names[] =
916 {
917 {"TRANSLUCENT", LINEFX_Translucency, 0},
918 {"VECTOR_SCROLL", LINEFX_VectorScroll, 0},
919 {"OFFSET_SCROLL", LINEFX_OffsetScroll, 0},
920
921 {"SCALE_TEX", LINEFX_Scale, 0},
922 {"SKEW_TEX", LINEFX_Skew, 0},
923 {"LIGHT_WALL", LINEFX_LightWall, 0},
924
925 {"UNBLOCK_THINGS", LINEFX_UnblockThings, 0},
926 {"BLOCK_SHOTS", LINEFX_BlockShots, 0},
927 {"BLOCK_SIGHT", LINEFX_BlockSight, 0},
928 {NULL, 0, 0}
929 };
930
931 //
932 // Gets the line effect flags.
933 //
DDF_LineGetLineEffect(const char * info,void * storage)934 static void DDF_LineGetLineEffect(const char *info, void *storage)
935 {
936 line_effect_type_e *var = (line_effect_type_e *)storage;
937
938 int flag_value;
939
940 if (DDF_CompareName(info, "NONE") == 0)
941 {
942 *var = LINEFX_NONE;
943 return;
944 }
945
946 switch (DDF_MainCheckSpecialFlag(info, line_effect_names,
947 &flag_value, true, false))
948 {
949 case CHKF_Positive:
950 *var = (line_effect_type_e)(*var | flag_value);
951 break;
952
953 case CHKF_Negative:
954 *var = (line_effect_type_e)(*var & ~flag_value);
955 break;
956
957 case CHKF_User:
958 case CHKF_Unknown:
959 DDF_WarnError("Unknown line effect type: %s", info);
960 break;
961 }
962 }
963
964 static specflags_t sector_effect_names[] =
965 {
966 {"LIGHT_FLOOR", SECTFX_LightFloor, 0},
967 {"LIGHT_CEILING", SECTFX_LightCeiling, 0},
968 {"SCROLL_FLOOR", SECTFX_ScrollFloor, 0},
969 {"SCROLL_CEILING", SECTFX_ScrollCeiling, 0},
970 {"PUSH_THINGS", SECTFX_PushThings, 0},
971
972 {"SET_FRICTION", SECTFX_SetFriction, 0},
973 {"WIND_FORCE", SECTFX_WindForce, 0},
974 {"CURRENT_FORCE", SECTFX_CurrentForce, 0},
975 {"POINT_FORCE", SECTFX_PointForce, 0},
976
977 {"RESET_FLOOR", SECTFX_ResetFloor, 0},
978 {"RESET_CEILING", SECTFX_ResetCeiling, 0},
979 {"ALIGN_FLOOR", SECTFX_AlignFloor, 0},
980 {"ALIGN_CEILING", SECTFX_AlignCeiling, 0},
981 {"SCALE_FLOOR", SECTFX_ScaleFloor, 0},
982 {"SCALE_CEILING", SECTFX_ScaleCeiling, 0},
983 {NULL, 0, 0}
984 };
985
986 //
987 // Gets the sector effect flags.
988 //
DDF_LineGetSectorEffect(const char * info,void * storage)989 static void DDF_LineGetSectorEffect(const char *info, void *storage)
990 {
991 sector_effect_type_e *var = (sector_effect_type_e *)storage;
992
993 int flag_value;
994
995 if (DDF_CompareName(info, "NONE") == 0)
996 {
997 *var = SECTFX_None;
998 return;
999 }
1000
1001 switch (DDF_MainCheckSpecialFlag(info, sector_effect_names, &flag_value,
1002 true, false))
1003 {
1004 case CHKF_Positive:
1005 *var = (sector_effect_type_e)(*var | flag_value);
1006 break;
1007
1008 case CHKF_Negative:
1009 *var = (sector_effect_type_e)(*var & ~flag_value);
1010 break;
1011
1012 case CHKF_User:
1013 case CHKF_Unknown:
1014 DDF_WarnError("Unknown sector effect type: %s", info);
1015 break;
1016 }
1017 }
1018
1019 static specflags_t portal_effect_names[] =
1020 {
1021 {"STANDARD", PORTFX_Standard, 0},
1022 {"MIRROR", PORTFX_Mirror, 0},
1023 {"CAMERA", PORTFX_Camera, 0},
1024
1025 {NULL, 0, 0}
1026 };
1027
1028 //
1029 // Gets the portal effect flags.
1030 //
DDF_LineGetPortalEffect(const char * info,void * storage)1031 static void DDF_LineGetPortalEffect(const char *info, void *storage)
1032 {
1033 portal_effect_type_e *var = (portal_effect_type_e *)storage;
1034
1035 int flag_value;
1036
1037 if (DDF_CompareName(info, "NONE") == 0)
1038 {
1039 *var = PORTFX_None;
1040 return;
1041 }
1042
1043 switch (DDF_MainCheckSpecialFlag(info, portal_effect_names, &flag_value,
1044 true, false))
1045 {
1046 case CHKF_Positive:
1047 *var = (portal_effect_type_e)(*var | flag_value);
1048 break;
1049
1050 case CHKF_Negative:
1051 *var = (portal_effect_type_e)(*var & ~flag_value);
1052 break;
1053
1054 case CHKF_User:
1055 case CHKF_Unknown:
1056 DDF_WarnError("Unknown portal type: %s", info);
1057 break;
1058 }
1059 }
1060
1061 static specflags_t slope_type_names[] =
1062 {
1063 {"FAKE_FLOOR", SLP_DetailFloor, 0},
1064 {"FAKE_CEILING", SLP_DetailCeiling, 0},
1065
1066 {NULL, 0, 0}
1067 };
1068
DDF_LineGetSlopeType(const char * info,void * storage)1069 static void DDF_LineGetSlopeType(const char *info, void *storage)
1070 {
1071 slope_type_e *var = (slope_type_e *)storage;
1072
1073 int flag_value;
1074
1075 if (DDF_CompareName(info, "NONE") == 0)
1076 {
1077 *var = SLP_NONE;
1078 return;
1079 }
1080
1081 switch (DDF_MainCheckSpecialFlag(info, slope_type_names, &flag_value,
1082 true, false))
1083 {
1084 case CHKF_Positive:
1085 *var = (slope_type_e)(*var | flag_value);
1086 break;
1087
1088 case CHKF_Negative:
1089 *var = (slope_type_e)(*var & ~flag_value);
1090 break;
1091
1092 case CHKF_User:
1093 case CHKF_Unknown:
1094 DDF_WarnError("Unknown slope type: %s", info);
1095 break;
1096 }
1097 }
1098
DDF_LineMakeCrush(const char * info)1099 static void DDF_LineMakeCrush(const char *info)
1100 {
1101 dynamic_line->f.crush_damage = 10;
1102 dynamic_line->c.crush_damage = 10;
1103 }
1104
1105
1106 //----------------------------------------------------------------------------
1107
1108
1109 // --> Donut definition class
1110
1111 //
1112 // donutdef_c Constructor
1113 //
donutdef_c()1114 donutdef_c::donutdef_c()
1115 {
1116 }
1117
1118 //
1119 // donutdef_c Copy constructor
1120 //
donutdef_c(donutdef_c & rhs)1121 donutdef_c::donutdef_c(donutdef_c &rhs)
1122 {
1123 Copy(rhs);
1124 }
1125
1126 //
1127 // donutdef_c Destructor
1128 //
~donutdef_c()1129 donutdef_c::~donutdef_c()
1130 {
1131 }
1132
1133 //
1134 // donutdef_c::Copy()
1135 //
Copy(donutdef_c & src)1136 void donutdef_c::Copy(donutdef_c &src)
1137 {
1138 dodonut = src.dodonut;
1139
1140 // FIXME! Strip out the d_ since we're not trying to
1141 // to differentiate them now?
1142 d_sfxin = src.d_sfxin;
1143 d_sfxinstop = src.d_sfxinstop;
1144 d_sfxout = src.d_sfxout;
1145 d_sfxoutstop = src.d_sfxoutstop;
1146 }
1147
1148 //
1149 // donutdef_c::Default()
1150 //
Default()1151 void donutdef_c::Default()
1152 {
1153 dodonut = false;
1154 d_sfxin = NULL;
1155 d_sfxinstop = NULL;
1156 d_sfxout = NULL;
1157 d_sfxoutstop = NULL;
1158 }
1159
1160 //
1161 // donutdef_c assignment operator
1162 //
operator =(donutdef_c & rhs)1163 donutdef_c& donutdef_c::operator=(donutdef_c &rhs)
1164 {
1165 if(&rhs != this)
1166 Copy(rhs);
1167
1168 return *this;
1169 }
1170
1171
1172 // --> Extrafloor definition class
1173
1174 //
1175 // extrafloordef_c Constructor
1176 //
extrafloordef_c()1177 extrafloordef_c::extrafloordef_c()
1178 {
1179 }
1180
1181 //
1182 // extrafloordef_c Copy constructor
1183 //
extrafloordef_c(extrafloordef_c & rhs)1184 extrafloordef_c::extrafloordef_c(extrafloordef_c &rhs)
1185 {
1186 Copy(rhs);
1187 }
1188
1189 //
1190 // extrafloordef_c Destructor
1191 //
~extrafloordef_c()1192 extrafloordef_c::~extrafloordef_c()
1193 {
1194 }
1195
1196 //
1197 // extrafloordef_c::Copy()
1198 //
Copy(extrafloordef_c & src)1199 void extrafloordef_c::Copy(extrafloordef_c &src)
1200 {
1201 control = src.control;
1202 type = src.type;
1203 }
1204
1205 //
1206 // extrafloordef_c::Default()
1207 //
Default()1208 void extrafloordef_c::Default()
1209 {
1210 control = EFCTL_None;
1211 type = EXFL_None;
1212 }
1213
1214 //
1215 // extrafloordef_c assignment operator
1216 //
operator =(extrafloordef_c & rhs)1217 extrafloordef_c& extrafloordef_c::operator=(extrafloordef_c &rhs)
1218 {
1219 if(&rhs != this)
1220 Copy(rhs);
1221
1222 return *this;
1223 }
1224
1225
1226 // --> Ladder definition class
1227
1228 //
1229 // ladderdef_c Constructor
1230 //
ladderdef_c()1231 ladderdef_c::ladderdef_c()
1232 {
1233 }
1234
1235 //
1236 // ladderdef_c Copy constructor
1237 //
ladderdef_c(ladderdef_c & rhs)1238 ladderdef_c::ladderdef_c(ladderdef_c &rhs)
1239 {
1240 Copy(rhs);
1241 }
1242
1243 //
1244 // ladderdef_c Destructor
1245 //
~ladderdef_c()1246 ladderdef_c::~ladderdef_c()
1247 {
1248 }
1249
1250 //
1251 // ladderdef_c::Copy()
1252 //
Copy(ladderdef_c & src)1253 void ladderdef_c::Copy(ladderdef_c &src)
1254 {
1255 height = src.height;
1256 }
1257
1258 //
1259 // ladderdef_c::Default()
1260 //
Default()1261 void ladderdef_c::Default()
1262 {
1263 height = 0.0f;
1264 }
1265
1266 //
1267 // ladderdef_c assignment operator
1268 //
operator =(ladderdef_c & rhs)1269 ladderdef_c& ladderdef_c::operator=(ladderdef_c &rhs)
1270 {
1271 if(&rhs != this)
1272 Copy(rhs);
1273
1274 return *this;
1275 }
1276
1277 // --> Light effect definition class
1278
1279 //
1280 // lightdef_c Constructor
1281 //
lightdef_c()1282 lightdef_c::lightdef_c()
1283 {
1284 }
1285
1286 //
1287 // lightdef_c Copy constructor
1288 //
lightdef_c(lightdef_c & rhs)1289 lightdef_c::lightdef_c(lightdef_c &rhs)
1290 {
1291 Copy(rhs);
1292 }
1293
1294 //
1295 // lightdef_c Destructor
1296 //
~lightdef_c()1297 lightdef_c::~lightdef_c()
1298 {
1299 }
1300
1301 //
1302 // lightdef_c::Copy()
1303 //
Copy(lightdef_c & src)1304 void lightdef_c::Copy(lightdef_c &src)
1305 {
1306 type = src.type;
1307 level = src.level;
1308 chance = src.chance;
1309 darktime = src.darktime;
1310 brighttime = src.brighttime;
1311 sync = src.sync;
1312 step = src.step;
1313 }
1314
1315 //
1316 // lightdef_c::Default()
1317 //
Default()1318 void lightdef_c::Default()
1319 {
1320 type = LITE_None;
1321 level = 64;
1322 chance = PERCENT_MAKE(50);
1323 darktime = 0;
1324 brighttime = 0;
1325 sync = 0;
1326 step = 8;
1327 }
1328
1329 //
1330 // lightdef_c assignment operator
1331 //
operator =(lightdef_c & rhs)1332 lightdef_c& lightdef_c::operator=(lightdef_c &rhs)
1333 {
1334 if(&rhs != this)
1335 Copy(rhs);
1336
1337 return *this;
1338 }
1339
1340 // --> Moving plane definition class
1341
1342 //
1343 // movplanedef_c Constructor
1344 //
movplanedef_c()1345 movplanedef_c::movplanedef_c()
1346 {
1347 }
1348
1349 //
1350 // movplanedef_c Copy constructor
1351 //
movplanedef_c(movplanedef_c & rhs)1352 movplanedef_c::movplanedef_c(movplanedef_c &rhs)
1353 {
1354 Copy(rhs);
1355 }
1356
1357 //
1358 // movplanedef_c Destructor
1359 //
~movplanedef_c()1360 movplanedef_c::~movplanedef_c()
1361 {
1362 }
1363
1364 //
1365 // movplanedef_c::Copy()
1366 //
Copy(movplanedef_c & src)1367 void movplanedef_c::Copy(movplanedef_c &src)
1368 {
1369 type = src.type;
1370 is_ceiling = src.is_ceiling;
1371 speed_up = src.speed_up;
1372 speed_down = src.speed_down;
1373 destref = src.destref;
1374 dest = src.dest;
1375 otherref = src.otherref;
1376 other = src.other;
1377 crush_damage = src.crush_damage;
1378 tex = src.tex;
1379 wait = src.wait;
1380 prewait = src.prewait;
1381 sfxstart = src.sfxstart;
1382 sfxup = src.sfxup;
1383 sfxdown = src.sfxdown;
1384 sfxstop = src.sfxstop;
1385 scroll_angle = src.scroll_angle;
1386 scroll_speed = src.scroll_speed;
1387 ignore_texture = src.ignore_texture;
1388 }
1389
1390 //
1391 // movplanedef_c::Default()
1392 //
Default(movplanedef_c::default_e def)1393 void movplanedef_c::Default(movplanedef_c::default_e def)
1394 {
1395 type = mov_undefined;
1396
1397 if (def == DEFAULT_CeilingLine || def == DEFAULT_CeilingSect)
1398 is_ceiling = true;
1399 else
1400 is_ceiling = false;
1401
1402 switch (def)
1403 {
1404 case DEFAULT_CeilingLine:
1405 case DEFAULT_FloorLine:
1406 {
1407 speed_up = -1;
1408 speed_down = -1;
1409 break;
1410 }
1411
1412 case DEFAULT_DonutFloor:
1413 {
1414 speed_up = FLOORSPEED/2;
1415 speed_down = FLOORSPEED/2;
1416 break;
1417 }
1418
1419 default:
1420 {
1421 speed_up = 0;
1422 speed_down = 0;
1423 break;
1424 }
1425 }
1426
1427 destref = REF_Absolute;
1428
1429 // FIXME!!! Why are we using INT_MAX with a fp number?
1430 dest = (def != DEFAULT_DonutFloor) ? 0.0f : (float)INT_MAX;
1431
1432 switch (def)
1433 {
1434 case DEFAULT_CeilingLine:
1435 {
1436 otherref = (heightref_e)(REF_Current|REF_CEILING);
1437 break;
1438 }
1439
1440 case DEFAULT_FloorLine:
1441 {
1442 otherref = (heightref_e)(REF_Surrounding|REF_HIGHEST|REF_INCLUDE);
1443 break;
1444 }
1445
1446 default:
1447 {
1448 otherref = REF_Absolute;
1449 break;
1450 }
1451 }
1452
1453 // FIXME!!! Why are we using INT_MAX with a fp number?
1454 other = (def != DEFAULT_DonutFloor) ? 0.0f : (float)INT_MAX;
1455
1456 crush_damage = 0;
1457
1458 tex.clear();
1459
1460 wait = 0;
1461 prewait = 0;
1462
1463 sfxstart = NULL;
1464 sfxup = NULL;
1465 sfxdown = NULL;
1466 sfxstop = NULL;
1467
1468 scroll_angle = 0;
1469 scroll_speed = 0.0f;
1470
1471 ignore_texture = false;
1472 }
1473
1474 //
1475 // movplanedef_c assignment operator
1476 //
operator =(movplanedef_c & rhs)1477 movplanedef_c& movplanedef_c::operator=(movplanedef_c &rhs)
1478 {
1479 if(&rhs != this)
1480 Copy(rhs);
1481
1482 return *this;
1483 }
1484
1485 // --> Sliding door definition class
1486
1487 //
1488 // sliding_door_c Constructor
1489 //
sliding_door_c()1490 sliding_door_c::sliding_door_c()
1491 {
1492 }
1493
1494 //
1495 // sliding_door_c Copy constructor
1496 //
sliding_door_c(sliding_door_c & rhs)1497 sliding_door_c::sliding_door_c(sliding_door_c &rhs)
1498 {
1499 Copy(rhs);
1500 }
1501
1502 //
1503 // sliding_door_c Destructor
1504 //
~sliding_door_c()1505 sliding_door_c::~sliding_door_c()
1506 {
1507 }
1508
1509 //
1510 // sliding_door_c::Copy()
1511 //
Copy(sliding_door_c & src)1512 void sliding_door_c::Copy(sliding_door_c &src)
1513 {
1514 type = src.type;
1515 speed = src.speed;
1516 wait = src.wait;
1517 see_through = src.see_through;
1518 distance = src.distance;
1519 sfx_start = src.sfx_start;
1520 sfx_open = src.sfx_open;
1521 sfx_close = src.sfx_close;
1522 sfx_stop = src.sfx_stop;
1523 }
1524
1525 //
1526 // sliding_door_c::Default()
1527 //
Default()1528 void sliding_door_c::Default()
1529 {
1530 type = SLIDE_None;
1531 speed =4.0f;
1532 wait = 150;
1533 see_through = false;
1534 distance = PERCENT_MAKE(90);
1535 sfx_start = sfx_None;
1536 sfx_open = sfx_None;
1537 sfx_close = sfx_None;
1538 sfx_stop = sfx_None;
1539 }
1540
1541 //
1542 // sliding_door_c assignment operator
1543 //
operator =(sliding_door_c & rhs)1544 sliding_door_c& sliding_door_c::operator=(sliding_door_c &rhs)
1545 {
1546 if(&rhs != this)
1547 Copy(rhs);
1548
1549 return *this;
1550 }
1551
1552 // --> Teleport point definition class
1553
1554 //
1555 // teleportdef_c Constructor
1556 //
teleportdef_c()1557 teleportdef_c::teleportdef_c()
1558 {
1559 }
1560
1561 //
1562 // teleportdef_c Copy constructor
1563 //
teleportdef_c(teleportdef_c & rhs)1564 teleportdef_c::teleportdef_c(teleportdef_c &rhs)
1565 {
1566 Copy(rhs);
1567 }
1568
1569 //
1570 // teleportdef_c Destructor
1571 //
~teleportdef_c()1572 teleportdef_c::~teleportdef_c()
1573 {
1574 }
1575
1576 //
1577 // teleportdef_c::Copy()
1578 //
Copy(teleportdef_c & src)1579 void teleportdef_c::Copy(teleportdef_c &src)
1580 {
1581 teleport = src.teleport;
1582
1583 inspawnobj = src.inspawnobj;
1584 inspawnobj_ref = src.inspawnobj_ref;
1585
1586 outspawnobj = src.outspawnobj;
1587 outspawnobj_ref = src.outspawnobj_ref;
1588
1589 special = src.special;
1590 delay = src.delay;
1591 }
1592
1593 //
1594 // teleportdef_c::Default()
1595 //
Default()1596 void teleportdef_c::Default()
1597 {
1598 teleport = false;
1599
1600 inspawnobj = NULL;
1601 inspawnobj_ref.clear();
1602
1603 outspawnobj = NULL;
1604 outspawnobj_ref.clear();
1605
1606 delay = 0;
1607 special = TELSP_None;
1608 }
1609
1610 //
1611 // teleportdef_c assignment operator
1612 //
operator =(teleportdef_c & rhs)1613 teleportdef_c& teleportdef_c::operator=(teleportdef_c &rhs)
1614 {
1615 if(&rhs != this)
1616 Copy(rhs);
1617
1618 return *this;
1619 }
1620
1621 // --> Line definition type class
1622
1623 //
1624 // linetype_c Constructor
1625 //
linetype_c()1626 linetype_c::linetype_c() : number(0)
1627 {
1628 Default();
1629 }
1630
1631 //
1632 // linetype_c Destructor
1633 //
~linetype_c()1634 linetype_c::~linetype_c()
1635 {
1636 }
1637
1638
CopyDetail(linetype_c & src)1639 void linetype_c::CopyDetail(linetype_c &src)
1640 {
1641 newtrignum = src.newtrignum;
1642 type = src.type;
1643 obj = src.obj;
1644 keys = src.keys;
1645 count = src.count;
1646
1647 f = src.f;
1648 c = src.c;
1649 d = src.d;
1650 s = src.s;
1651 t = src.t;
1652 l = src.l;
1653
1654 ladder = src.ladder;
1655 e_exit = src.e_exit;
1656 hub_exit = src.hub_exit;
1657 s_xspeed = src.s_xspeed;
1658 s_yspeed = src.s_yspeed;
1659 scroll_parts = src.scroll_parts;
1660
1661 failedmessage = src.failedmessage;
1662 failed_sfx = src.failed_sfx;
1663
1664 use_colourmap = src.use_colourmap;
1665 gravity = src.gravity;
1666 friction = src.friction;
1667 viscosity = src.viscosity;
1668 drag = src.drag;
1669 ambient_sfx = src.ambient_sfx;
1670 activate_sfx = src.activate_sfx;
1671 music = src.music;
1672 autoline = src.autoline;
1673 singlesided = src.singlesided;
1674 ef = src.ef;
1675 translucency = src.translucency;
1676 appear = src.appear;
1677
1678 special_flags = src.special_flags;
1679 trigger_effect = src.trigger_effect;
1680 line_effect = src.line_effect;
1681 line_parts = src.line_parts;
1682 sector_effect = src.sector_effect;
1683 portal_effect = src.portal_effect;
1684 slope_type = src.slope_type;
1685 fx_color = src.fx_color;
1686 }
1687
1688
Default(void)1689 void linetype_c::Default(void)
1690 {
1691 newtrignum = 0;
1692 type = line_none;
1693 obj = trig_none;
1694 keys = KF_NONE;
1695 count = -1;
1696
1697 f.Default(movplanedef_c::DEFAULT_FloorLine);
1698 c.Default(movplanedef_c::DEFAULT_CeilingLine);
1699
1700 d.Default(); // Donut
1701 s.Default(); // Sliding Door
1702
1703 t.Default(); // Teleport
1704 l.Default(); // Light definition
1705
1706 ladder.Default(); // Ladder
1707
1708 e_exit = EXIT_None;
1709 hub_exit = 0;
1710 s_xspeed = 0.0f;
1711 s_yspeed = 0.0f;
1712 scroll_parts = SCPT_None;
1713
1714 failedmessage.clear();
1715 failed_sfx = NULL;
1716
1717 use_colourmap = NULL;
1718 gravity = FLO_UNUSED;
1719 friction = FLO_UNUSED;
1720 viscosity = FLO_UNUSED;
1721 drag = FLO_UNUSED;
1722 ambient_sfx = sfx_None;
1723 activate_sfx = sfx_None;
1724 music = 0;
1725 autoline = false;
1726 singlesided = false;
1727
1728 ef.Default();
1729
1730 translucency = PERCENT_MAKE(100);
1731 appear = DEFAULT_APPEAR;
1732 special_flags = LINSP_None;
1733 trigger_effect = 0;
1734 line_effect = LINEFX_NONE;
1735 line_parts = SCPT_None;
1736 sector_effect = SECTFX_None;
1737 portal_effect = PORTFX_None;
1738 slope_type = SLP_NONE;
1739 fx_color = RGB_MAKE(0,0,0);
1740 }
1741
1742
1743 // --> Line definition type container class
1744
1745 //
1746 // linetype_container_c Constructor
1747 //
linetype_container_c()1748 linetype_container_c::linetype_container_c() :
1749 epi::array_c(sizeof(linetype_c*))
1750 {
1751 Reset();
1752 }
1753
1754 //
1755 // linetype_container_c Destructor
1756 //
~linetype_container_c()1757 linetype_container_c::~linetype_container_c()
1758 {
1759 Clear();
1760 }
1761
1762 //
1763 // linetype_container_c::CleanupObject
1764 //
CleanupObject(void * obj)1765 void linetype_container_c::CleanupObject(void *obj)
1766 {
1767 linetype_c *l = *(linetype_c**)obj;
1768
1769 if (l)
1770 delete l;
1771
1772 return;
1773 }
1774
1775 //
1776 // linetype_c* linetype_container_c::Lookup()
1777 //
1778 // Looks an linetype by id, returns NULL if line can't be found.
1779 //
Lookup(const int id)1780 linetype_c* linetype_container_c::Lookup(const int id)
1781 {
1782 if (id == 0)
1783 return default_linetype;
1784
1785 int slot = DDF_LineHashFunc(id);
1786
1787 // check the cache
1788 if (lookup_cache[slot] &&
1789 lookup_cache[slot]->number == id)
1790 {
1791 return lookup_cache[slot];
1792 }
1793
1794 epi::array_iterator_c it;
1795
1796 for (it = GetTailIterator(); it.IsValid(); it--)
1797 {
1798 linetype_c *l = ITERATOR_TO_TYPE(it, linetype_c*);
1799
1800 if (l->number == id)
1801 {
1802 // update the cache
1803 lookup_cache[slot] = l;
1804 return l;
1805 }
1806 }
1807
1808 return NULL;
1809 }
1810
1811 //
1812 // linetype_container_c::Reset()
1813 //
1814 // Clears down both the data and the cache
1815 //
Reset()1816 void linetype_container_c::Reset()
1817 {
1818 Clear();
1819 memset(lookup_cache, 0, sizeof(linetype_c*) * LOOKUP_CACHESIZE);
1820 }
1821
1822 //--- editor settings ---
1823 // vi:ts=4:sw=4:noexpandtab
1824