3 float STATE_BOTTOM = 1;
9 void() plat_center_touch;
10 void() plat_outside_touch;
11 void() plat_trigger_use;
15 float PLAT_LOW_TRIGGER = 1;
17 void() plat_spawn_inside_trigger =
20 local vector tmin, tmax;
23 trigger.touch = plat_center_touch;
24 trigger.movetype = MOVETYPE_NONE;
25 trigger.solid = SOLID_TRIGGER;
28 tmin = self.mins + '25 25 0';
29 tmax = self.maxs - '25 25 -8';
30 tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
31 if (self.spawnflags & PLAT_LOW_TRIGGER)
34 if (self.size_x <= 50)
36 tmin_x = (self.mins_x + self.maxs_x) / 2;
39 if (self.size_y <= 50)
41 tmin_y = (self.mins_y + self.maxs_y) / 2;
45 setsize (trigger, tmin, tmax);
50 sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
52 self.think = plat_go_down;
53 self.nextthink = self.ltime + 3;
56 void() plat_hit_bottom =
58 sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
64 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
66 SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
71 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
73 SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
76 void() plat_center_touch =
78 if (other.classname != "player")
81 if (other.health <= 0)
87 else if (self.state == 1)
88 self.nextthink = self.ltime + 1; // delay going down
91 void() plat_outside_touch =
93 if (other.classname != "player")
96 if (other.health <= 0)
104 void() plat_trigger_use =
107 return; // allready activated
116 else if (self.state == 3)
119 objerror ("plat_crush: bad self.state\n");
126 objerror ("plat_use: not in up state");
131 .string sound1, sound2;
140 if (self.sounds == 0)
143 if (self.sounds == 1)
145 precache_sound ("plats/plat1.wav");
146 precache_sound ("plats/plat2.wav");
147 self.noise = "plats/plat1.wav";
148 self.noise1 = "plats/plat2.wav";
151 if (self.sounds == 2)
153 precache_sound ("plats/medplat1.wav");
154 precache_sound ("plats/medplat2.wav");
155 self.noise = "plats/medplat1.wav";
156 self.noise1 = "plats/medplat2.wav";
161 precache_sound (self.sound1);
162 self.noise = self.sound1;
166 precache_sound (self.sound2);
167 self.noise1 = self.sound2;
170 self.mangle = self.angles;
171 self.angles = '0 0 0';
173 self.classname = "plat";
174 self.solid = SOLID_BSP;
175 self.movetype = MOVETYPE_PUSH;
176 setorigin (self, self.origin);
177 setmodel (self, self.model);
178 setsize (self, self.mins , self.maxs);
180 self.blocked = plat_crush;
183 self.pos1 = self.origin;
184 self.pos2 = self.origin;
185 self.pos2_z = self.origin_z - self.size_z + 8;
187 self.use = plat_trigger_use;
189 plat_spawn_inside_trigger (); // the "start moving" trigger
198 setorigin (self, self.pos2);
206 void() func_train_find;
208 void() train_blocked =
210 if (time < self.attack_finished)
212 self.attack_finished = time + 0.5;
216 if (self.think != func_train_find)
225 self.nextthink = self.ltime + self.wait;
226 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
229 self.nextthink = self.ltime + 0.1;
231 self.think = train_next;
238 targ = find (world, targetname, self.target);
239 self.target = targ.target;
241 objerror ("train_next: no next target");
243 self.wait = targ.wait;
246 sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
247 SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
250 void() func_train_find =
254 targ = find (world, targetname, self.target);
255 self.target = targ.target;
256 setorigin (self, targ.origin - self.mins);
257 if (!self.targetname)
258 { // not triggered, so start immediately
259 self.nextthink = self.ltime + 0.1;
260 self.think = train_next;
270 objerror ("func_train without a target");
272 if (self.sounds == 0)
274 self.noise = ("misc/null.wav");
275 precache_sound ("misc/null.wav");
276 self.noise1 = ("misc/null.wav");
277 precache_sound ("misc/null.wav");
280 if (self.sounds == 1)
282 self.noise = ("plats/train2.wav");
283 precache_sound ("plats/train2.wav");
284 self.noise1 = ("plats/train1.wav");
285 precache_sound ("plats/train1.wav");
288 self.solid = SOLID_BSP;
289 self.movetype = MOVETYPE_PUSH;
290 self.blocked = train_blocked;
291 self.use = train_use;
292 self.classname = "train";
294 setmodel (self, self.model);
295 setsize (self, self.mins , self.maxs);
296 setorigin (self, self.origin);
297 self.nextthink = self.ltime + 0.1;
298 self.think = func_train_find;
305 self.think = train_next;
306 self.nextthink = self.ltime + self.wait;
312 targ = find(world, targetname, self.target);
313 self.target = targ.target;
315 objerror("train_next: no next target");
316 self.wait = targ.wait;
320 SUB_CalcMove(targ.origin - self.mins, targ.speed, train_wait);
322 SUB_CalcMove(targ.origin - self.mins, self.speed, train_wait);
325 void() func_train_find =
328 targ = find(world, targetname, self.target);
329 self.target = targ.target;
330 setorigin(self, targ.origin - self.mins);
331 self.nextthink = self.ltime + 1;
332 self.think = train_next;
335 /*QUAKED func_train (0 .5 .8) ?
336 Ridable platform, targets path_corner path to follow.
337 speed : speed the train moves (can be overridden by each path_corner)
338 target : targetname of first path_corner (starts here)
343 objerror("func_train without a target");
347 self.solid = SOLID_BSP;
348 self.movetype = MOVETYPE_PUSH;
350 setmodel(self, self.model);
351 setsize(self, self.mins, self.maxs);
352 setorigin(self, self.origin);
354 // wait for targets to spawn
355 self.nextthink = self.ltime + 0.1;
356 self.think = func_train_find;
359 /*QUAKED func_rotating (0 .5 .8) ? - - X_AXIS Y_AXIS
360 Brush model that spins in place on one axis (default Z).
361 speed : speed to rotate (in degrees per second)
362 noise : path/name of looping .wav file to play.
364 void() func_rotating =
368 precache_sound(self.noise);
369 ambientsound(self.origin, self.noise, 1, ATTN_IDLE);
373 // FIXME: test if this turns the right way, then remove this comment (negate as needed)
374 if (self.spawnflags & 4) // X (untested)
375 self.avelocity = '0 0 1' * self.speed;
376 // FIXME: test if this turns the right way, then remove this comment (negate as needed)
377 else if (self.spawnflags & 8) // Y (untested)
378 self.avelocity = '1 0 0' * self.speed;
379 // FIXME: test if this turns the right way, then remove this comment (negate as needed)
381 self.avelocity = '0 1 0' * self.speed;
383 self.solid = SOLID_BSP;
384 self.movetype = MOVETYPE_PUSH;
386 setmodel(self, self.model);
387 setsize(self, self.mins, self.maxs);
388 setorigin(self, self.origin);
390 // wait for targets to spawn
391 self.nextthink = self.ltime + 999999999;
392 self.think = SUB_Null;
397 void() func_bobbing_controller_think =
400 self.nextthink = time + 0.1;
401 // calculate sinewave using makevectors
402 makevectors((time * self.owner.cnt + self.owner.phase) * '0 1 0');
403 v = self.owner.destvec + self.owner.movedir * v_forward_y;
404 // * 10 so it will arrive in 0.1 sec
405 self.owner.velocity = (v - self.owner.origin) * 10;
408 /*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
409 Brush model that moves back and forth on one axis (default Z).
410 speed : how long one cycle takes in seconds (default 4)
411 height : how far the cycle moves (default 32)
412 phase : cycle timing adjustment (0-1 as a fraction of the cycle, default 0)
413 noise : path/name of looping .wav file to play.
415 void() func_bobbing =
417 local entity controller;
420 precache_sound(self.noise);
421 ambientsound(self.origin, self.noise, 1, ATTN_IDLE);
427 // center of bobbing motion
428 self.destvec = self.origin;
429 // time scale to get degrees
430 self.cnt = 360 / self.speed;
432 if (self.spawnflags & 1) // X
433 self.movedir = '1 0 0' * self.height;
434 else if (self.spawnflags & 2) // Y
435 self.movedir = '0 1 0' * self.height;
437 self.movedir = '0 0 1' * self.height;
439 self.solid = SOLID_BSP;
440 self.movetype = MOVETYPE_PUSH;
442 setmodel(self, self.model);
443 setsize(self, self.mins, self.maxs);
444 setorigin(self, self.origin);
446 // wait for targets to spawn
447 controller = spawn();
448 controller.classname = "func_bobbing_controller";
449 controller.owner = self;
450 controller.nextthink = time + 1;
451 controller.think = func_bobbing_controller_think;
452 self.nextthink = self.ltime + 999999999;
453 self.think = SUB_Null;
455 // Savage: Reduce bandwith, critical on e.g. nexdm02
456 self.effects |= EF_LOWPRECISION;
459 // button and multiple button
462 void() button_return;
466 self.state = STATE_TOP;
467 self.nextthink = self.ltime + self.wait;
468 self.think = button_return;
469 activator = self.enemy;
471 self.frame = 1; // use alternate textures
476 self.state = STATE_BOTTOM;
479 void() button_return =
481 self.state = STATE_DOWN;
482 SUB_CalcMove (self.pos1, self.speed, button_done);
483 self.frame = 0; // use normal textures
485 self.takedamage = DAMAGE_YES; // can be shot again
489 void() button_blocked =
491 // do nothing, just don't come all the way back out
497 self.health = self.max_health;
498 self.takedamage = DAMAGE_NO; // will be reset upon return
500 if (self.state == STATE_UP || self.state == STATE_TOP)
503 if (self.noise != "")
504 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
506 self.state = STATE_UP;
507 SUB_CalcMove (self.pos2, self.speed, button_wait);
513 // if (activator.classname != "player")
515 // dprint(activator.classname);
516 // dprint(" triggered a button\n");
518 self.enemy = activator;
522 void() button_touch =
524 // if (activator.classname != "player")
526 // dprint(activator.classname);
527 // dprint(" touched a button\n");
531 if (other.classname != "player")
535 self.enemy = other.owner;
539 void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) button_damage =
541 self.health = self.health - damage;
542 if (self.health <= 0)
544 // if (activator.classname != "player")
546 // dprint(activator.classname);
547 // dprint(" killed a button\n");
549 self.enemy = damage_attacker;
555 /*QUAKED func_button (0 .5 .8) ?
556 When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
558 "angle" determines the opening direction
559 "target" all entities with a matching targetname will be used
560 "speed" override the default 40 speed
561 "wait" override the default 1 second wait (-1 = never return)
562 "lip" override the default 4 pixel lip remaining at end of move
563 "health" if set, the button must be killed instead of touched
574 self.movetype = MOVETYPE_PUSH;
575 self.solid = SOLID_BSP;
576 setmodel (self, self.model);
578 self.blocked = button_blocked;
579 self.use = button_use;
581 // if (self.health == 0) // all buttons are now shootable
585 self.max_health = self.health;
586 self.event_damage = button_damage;
587 self.takedamage = DAMAGE_YES;
590 self.touch = button_touch;
599 self.state = STATE_BOTTOM;
601 self.pos1 = self.origin;
602 self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
606 float DOOR_START_OPEN = 1;
607 float DOOR_DONT_LINK = 4;
608 float DOOR_TOGGLE = 32;
612 Doors are similar to buttons, but can spawn a fat trigger field around them
613 to open without a touch, and they link together to form simultanious
616 Door.owner is the master door. If there is only one door, it points to itself.
617 If multiple doors, all will point to a single one.
619 Door.enemy chains from the master door through all doors linked in the chain.
624 =============================================================================
628 =============================================================================
634 void() door_blocked =
636 //T_Damage (other, self, self, self.dmg, self.dmg, self.deathtype, DT_IMPACT, (self.absmin + self.absmax) * 0.5, '0 0 0', Obituary_Generic);
638 // if a door has a negative wait, it would never come back if blocked,
639 // so let it just squash the object to death real fast
642 if (self.state == STATE_DOWN)
650 void() door_hit_top =
652 if (self.noise1 != "")
653 sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
654 self.state = STATE_TOP;
655 if (self.spawnflags & DOOR_TOGGLE)
656 return; // don't come down automatically
657 self.think = door_go_down;
658 self.nextthink = self.ltime + self.wait;
661 void() door_hit_bottom =
663 if (self.noise1 != "")
664 sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
665 self.state = STATE_BOTTOM;
668 void() door_go_down =
670 if (self.noise2 != "")
671 sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
674 self.takedamage = DAMAGE_YES;
675 self.health = self.max_health;
678 self.state = STATE_DOWN;
679 SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
684 if (self.state == STATE_UP)
685 return; // allready going up
687 if (self.state == STATE_TOP)
688 { // reset top wait time
689 self.nextthink = self.ltime + self.wait;
693 if (self.noise2 != "")
694 sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
695 self.state = STATE_UP;
696 SUB_CalcMove (self.pos2, self.speed, door_hit_top);
703 =============================================================================
707 =============================================================================
715 if (self.owner != self)
716 objerror ("door_fire: self.owner != self");
718 self.message = ""; // no more message
721 if (self.spawnflags & DOOR_TOGGLE)
723 if (self.state == STATE_UP || self.state == STATE_TOP)
730 } while ( (self != starte) && (self != world) );
736 // trigger all paired doors
742 } while ( (self != starte) && (self != world) );
751 //dprint("door_use (model: ");dprint(self.model);dprint(")\n");
752 self.message = ""; // door message are for touch only
754 self.owner.message = "";
756 self.enemy.message = "";
767 void() door_trigger_touch =
769 if (other.health < 1)
772 if (time < self.attack_finished)
774 self.attack_finished = time + 1;
783 void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) door_damage =
786 self.health = self.health - damage;
787 if (self.health <= 0)
791 self.health = self.max_health;
792 self.takedamage = DAMAGE_NO; // wil be reset upon return
808 if (other.classname != "player")
810 if (self.owner.attack_finished > time)
813 self.owner.attack_finished = time + 2;
815 if (self.owner.message != "")
817 if (other.flags & FL_CLIENT)
818 centerprint (other, self.owner.message);
819 sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
824 =============================================================================
828 =============================================================================
832 entity(vector fmins, vector fmaxs) spawn_field =
834 local entity trigger;
838 trigger.classname = "doortriggerfield";
839 trigger.movetype = MOVETYPE_NONE;
840 trigger.solid = SOLID_TRIGGER;
841 trigger.owner = self;
842 trigger.touch = door_trigger_touch;
846 setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
851 float (entity e1, entity e2) EntitiesTouching =
853 if (e1.mins_x > e2.maxs_x)
855 if (e1.mins_y > e2.maxs_y)
857 if (e1.mins_z > e2.maxs_z)
859 if (e1.maxs_x < e2.mins_x)
861 if (e1.maxs_y < e2.mins_y)
863 if (e1.maxs_z < e2.mins_z)
878 local entity t, starte;
879 local vector cmins, cmaxs;
882 return; // already linked by another door
883 if (self.spawnflags & 4)
885 self.owner = self.enemy = self;
886 return; // don't want to link this door
897 self.owner = starte; // master door
900 starte.health = self.health;
902 starte.targetname = self.targetname;
903 if (self.message != "")
904 starte.message = self.message;
906 t = find(t, classname, self.classname);
909 self.enemy = starte; // make the chain a loop
911 // shootable, or triggered doors just needed the owner/enemy links,
912 // they don't spawn a field
923 self.owner.trigger_field = spawn_field(cmins, cmaxs);
928 if (EntitiesTouching(self,t))
931 objerror ("cross connected doors");
936 if (t.mins_x < cmins_x)
938 if (t.mins_y < cmins_y)
940 if (t.mins_z < cmins_z)
942 if (t.maxs_x > cmaxs_x)
944 if (t.maxs_y > cmaxs_y)
946 if (t.maxs_z > cmaxs_z)
954 /*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK x x TOGGLE
955 if two doors touch, they are assumed to be connected and operate as a unit.
957 TOGGLE causes the door to wait in both the start and end states for a trigger event.
959 START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
961 "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
962 "angle" determines the opening direction
963 "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
964 "health" if set, door must be shot open
965 "speed" movement speed (100 default)
966 "wait" wait before returning (3 default, -1 = never return)
967 "lip" lip remaining at end of move (8 default)
968 "dmg" damage to inflict when blocked (2 default)
979 //if (!self.deathtype) // map makers can override this
980 // self.deathtype = " got in the way";
983 self.max_health = self.health;
984 self.solid = SOLID_BSP;
985 self.movetype = MOVETYPE_PUSH;
986 setorigin (self, self.origin);
987 setmodel (self, self.model);
988 self.classname = "door";
990 self.blocked = door_blocked;
1002 self.pos1 = self.origin;
1003 self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
1005 // DOOR_START_OPEN is to allow an entity to be lighted in the closed position
1006 // but spawn in the open position
1007 if (self.spawnflags & DOOR_START_OPEN)
1009 setorigin (self, self.pos2);
1010 self.pos2 = self.pos1;
1011 self.pos1 = self.origin;
1014 self.state = STATE_BOTTOM;
1018 self.takedamage = DAMAGE_YES;
1019 self.event_damage = door_damage;
1025 self.touch = door_touch;
1027 // LinkDoors can't be done until all of the doors have been spawned, so
1028 // the sizes can be detected properly.
1029 self.think = LinkDoors;
1030 self.nextthink = self.ltime + 0.1;
1034 =============================================================================
1038 =============================================================================
1041 void() fd_secret_move1;
1042 void() fd_secret_move2;
1043 void() fd_secret_move3;
1044 void() fd_secret_move4;
1045 void() fd_secret_move5;
1046 void() fd_secret_move6;
1047 void() fd_secret_done;
1049 float SECRET_OPEN_ONCE = 1; // stays open
1050 float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
1051 float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
1052 float SECRET_NO_SHOOT = 8; // only opened by trigger
1053 float SECRET_YES_SHOOT = 16; // shootable even if targeted
1056 void () fd_secret_use =
1060 self.health = 10000;
1061 //self.havocattack = TRUE;
1063 // exit if still moving around...
1064 if (self.origin != self.oldorigin)
1067 self.message = ""; // no more message
1069 SUB_UseTargets(); // fire all targets / killtargets
1071 self.velocity = '0 0 0';
1073 // Make a sound, wait a little...
1075 if (self.noise1 != "")
1076 sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
1077 self.nextthink = self.ltime + 0.1;
1079 temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
1080 makevectors(self.mangle);
1084 if (self.spawnflags & SECRET_1ST_DOWN)
1085 self.t_width = fabs(v_up * self.size);
1087 self.t_width = fabs(v_right * self.size);
1091 self.t_length = fabs(v_forward * self.size);
1093 if (self.spawnflags & SECRET_1ST_DOWN)
1094 self.dest1 = self.origin - v_up * self.t_width;
1096 self.dest1 = self.origin + v_right * (self.t_width * temp);
1098 self.dest2 = self.dest1 + v_forward * self.t_length;
1099 SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
1100 if (self.noise2 != "")
1101 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
1104 // Wait after first movement...
1105 void () fd_secret_move1 =
1107 self.nextthink = self.ltime + 1.0;
1108 self.think = fd_secret_move2;
1109 if (self.noise3 != "")
1110 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
1113 // Start moving sideways w/sound...
1114 void () fd_secret_move2 =
1116 if (self.noise2 != "")
1117 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
1118 SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
1121 // Wait here until time to go back...
1122 void () fd_secret_move3 =
1124 if (self.noise3 != "")
1125 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
1126 if (!(self.spawnflags & SECRET_OPEN_ONCE))
1128 self.nextthink = self.ltime + self.wait;
1129 self.think = fd_secret_move4;
1134 void () fd_secret_move4 =
1136 if (self.noise2 != "")
1137 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
1138 SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
1142 void () fd_secret_move5 =
1144 self.nextthink = self.ltime + 1.0;
1145 self.think = fd_secret_move6;
1146 if (self.noise3 != "")
1147 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
1150 void () fd_secret_move6 =
1152 if (self.noise2 != "")
1153 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
1154 SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
1157 void () fd_secret_done =
1159 if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
1161 self.health = 10000;
1162 self.takedamage = DAMAGE_YES;
1163 //self.th_pain = fd_secret_use;
1165 if (self.noise3 != "")
1166 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
1169 void () secret_blocked =
1171 if (time < self.attack_finished)
1173 self.attack_finished = time + 0.5;
1174 //T_Damage (other, self, self, self.dmg, self.dmg, self.deathtype, DT_IMPACT, (self.absmin + self.absmax) * 0.5, '0 0 0', Obituary_Generic);
1184 void() secret_touch =
1186 if (activator.classname != "player")
1188 if (self.attack_finished > time)
1191 self.attack_finished = time + 2;
1195 if (other.flags & FL_CLIENT)
1196 centerprint (other, self.message);
1197 sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
1202 /*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
1203 Basic secret door. Slides back, then to the side. Angle determines direction.
1204 wait = # of seconds before coming back
1205 1st_left = 1st move is left of arrow
1206 1st_down = 1st move is down from arrow
1207 always_shoot = even if targeted, keep shootable
1208 t_width = override WIDTH to move back (or height if going down)
1209 t_length = override LENGTH to move sideways
1210 "dmg" damage to inflict when blocked (2 default)
1212 If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
1219 void () func_door_secret =
1221 /*if (!self.deathtype) // map makers can override this
1222 self.deathtype = " got in the way";*/
1228 self.mangle = self.angles;
1229 self.angles = '0 0 0';
1230 self.solid = SOLID_BSP;
1231 self.movetype = MOVETYPE_PUSH;
1232 self.classname = "door";
1233 setmodel (self, self.model);
1234 setorigin (self, self.origin);
1236 self.touch = secret_touch;
1237 self.blocked = secret_blocked;
1239 self.use = fd_secret_use;
1240 if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
1242 self.health = 10000;
1243 self.takedamage = DAMAGE_YES;
1244 self.event_damage = fd_secret_use;
1246 self.oldorigin = self.origin;
1248 self.wait = 5; // 5 seconds before closing