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