Xonotic
door.qc
Go to the documentation of this file.
1 #include "door.qh"
2 #include "door_rotating.qh"
3 /*
4 
5 Doors are similar to buttons, but can spawn a fat trigger field around them
6 to open without a touch, and they link together to form simultanious
7 double/quad doors.
8 
9 Door.owner is the master door. If there is only one door, it points to itself.
10 If multiple doors, all will point to a single one.
11 
12 Door.enemy chains from the master door through all doors linked in the chain.
13 
14 */
15 
16 
17 /*
18 =============================================================================
19 
20 THINK FUNCTIONS
21 
22 =============================================================================
23 */
24 
25 void door_go_down(entity this);
26 void door_go_up(entity this, entity actor, entity trigger);
27 
28 void door_blocked(entity this, entity blocker)
29 {
30  if((this.spawnflags & DOOR_CRUSH)
31 #ifdef SVQC
32  && (blocker.takedamage != DAMAGE_NO)
33 #elif defined(CSQC)
34  && !IS_DEAD(blocker)
35 #endif
36  )
37  { // KIll Kill Kill!!
38 #ifdef SVQC
39  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
40 #endif
41  }
42  else
43  {
44 #ifdef SVQC
45  if((this.dmg) && (blocker.takedamage == DAMAGE_YES)) // Shall we bite?
46  Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
47 #endif
48 
49  // don't change direction for dead or dying stuff
50  if(IS_DEAD(blocker)
51 #ifdef SVQC
52  && (blocker.takedamage == DAMAGE_NO)
53 #endif
54  )
55  {
56  if (this.wait >= 0)
57  {
58  if (this.state == STATE_DOWN)
59  {
60  if (this.classname == "door")
61  door_go_up(this, NULL, NULL);
62  else
63  door_rotating_go_up(this, blocker);
64  }
65  else
66  {
67  if (this.classname == "door")
68  door_go_down(this);
69  else
70  door_rotating_go_down(this);
71  }
72  }
73  }
74 #ifdef SVQC
75  else
76  {
77  //gib dying stuff just to make sure
78  if((this.dmg) && (blocker.takedamage != DAMAGE_NO)) // Shall we bite?
79  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
80  }
81 #endif
82  }
83 }
84 
85 void door_hit_top(entity this)
86 {
87  if (this.noise1 != "")
89  this.state = STATE_TOP;
90  if (this.spawnflags & DOOR_TOGGLE)
91  return; // don't come down automatically
92  if (this.classname == "door")
93  {
94  setthink(this, door_go_down);
95  } else
96  {
97  setthink(this, door_rotating_go_down);
98  }
99  this.nextthink = this.ltime + this.wait;
100 }
101 
103 {
104  if (this.noise1 != "")
106  this.state = STATE_BOTTOM;
107 }
108 
110 {
111  if (this.noise2 != "")
113  if (this.max_health)
114  {
115  this.takedamage = DAMAGE_YES;
117  }
118 
119  this.state = STATE_DOWN;
120  SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, door_hit_bottom);
121 }
122 
123 void door_go_up(entity this, entity actor, entity trigger)
124 {
125  if (this.state == STATE_UP)
126  return; // already going up
127 
128  if (this.state == STATE_TOP)
129  { // reset top wait time
130  this.nextthink = this.ltime + this.wait;
131  return;
132  }
133 
134  if (this.noise2 != "")
136  this.state = STATE_UP;
137  SUB_CalcMove (this, this.pos2, TSPEED_LINEAR, this.speed, door_hit_top);
138 
139  string oldmessage;
140  oldmessage = this.message;
141  this.message = "";
142  SUB_UseTargets(this, actor, trigger);
143  this.message = oldmessage;
144 }
145 
146 
147 /*
148 =============================================================================
149 
150 ACTIVATION FUNCTIONS
151 
152 =============================================================================
153 */
154 
155 bool door_check_keys(entity door, entity player)
156 {
157  if(door.owner)
158  door = door.owner;
159 
160  // no key needed
161  if(!door.itemkeys)
162  return true;
163 
164  // this door require a key
165  // only a player can have a key
166  if(!IS_PLAYER(player))
167  return false;
168 
169  entity store = player;
170 #ifdef SVQC
171  store = PS(player);
172 #endif
173  int valid = (door.itemkeys & store.itemkeys);
174  door.itemkeys &= ~valid; // only some of the needed keys were given
175 
176  if(!door.itemkeys)
177  {
178 #ifdef SVQC
179  play2(player, door.noise);
180  Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_UNLOCKED);
181 #endif
182  return true;
183  }
184 
185  if(!valid)
186  {
187 #ifdef SVQC
188  if(player.key_door_messagetime <= time)
189  {
190  play2(player, door.noise3);
191  Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(door.itemkeys));
192  player.key_door_messagetime = time + 2;
193  }
194 #endif
195  return false;
196  }
197 
198  // door needs keys the player doesn't have
199 #ifdef SVQC
200  if(player.key_door_messagetime <= time)
201  {
202  play2(player, door.noise3);
203  Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(door.itemkeys));
204  player.key_door_messagetime = time + 2;
205  }
206 #endif
207 
208  return false;
209 }
210 
211 void door_fire(entity this, entity actor, entity trigger)
212 {
213  if (this.owner != this)
214  objerror (this, "door_fire: this.owner != this");
215 
216  if (this.spawnflags & DOOR_TOGGLE)
217  {
218  if (this.state == STATE_UP || this.state == STATE_TOP)
219  {
220  entity e = this;
221  do {
222  if (e.classname == "door") {
223  door_go_down(e);
224  } else {
225  door_rotating_go_down(e);
226  }
227  e = e.enemy;
228  } while ((e != this) && (e != NULL));
229  return;
230  }
231  }
232 
233 // trigger all paired doors
234  entity e = this;
235  do {
236  if (e.classname == "door") {
237  door_go_up(e, actor, trigger);
238  } else {
239  // if the BIDIR spawnflag (==2) is set and the trigger has set trigger_reverse, reverse the opening direction
240  if ((e.spawnflags & DOOR_ROTATING_BIDIR) && trigger.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
241  e.lip = 666; // e.lip is used to remember reverse opening direction for door_rotating
242  e.pos2 = '0 0 0' - e.pos2;
243  }
244  // if BIDIR_IN_DOWN (==8) is set, prevent the door from reoping during closing if it is triggered from the wrong side
245  if (!((e.spawnflags & DOOR_ROTATING_BIDIR) && (e.spawnflags & DOOR_ROTATING_BIDIR_IN_DOWN) && e.state == STATE_DOWN
246  && (((e.lip == 666) && (trigger.trigger_reverse == 0)) || ((e.lip != 666) && (trigger.trigger_reverse != 0)))))
247  {
248  door_rotating_go_up(e, trigger);
249  }
250  }
251  e = e.enemy;
252  } while ((e != this) && (e != NULL));
253 }
254 
255 void door_use(entity this, entity actor, entity trigger)
256 {
257  //dprint("door_use (model: ");dprint(this.model);dprint(")\n");
258 
259  if (this.owner)
260  door_fire(this.owner, actor, trigger);
261 }
262 
263 void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
264 {
265  if(this.spawnflags & NOSPLASH)
266  if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
267  return;
268  TakeResource(this, RES_HEALTH, damage);
269 
270  if (this.itemkeys)
271  {
272  // don't allow opening doors through damage if keys are required
273  return;
274  }
275 
276  if (GetResource(this, RES_HEALTH) <= 0)
277  {
278  SetResourceExplicit(this.owner, RES_HEALTH, this.owner.max_health);
279  this.owner.takedamage = DAMAGE_NO; // will be reset upon return
280  door_use(this.owner, attacker, NULL);
281  }
282 }
283 
285 
286 /*
287 ================
288 door_touch
289 
290 Prints messages
291 ================
292 */
293 
294 void door_touch(entity this, entity toucher)
295 {
296  if (!IS_PLAYER(toucher))
297  return;
298  if (this.owner.door_finished > time)
299  return;
300 
301  this.owner.door_finished = time + 2;
302 
303 #ifdef SVQC
304  if (!(this.owner.dmg) && (this.owner.message != ""))
305  {
306  if (IS_CLIENT(toucher))
307  centerprint(toucher, this.owner.message);
308  play2(toucher, this.owner.noise);
309  }
310 #endif
311 }
312 
314 {
315  if((this.spawnflags & DOOR_CRUSH) && (blocker.takedamage != DAMAGE_NO)) { // Kill Kill Kill!!
316 #ifdef SVQC
317  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
318 #endif
319  }
320  else
321  {
322 
323 #ifdef SVQC
324  if((this.dmg) && (blocker.takedamage == DAMAGE_YES)) // Shall we bite?
325  Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
326 #endif
327 
328  //Dont chamge direction for dead or dying stuff
329  if(IS_DEAD(blocker) && (blocker.takedamage == DAMAGE_NO))
330  {
331  if (this.wait >= 0)
332  {
333  if (this.state == STATE_DOWN)
334  door_rotating_go_up (this, blocker);
335  else
336  door_rotating_go_down (this);
337  }
338  }
339 #ifdef SVQC
340  else
341  {
342  //gib dying stuff just to make sure
343  if((this.dmg) && (blocker.takedamage != DAMAGE_NO)) // Shall we bite?
344  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
345  }
346 #endif
347  }
348 }
349 
350 /*
351 =========================================
352 door trigger
353 
354 Spawned if a door lacks a real activator
355 =========================================
356 */
357 
358 void door_trigger_touch(entity this, entity toucher)
359 {
360  if (GetResource(toucher, RES_HEALTH) < 1)
361 #ifdef SVQC
362  if (!((toucher.iscreature || (toucher.flags & FL_PROJECTILE)) && !IS_DEAD(toucher)))
363 #elif defined(CSQC)
364  if(!((IS_CLIENT(toucher) || toucher.classname == "ENT_CLIENT_PROJECTILE") && !IS_DEAD(toucher)))
365 #endif
366  return;
367 
368  if (time < this.door_finished)
369  return;
370 
371  // check if door is locked
372  if (!door_check_keys(this, toucher))
373  return;
374 
375  this.door_finished = time + 1;
376 
377  door_use(this.owner, toucher, NULL);
378 }
379 
380 void door_spawnfield(entity this, vector fmins, vector fmaxs)
381 {
382  entity trigger;
383  vector t1 = fmins, t2 = fmaxs;
384 
385  trigger = new(doortriggerfield);
386  set_movetype(trigger, MOVETYPE_NONE);
387  trigger.solid = SOLID_TRIGGER;
388  trigger.owner = this;
389 #ifdef SVQC
390  settouch(trigger, door_trigger_touch);
391 #endif
392 
393  setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
394 }
395 
396 
397 /*
398 =============
399 LinkDoors
400 
401 
402 =============
403 */
404 
406 {
407  while((cur = find(cur, classname, pass.classname)) && ((cur.spawnflags & DOOR_DONT_LINK) || cur.enemy))
408  {
409  }
410  return cur;
411 }
412 
414 {
415  float DELTA = 4;
416  if((e1.absmin_x > e2.absmax_x + DELTA)
417  || (e1.absmin_y > e2.absmax_y + DELTA)
418  || (e1.absmin_z > e2.absmax_z + DELTA)
419  || (e2.absmin_x > e1.absmax_x + DELTA)
420  || (e2.absmin_y > e1.absmax_y + DELTA)
421  || (e2.absmin_z > e1.absmax_z + DELTA)
422  ) { return false; }
423  return true;
424 }
425 
426 #ifdef SVQC
427 void door_link();
428 #endif
429 void LinkDoors(entity this)
430 {
431  entity t;
432  vector cmins, cmaxs;
433 
434 #ifdef SVQC
435  door_link();
436 #endif
437 
438  if (this.enemy)
439  return; // already linked by another door
440  if (this.spawnflags & DOOR_DONT_LINK)
441  {
442  this.owner = this.enemy = this;
443 
444  if (GetResource(this, RES_HEALTH))
445  return;
446  if(this.targetname && this.targetname != "")
447  return;
448  if (this.items)
449  return;
450 
451  door_spawnfield(this, this.absmin, this.absmax);
452 
453  return; // don't want to link this door
454  }
455 
457 
458  // set owner, and make a loop of the chain
459  LOG_TRACE("LinkDoors: linking doors:");
460  for(t = this; ; t = t.enemy)
461  {
462  LOG_TRACE(" ", etos(t));
463  t.owner = this;
464  if(t.enemy == NULL)
465  {
466  t.enemy = this;
467  break;
468  }
469  }
470  LOG_TRACE("");
471 
472  // collect health, targetname, message, size
473  cmins = this.absmin;
474  cmaxs = this.absmax;
475  for(t = this; ; t = t.enemy)
476  {
477  if(GetResource(t, RES_HEALTH) && !GetResource(this, RES_HEALTH))
479  if((t.targetname != "") && (this.targetname == ""))
480  this.targetname = t.targetname;
481  if((t.message != "") && (this.message == ""))
482  this.message = t.message;
483  if (t.absmin_x < cmins_x)
484  cmins_x = t.absmin_x;
485  if (t.absmin_y < cmins_y)
486  cmins_y = t.absmin_y;
487  if (t.absmin_z < cmins_z)
488  cmins_z = t.absmin_z;
489  if (t.absmax_x > cmaxs_x)
490  cmaxs_x = t.absmax_x;
491  if (t.absmax_y > cmaxs_y)
492  cmaxs_y = t.absmax_y;
493  if (t.absmax_z > cmaxs_z)
494  cmaxs_z = t.absmax_z;
495  if(t.enemy == this)
496  break;
497  }
498 
499  // distribute health, targetname, message
500  for(t = this; t; t = t.enemy)
501  {
503  t.targetname = this.targetname;
504  t.message = this.message;
505  if(t.enemy == this)
506  break;
507  }
508 
509  // shootable, or triggered doors just needed the owner/enemy links,
510  // they don't spawn a field
511 
512  if (GetResource(this, RES_HEALTH))
513  return;
514  if(this.targetname && this.targetname != "")
515  return;
516  if (this.items)
517  return;
518 
519  door_spawnfield(this, cmins, cmaxs);
520 }
521 
522 REGISTER_NET_LINKED(ENT_CLIENT_DOOR)
523 
524 #ifdef SVQC
525 /*QUAKED spawnfunc_func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
526 if two doors touch, they are assumed to be connected and operate as a unit.
527 
528 TOGGLE causes the door to wait in both the start and end states for a trigger event.
529 
530 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 useful for touch or takedamage doors).
531 
532 GOLD_KEY causes the door to open only if the activator holds a gold key.
533 
534 SILVER_KEY causes the door to open only if the activator holds a silver key.
535 
536 "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
537 "angle" determines the opening direction
538 "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
539 "health" if set, door must be shot open
540 "speed" movement speed (100 default)
541 "wait" wait before returning (3 default, -1 = never return)
542 "lip" lip remaining at end of move (8 default)
543 "dmg" damage to inflict when blocked (2 default)
544 "sounds"
545 0) no sound
546 1) stone
547 2) base
548 3) stone chain
549 4) screechy metal
550 FIXME: only one sound set available at the time being
551 
552 */
553 
554 float door_send(entity this, entity to, float sf)
555 {
556  WriteHeader(MSG_ENTITY, ENT_CLIENT_DOOR);
557  WriteByte(MSG_ENTITY, sf);
558 
559  if(sf & SF_TRIGGER_INIT)
560  {
561  WriteString(MSG_ENTITY, this.classname);
562  WriteByte(MSG_ENTITY, this.spawnflags);
563 
564  WriteString(MSG_ENTITY, this.model);
565 
566  trigger_common_write(this, true);
567 
568  WriteVector(MSG_ENTITY, this.pos1);
569  WriteVector(MSG_ENTITY, this.pos2);
570 
571  WriteVector(MSG_ENTITY, this.size);
572 
573  WriteShort(MSG_ENTITY, this.wait);
574  WriteShort(MSG_ENTITY, this.speed);
575  WriteByte(MSG_ENTITY, this.lip);
576  WriteByte(MSG_ENTITY, this.state);
577  WriteCoord(MSG_ENTITY, this.ltime);
578  }
579 
580  if(sf & SF_TRIGGER_RESET)
581  {
582  // client makes use of this, we do not
583  }
584 
585  if(sf & SF_TRIGGER_UPDATE)
586  {
587  WriteVector(MSG_ENTITY, this.origin);
588 
589  WriteVector(MSG_ENTITY, this.pos1);
590  WriteVector(MSG_ENTITY, this.pos2);
591  }
592 
593  return true;
594 }
595 
596 void door_link()
597 {
598  //Net_LinkEntity(this, false, 0, door_send);
599 }
600 #endif
601 
603 {
604  setorigin(this, this.pos2);
605  this.pos2 = this.pos1;
606  this.pos1 = this.origin;
607 
608 #ifdef SVQC
609  this.SendFlags |= SF_TRIGGER_UPDATE;
610 #endif
611 }
612 
613 void door_reset(entity this)
614 {
615  setorigin(this, this.pos1);
616  this.velocity = '0 0 0';
617  this.state = STATE_BOTTOM;
618  setthink(this, func_null);
619  this.nextthink = 0;
620 
621 #ifdef SVQC
622  this.SendFlags |= SF_TRIGGER_RESET;
623 #endif
624 }
625 
626 #ifdef SVQC
627 
628 // common code for func_door and func_door_rotating spawnfuncs
629 void door_init_shared(entity this)
630 {
631  this.max_health = GetResource(this, RES_HEALTH);
632 
633  // unlock sound
634  if(this.noise == "")
635  {
636  this.noise = "misc/talk.wav";
637  }
638  // door still locked sound
639  if(this.noise3 == "")
640  {
641  this.noise3 = "misc/talk.wav";
642  }
643  precache_sound(this.noise);
644  precache_sound(this.noise3);
645 
646  if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message == ""))
647  {
648  this.message = "was squished";
649  }
650  if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message2 == ""))
651  {
652  this.message2 = "was squished by";
653  }
654 
655  // TODO: other soundpacks
656  if (this.sounds > 0 || q3compat)
657  {
658  // Doors in Q3 always have sounds (they're hard coded in Q3 engine)
659  this.noise2 = "plats/medplat1.wav";
660  this.noise1 = "plats/medplat2.wav";
661  }
662 
663  if (q3compat)
664  {
665  // CPMA adds these fields for overriding the engine sounds
666  string s = GetField_fullspawndata(this, "sound_start", true);
667  string e = GetField_fullspawndata(this, "sound_end", true);
668 
669  if (s)
670  this.noise2 = strzone(s);
671  if (e)
672  this.noise1 = strzone(e);
673  }
674 
675  // sound when door stops moving
676  if(this.noise1 && this.noise1 != "")
677  {
678  precache_sound(this.noise1);
679  }
680  // sound when door is moving
681  if(this.noise2 && this.noise2 != "")
682  {
683  precache_sound(this.noise2);
684  }
685 
686  if(autocvar_sv_doors_always_open)
687  {
688  this.wait = -1;
689  }
690  else if (!this.wait)
691  {
692  this.wait = 3;
693  }
694 
695  if (!this.lip)
696  {
697  this.lip = 8;
698  }
699 
700  this.state = STATE_BOTTOM;
701 
702  if (GetResource(this, RES_HEALTH))
703  {
704  //this.canteamdamage = true; // TODO
705  this.takedamage = DAMAGE_YES;
706  this.event_damage = door_damage;
707  }
708 
709  if (this.items)
710  {
711  this.wait = -1;
712  }
713 }
714 
715 // spawnflags require key (for now only func_door)
716 spawnfunc(func_door)
717 {
718  // Quake 1 keys compatibility
719  if (this.spawnflags & SPAWNFLAGS_GOLD_KEY)
720  this.itemkeys |= ITEM_KEY_BIT(0);
722  this.itemkeys |= ITEM_KEY_BIT(1);
723 
724  SetMovedir(this);
725 
726  if (!InitMovingBrushTrigger(this))
727  return;
728  this.effects |= EF_LOWPRECISION;
729  this.classname = "door";
730 
731  setblocked(this, door_blocked);
732  this.use = door_use;
733 
734  if(this.spawnflags & DOOR_NONSOLID)
735  this.solid = SOLID_NOT;
736 
737 // DOOR_START_OPEN is to allow an entity to be lighted in the closed position
738 // but spawn in the open position
739  if (this.spawnflags & DOOR_START_OPEN)
740  InitializeEntity(this, door_init_startopen, INITPRIO_SETLOCATION);
741 
742  door_init_shared(this);
743 
744  this.pos1 = this.origin;
745  this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
746 
747  if(autocvar_sv_doors_always_open)
748  {
749  this.speed = max(750, this.speed);
750  }
751  else if (!this.speed)
752  {
753  if (q3compat)
754  this.speed = 400;
755  else
756  this.speed = 100;
757  }
758 
759  settouch(this, door_touch);
760 
761 // LinkDoors can't be done until all of the doors have been spawned, so
762 // the sizes can be detected properly.
763  InitializeEntity(this, LinkDoors, INITPRIO_LINKDOORS);
764 
765  this.reset = door_reset;
766 }
767 
768 #elif defined(CSQC)
769 
770 NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
771 {
772  int sf = ReadByte();
773 
774  if(sf & SF_TRIGGER_INIT)
775  {
776  this.classname = strzone(ReadString());
777  this.spawnflags = ReadByte();
778 
779  this.mdl = strzone(ReadString());
780  _setmodel(this, this.mdl);
781 
782  trigger_common_read(this, true);
783 
784  this.pos1 = ReadVector();
785  this.pos2 = ReadVector();
786 
787  this.size = ReadVector();
788 
789  this.wait = ReadShort();
790  this.speed = ReadShort();
791  this.lip = ReadByte();
792  this.state = ReadByte();
793  this.ltime = ReadCoord();
794 
795  this.solid = SOLID_BSP;
797  this.use = door_use;
798 
799  LinkDoors(this);
800 
801  if(this.spawnflags & DOOR_START_OPEN)
802  door_init_startopen(this);
803 
804  this.move_time = time;
806  }
807 
808  if(sf & SF_TRIGGER_RESET)
809  {
810  door_reset(this);
811  }
812 
813  if(sf & SF_TRIGGER_UPDATE)
814  {
815  this.origin = ReadVector();
816  setorigin(this, this.origin);
817 
818  this.pos1 = ReadVector();
819  this.pos2 = ReadVector();
820  }
821  return true;
822 }
823 
824 #endif
const int HITTYPE_SPLASH
automatically set by RadiusDamage
Definition: all.qh:27
const float SOLID_NOT
Definition: csprogsdefs.qc:244
float state
Definition: subs.qh:32
float MOVETYPE_NONE
Definition: progsdefs.qc:246
void door_trigger_touch(entity this, entity toucher)
Definition: door.qc:358
void door_generic_plat_blocked(entity this, entity blocker)
Definition: door.qc:313
const int NOSPLASH
Definition: defs.qh:12
#define REGISTER_NET_LINKED(id)
Definition: net.qh:67
float speed
Definition: subs.qh:41
float door_finished
Definition: door.qc:284
#define ITEM_KEY_BIT(n)
Returns the bit ID of a key.
Definition: keys.qh:6
string GetField_fullspawndata(entity e, string f,...)
Definition: main.qc:400
const int SF_TRIGGER_INIT
Definition: defs.qh:22
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Definition: cl_resources.qc:15
string noise
Definition: progsdefs.qc:209
#define ReadString
const int DOOR_START_OPEN
Definition: door.qh:7
void door_use(entity this, entity actor, entity trigger)
Definition: door.qc:255
#define IS_CLIENT(v)
Definition: utils.qh:13
entity() spawn
#define STATE_TOP
Definition: sys-pre.qh:30
const int SPAWNFLAGS_GOLD_KEY
Definition: door.qh:9
const int TSPEED_LINEAR
Definition: subs.qh:71
const int DOOR_ROTATING_BIDIR_IN_DOWN
Definition: door_rotating.qh:5
void FindConnectedComponent(entity e,.entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
Definition: util.qc:1630
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition: triggers.qc:366
#define PS(this)
Definition: state.qh:18
#define NET_HANDLE(id, param)
Definition: net.qh:12
string noise2
Definition: progsdefs.qc:209
float dmg
Definition: platforms.qh:6
void door_fire(entity this, entity actor, entity trigger)
Definition: door.qc:211
entity to
Definition: self.qh:96
spawnfunc(info_player_attacker)
Definition: sv_assault.qc:283
origin
Definition: ent_cs.qc:114
void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition: door.qc:263
string classname
Definition: csprogsdefs.qc:107
vector size
Definition: csprogsdefs.qc:114
float ltime
Definition: progsdefs.qc:107
float effects
Definition: csprogsdefs.qc:111
#define STATE_DOWN
Definition: sys-pre.qh:33
void SUB_CalcMove(entity this, vector tdest, float tspeedtype, float tspeed, void(entity this) func)
Definition: subs.qc:256
float spawnflags
Definition: progsdefs.qc:191
#define DMG_NOWEP
Definition: damage.qh:126
entity owner
Definition: main.qh:73
string model
Definition: csprogsdefs.qc:108
void door_spawnfield(entity this, vector fmins, vector fmaxs)
Definition: door.qc:380
void door_go_up(entity this, entity actor, entity trigger)
Definition: door.qc:123
string noise3
Definition: progsdefs.qc:209
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
Definition: cl_resources.qc:31
const int DOOR_CRUSH
Definition: door.qh:14
void door_blocked(entity this, entity blocker)
Definition: door.qc:28
vector absmax
Definition: csprogsdefs.qc:92
RES_HEALTH
Definition: ent_cs.qc:126
const int DOOR_DONT_LINK
Definition: door.qh:8
int q3compat
Definition: quake3.qh:3
vector movedir
Definition: progsdefs.qc:203
entity enemy
Definition: sv_ctf.qh:143
bool door_check_keys(entity door, entity player)
Definition: door.qc:155
float MOVETYPE_PUSH
Definition: progsdefs.qc:253
float wait
Definition: subs.qh:39
const int SF_TRIGGER_RESET
Definition: defs.qh:24
string noise1
Definition: progsdefs.qc:209
string message
Definition: powerups.qc:19
#define NULL
Definition: post.qh:17
float max_health
const float VOL_BASE
Definition: sound.qh:36
const int SPAWNFLAGS_SILVER_KEY
Definition: door.qh:10
void door_init_startopen(entity this)
Definition: door.qc:602
float takedamage
Definition: progsdefs.qc:147
void door_go_down(entity this)
Definition: door.qc:109
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition: damage.qc:583
#define IS_DEAD(s)
Definition: utils.qh:26
const float ATTEN_NORM
Definition: sound.qh:30
float nextthink
Definition: csprogsdefs.qc:121
const int CH_TRIGGER_SINGLE
Definition: sound.qh:13
void door_touch(entity this, entity toucher)
Definition: door.qc:294
float itemkeys
Definition: subs.qh:61
#define STATE_UP
Definition: sys-pre.qh:32
vector(float skel, float bonenum) _skel_get_boneabs_hidden
void door_hit_bottom(entity this)
Definition: door.qc:102
bool LinkDoors_isconnected(entity e1, entity e2, entity pass)
Definition: door.qc:413
void LinkDoors(entity this)
Definition: door.qc:429
entity LinkDoors_nextent(entity cur, entity near, entity pass)
Definition: door.qc:405
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
const float SOLID_BSP
Definition: csprogsdefs.qc:248
const int DOOR_ROTATING_BIDIR
Definition: door_rotating.qh:4
void InitializeEntity(entity e, void(entity this) func, int order)
Definition: world.qc:2146
float move_time
Definition: movetypes.qh:77
float lip
Definition: subs.qh:40
#define LOG_TRACE(...)
Definition: log.qh:81
void door_reset(entity this)
Definition: door.qc:613
float items
Definition: progsdefs.qc:145
#define _sound(e, c, s, v, a)
Definition: sound.qh:50
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
string targetname
Definition: progsdefs.qc:194
vector pos1
Definition: subs.qh:50
setorigin(ent, v)
#define setthink(e, f)
float sounds
Definition: subs.qh:42
#define use
Definition: csprogsdefs.qh:50
#define DEATH_ISSPECIAL(t)
Definition: all.qh:35
vector absmin
Definition: csprogsdefs.qc:92
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
vector pos2
Definition: subs.qh:50
#define pass(name, colormin, colormax)
void door_hit_top(entity this)
Definition: door.qc:85
const int DOOR_NONSOLID
Definition: door.qh:13
float DAMAGE_NO
Definition: progsdefs.qc:282
void set_movetype(entity this, int mt)
#define IS_PLAYER(v)
Definition: utils.qh:9
float EF_LOWPRECISION
var void func_null()
float solid
Definition: csprogsdefs.qc:99
float DAMAGE_YES
Definition: progsdefs.qc:283
const int SF_TRIGGER_UPDATE
Definition: defs.qh:23
#define STATE_BOTTOM
Definition: sys-pre.qh:31
const int DOOR_TOGGLE
Definition: door.qh:11