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;
145 oldmessage = this.message;
146 this.message = "";
147 SUB_UseTargets(this, actor, trigger);
148 this.message = oldmessage;
149}
150
151
152/*
153=============================================================================
154
155ACTIVATION FUNCTIONS
156
157=============================================================================
158*/
159
160bool door_check_keys(entity door, entity player)
161{
162 if(door.owner)
163 door = door.owner;
164
165 // no key needed
166 if(!door.itemkeys)
167 return true;
168
169 // this door require a key
170 // only a player can have a key
171 if(!IS_PLAYER(player))
172 return false;
173
174 entity store = player;
175#ifdef SVQC
176 store = PS(player);
177#endif
178 int valid = (door.itemkeys & store.itemkeys);
179 door.itemkeys &= ~valid; // only some of the needed keys were given
180
181 if(!door.itemkeys)
182 {
183#ifdef SVQC
184 play2(player, door.noise);
185 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_UNLOCKED);
186#endif
187 return true;
188 }
189
190 if(!valid)
191 {
192#ifdef SVQC
193 if(player.key_door_messagetime <= time)
194 {
195 play2(player, door.noise3);
196 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(door.itemkeys));
197 player.key_door_messagetime = time + 2;
198 }
199#endif
200 return false;
201 }
202
203 // door needs keys the player doesn't have
204#ifdef SVQC
205 if(player.key_door_messagetime <= time)
206 {
207 play2(player, door.noise3);
208 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(door.itemkeys));
209 player.key_door_messagetime = time + 2;
210 }
211#endif
212
213 return false;
214}
215
216void door_use(entity this, entity actor, entity trigger)
217{
218 //dprint("door_use (model: ");dprint(this.model);dprint(")\n");
219
220 if (!this.owner)
221 return;
222 if (this.owner.active != ACTIVE_ACTIVE)
223 return;
224 this = this.owner;
225
226 if (this.spawnflags & DOOR_TOGGLE)
227 {
228 if (this.state == STATE_UP || this.state == STATE_TOP)
229 {
230 entity e = this;
231 do {
232 if (e.classname == "door") {
233 door_go_down(e);
234 } else {
236 }
237 e = e.enemy;
238 } while ((e != this) && (e != NULL));
239 return;
240 }
241 }
242
243// trigger all paired doors
244 entity e = this;
245 do {
246 if (e.classname == "door") {
247 door_go_up(e, actor, trigger);
248 } else {
249 // if the BIDIR spawnflag (==2) is set and the trigger has set trigger_reverse, reverse the opening direction
250 if ((e.spawnflags & DOOR_ROTATING_BIDIR) && trigger.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
251 e.lip = 666; // e.lip is used to remember reverse opening direction for door_rotating
252 e.pos2 = '0 0 0' - e.pos2;
253 }
254 // if BIDIR_IN_DOWN (==8) is set, prevent the door from reoping during closing if it is triggered from the wrong side
255 if (!((e.spawnflags & DOOR_ROTATING_BIDIR) && (e.spawnflags & DOOR_ROTATING_BIDIR_IN_DOWN) && e.state == STATE_DOWN
256 && (((e.lip == 666) && (trigger.trigger_reverse == 0)) || ((e.lip != 666) && (trigger.trigger_reverse != 0)))))
257 {
258 door_rotating_go_up(e, trigger);
259 }
260 }
261 e = e.enemy;
262 } while ((e != this) && (e != NULL));
263}
264
265void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
266{
267 if(this.spawnflags & NOSPLASH)
268 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
269 return;
270 TakeResource(this, RES_HEALTH, damage);
271
272 if (this.itemkeys)
273 {
274 // don't allow opening doors through damage if keys are required
275 return;
276 }
277
278 if (GetResource(this, RES_HEALTH) <= 0)
279 {
280 SetResourceExplicit(this.owner, RES_HEALTH, this.owner.max_health);
281 this.owner.takedamage = DAMAGE_NO; // will be reset upon return
282 door_use(this.owner, attacker, NULL);
283 }
284}
285
287
288/*
289================
290door_touch
291
292Prints messages
293================
294*/
295
297{
298 if (!IS_PLAYER(toucher))
299 return;
300 if (this.owner.door_finished > time)
301 return;
302#ifdef SVQC
303 if (this.owner.active != ACTIVE_ACTIVE)
304 return;
305#endif
306
307 this.owner.door_finished = time + 2;
308
309#ifdef SVQC
310 if (!(this.owner.dmg) && (this.owner.message != ""))
311 {
312 if (IS_CLIENT(toucher))
313 centerprint(toucher, this.owner.message);
314 play2(toucher, this.owner.noise);
315 }
316#endif
317}
318
320{
321 if((this.spawnflags & DOOR_CRUSH) && (blocker.takedamage != DAMAGE_NO)) { // Kill Kill Kill!!
322#ifdef SVQC
323 Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
324#endif
325 }
326 else
327 {
328
329#ifdef SVQC
330 if((this.dmg) && (blocker.takedamage == DAMAGE_YES)) // Shall we bite?
331 Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
332#endif
333
334 //Dont chamge direction for dead or dying stuff
335 if(IS_DEAD(blocker) && (blocker.takedamage == DAMAGE_NO))
336 {
337 if (this.wait >= 0)
338 {
339 if (this.state == STATE_DOWN)
340 door_rotating_go_up (this, blocker);
341 else
343 }
344 }
345#ifdef SVQC
346 else
347 {
348 //gib dying stuff just to make sure
349 if((this.dmg) && (blocker.takedamage != DAMAGE_NO)) // Shall we bite?
350 Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
351 }
352#endif
353 }
354}
355
356/*
357=========================================
358door trigger
359
360Spawned if a door lacks a real activator
361=========================================
362*/
363
365{
366 if (GetResource(toucher, RES_HEALTH) < 1)
367#ifdef SVQC
368 if (!((toucher.iscreature || (toucher.flags & FL_PROJECTILE)) && !IS_DEAD(toucher)))
369#elif defined(CSQC)
370 if(!((IS_CLIENT(toucher) || toucher.classname == "ENT_CLIENT_PROJECTILE") && !IS_DEAD(toucher)))
371#endif
372 return;
373#ifdef SVQC
374 if (this.owner.active != ACTIVE_ACTIVE)
375 return;
376#endif
377
378 if (this.owner.state == STATE_UP)
379 return;
380
381 // check if door is locked
382 if (!door_check_keys(this, toucher))
383 return;
384
385 if (this.owner.state == STATE_TOP)
386 {
387 if (this.owner.nextthink < this.owner.ltime + this.owner.wait)
388 {
389 entity e = this.owner;
390 do {
391 e.nextthink = e.ltime + e.wait;
392 e = e.enemy;
393 } while (e != this.owner);
394 }
395 return;
396 }
397
398 door_use(this.owner, toucher, NULL);
399}
400
401void door_spawnfield(entity this, vector fmins, vector fmaxs)
402{
403 entity trigger;
404 vector t1 = fmins, t2 = fmaxs;
405
406 trigger = new(doortriggerfield);
407 set_movetype(trigger, MOVETYPE_NONE);
408 trigger.solid = SOLID_TRIGGER;
409 trigger.owner = this;
410#ifdef SVQC
412#endif
413
414 setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
415}
416
417
418/*
419=============
420LinkDoors
421
422
423=============
424*/
425
427{
428 while ((cur = find(cur, classname, pass.classname))
429 && ((!Q3COMPAT_COMMON && (cur.spawnflags & DOOR_DONT_LINK)) || cur.enemy))
430 {
431 }
432 return cur;
433}
434
436{
438 return e1.team == e2.team;
439
440 float DELTA = 4;
441 if((e1.absmin_x > e2.absmax_x + DELTA)
442 || (e1.absmin_y > e2.absmax_y + DELTA)
443 || (e1.absmin_z > e2.absmax_z + DELTA)
444 || (e2.absmin_x > e1.absmax_x + DELTA)
445 || (e2.absmin_y > e1.absmax_y + DELTA)
446 || (e2.absmin_z > e1.absmax_z + DELTA)
447 ) { return false; }
448 return true;
449}
450
451#ifdef SVQC
452void door_link();
453#endif
455{
456 entity t;
457 vector cmins, cmaxs;
458
459#ifdef SVQC
460 door_link();
461#endif
462
463 if (this.enemy)
464 return; // already linked by another door
465
466 // Q3 door linking is done for teamed doors only and is not affected by spawnflags or bmodel proximity
467 if ((!Q3COMPAT_COMMON && (this.spawnflags & DOOR_DONT_LINK)) || (Q3COMPAT_COMMON && !this.team))
468 {
469 this.owner = this.enemy = this;
470
471 if (GetResource(this, RES_HEALTH))
472 return;
473 if(this.targetname && this.targetname != "")
474 return;
475 if (this.items)
476 return;
477
478 door_spawnfield(this, this.absmin, this.absmax);
479
480 return; // don't want to link this door
481 }
482
484
485 // set owner, and make a loop of the chain
486 LOG_TRACE("LinkDoors: linking doors:");
487 for(t = this; ; t = t.enemy)
488 {
489 LOG_TRACE(" ", etos(t));
490 t.owner = this;
491 if(t.enemy == NULL)
492 {
493 t.enemy = this;
494 break;
495 }
496 }
497 LOG_TRACE("");
498
499 // collect health, targetname, message, size
500 cmins = this.absmin;
501 cmaxs = this.absmax;
502 for(t = this; ; t = t.enemy)
503 {
504 if(GetResource(t, RES_HEALTH) && !GetResource(this, RES_HEALTH))
505 SetResourceExplicit(this, RES_HEALTH, GetResource(t, RES_HEALTH));
506 if((t.targetname != "") && (this.targetname == ""))
507 this.targetname = t.targetname;
508 if((t.message != "") && (this.message == ""))
509 this.message = t.message;
510 if (t.absmin_x < cmins_x)
511 cmins_x = t.absmin_x;
512 if (t.absmin_y < cmins_y)
513 cmins_y = t.absmin_y;
514 if (t.absmin_z < cmins_z)
515 cmins_z = t.absmin_z;
516 if (t.absmax_x > cmaxs_x)
517 cmaxs_x = t.absmax_x;
518 if (t.absmax_y > cmaxs_y)
519 cmaxs_y = t.absmax_y;
520 if (t.absmax_z > cmaxs_z)
521 cmaxs_z = t.absmax_z;
522 if(t.enemy == this)
523 break;
524 }
525
526 // distribute health, targetname, message
527 for(t = this; t; t = t.enemy)
528 {
529 SetResourceExplicit(t, RES_HEALTH, GetResource(this, RES_HEALTH));
530 t.targetname = this.targetname;
531 t.message = this.message;
532 if(t.enemy == this)
533 break;
534 }
535
536 // shootable, or triggered doors just needed the owner/enemy links,
537 // they don't spawn a field
538
539 if (GetResource(this, RES_HEALTH))
540 return;
541 if(this.targetname && this.targetname != "")
542 return;
543 if (this.items)
544 return;
545
546 door_spawnfield(this, cmins, cmaxs);
547}
548
549REGISTER_NET_LINKED(ENT_CLIENT_DOOR)
550
551#ifdef SVQC
552/*QUAKED spawnfunc_func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
553if two doors touch, they are assumed to be connected and operate as a unit.
554
555TOGGLE causes the door to wait in both the start and end states for a trigger event.
556
557START_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).
558
559GOLD_KEY causes the door to open only if the activator holds a gold key.
560
561SILVER_KEY causes the door to open only if the activator holds a silver key.
562
563"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
564"angle" determines the opening direction
565"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
566"health" if set, door must be shot open
567"speed" movement speed (100 default)
568"wait" wait before returning (3 default, -1 = never return)
569"lip" lip remaining at end of move (8 default)
570"dmg" damage to inflict when blocked (0 default)
571"sounds"
5720) no sound
5731) stone
5742) base
5753) stone chain
5764) screechy metal
577FIXME: only one sound set available at the time being
578
579*/
580
581float door_send(entity this, entity to, float sf)
582{
583 WriteHeader(MSG_ENTITY, ENT_CLIENT_DOOR);
585
586 if(sf & SF_TRIGGER_INIT)
587 {
590
592
593 trigger_common_write(this, true);
594
595 WriteVector(MSG_ENTITY, this.pos1);
596 WriteVector(MSG_ENTITY, this.pos2);
597
598 WriteVector(MSG_ENTITY, this.size);
599
602 WriteByte(MSG_ENTITY, this.lip);
605 }
606
607 if(sf & SF_TRIGGER_RESET)
608 {
609 // client makes use of this, we do not
610 }
611
612 if(sf & SF_TRIGGER_UPDATE)
613 {
614 WriteVector(MSG_ENTITY, this.origin);
615
616 WriteVector(MSG_ENTITY, this.pos1);
617 WriteVector(MSG_ENTITY, this.pos2);
618 }
619
620 return true;
621}
622
624{
625 //Net_LinkEntity(this, false, 0, door_send);
626}
627
629{
630 // Quake 1 and QL keys compatibility
632 this.itemkeys |= BIT(0);
634 this.itemkeys |= BIT(1);
635}
636#endif
637
639{
640 setorigin(this, this.pos2);
641 this.pos2 = this.pos1;
642 this.pos1 = this.origin;
643
644#ifdef SVQC
646#endif
647}
648
650{
651 setorigin(this, this.pos1);
652 this.velocity = '0 0 0';
653 this.state = STATE_BOTTOM;
654 this.active = ACTIVE_ACTIVE;
655 setthink(this, func_null);
656 this.nextthink = 0;
657
658#ifdef SVQC
660 door_init_keys(this);
661#endif
662}
663
664#ifdef SVQC
665
666// common code for func_door and func_door_rotating spawnfuncs
668{
669 this.max_health = GetResource(this, RES_HEALTH);
670
671 // unlock sound
672 if(this.noise == "")
673 {
674 this.noise = "misc/talk.wav";
675 }
676 // door still locked sound
677 if(this.noise3 == "")
678 {
679 this.noise3 = "misc/talk.wav";
680 }
681 precache_sound(this.noise);
683
684 if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message == ""))
685 {
686 this.message = "was squished";
687 }
688 if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message2 == ""))
689 {
690 this.message2 = "was squished by";
691 }
692
693 // TODO: other soundpacks
694 if (this.sounds > 0 || q3compat)
695 {
696 // Doors in Q3 always have sounds (they're hard coded)
697 this.noise2 = "plats/medplat1.wav";
698 this.noise1 = "plats/medplat2.wav";
699 }
700
701 if (q3compat)
702 {
703 // CPMA adds these fields for overriding the Q3 default sounds
704 string s = GetField_fullspawndata(this, "sound_start", true);
705 string e = GetField_fullspawndata(this, "sound_end", true);
706
707 // Quake Live adds these ones, because of course it had to be different from CPMA
708 if (!s) s = GetField_fullspawndata(this, "startsound", true);
709 if (!e) e = GetField_fullspawndata(this, "endsound", true);
710
711 if (s)
712 this.noise2 = strzone(s);
713 else
714 {
715 // PK3s supporting Q3A sometimes include custom sounds at Q3 default paths
716 s = "sound/movers/doors/dr1_strt.wav";
717 if (FindFileInMapPack(s))
718 this.noise2 = s;
719 }
720
721 if (e)
722 this.noise1 = strzone(e);
723 else
724 {
725 e = "sound/movers/doors/dr1_end.wav";
726 if (FindFileInMapPack(e))
727 this.noise1 = e;
728 }
729 }
730
731 // sound when door stops moving
732 if(this.noise1 && this.noise1 != "")
733 {
735 }
736 // sound when door is moving
737 if(this.noise2 && this.noise2 != "")
738 {
740 }
741
743 {
744 this.wait = -1;
745 }
746 else if (!this.wait)
747 {
748 this.wait = q3compat ? 2 : 3;
749 }
750
751 if (!this.lip)
752 {
753 this.lip = 8;
754 }
755
756 this.state = STATE_BOTTOM;
757
758 if (GetResource(this, RES_HEALTH) || (q3compat && this.targetname == ""))
759 {
760 //this.canteamdamage = true; // TODO
761 this.takedamage = DAMAGE_YES;
762 this.event_damage = door_damage;
763 }
764
765 if (this.items)
766 {
767 this.wait = -1;
768 }
769}
770
771// spawnflags require key (for now only func_door)
772spawnfunc(func_door)
773{
774 door_init_keys(this);
775
776 SetMovedir(this);
777
778 if (!InitMovingBrushTrigger(this))
779 return;
780 this.effects |= EF_LOWPRECISION;
781 this.classname = "door";
782
784 this.use = door_use;
785 this.active = ACTIVE_ACTIVE;
786
787 if(this.spawnflags & DOOR_NONSOLID)
788 this.solid = SOLID_NOT;
789
790 // DOOR_START_OPEN is to allow an entity to be lighted in the closed position
791 // but spawn in the open position
792 // the tuba door on xoylent requires the delayed init
793 if (this.spawnflags & DOOR_START_OPEN)
795
796 door_init_shared(this);
797
798 this.pos1 = this.origin;
799 vector absmovedir;
800 absmovedir.x = fabs(this.movedir.x);
801 absmovedir.y = fabs(this.movedir.y);
802 absmovedir.z = fabs(this.movedir.z);
803 this.pos2 = this.pos1 + this.movedir * (absmovedir * this.size - this.lip);
804
806 {
807 this.speed = max(750, this.speed);
808 }
809 else if (!this.speed)
810 {
811 if (q3compat)
812 this.speed = 400;
813 else
814 this.speed = 100;
815 }
816
817 if (q3compat)
818 {
819 if (!this.dmg)
820 this.dmg = 2;
821
822 if (!this.team)
823 {
824 string t = GetField_fullspawndata(this, "team", false);
825 // bones_was_here: same hack as used to support teamed items on Q3 maps
826 if (t) this.team = crc16(false, t);
827 }
828 }
829
830 settouch(this, door_touch);
831
832 // LinkDoors can't be done until all of the doors have been spawned, so
833 // the sizes can be detected properly.
835
836 this.reset = door_reset;
837}
838
839#elif defined(CSQC)
840
841NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
842{
843 int sf = ReadByte();
844
845 if(sf & SF_TRIGGER_INIT)
846 {
847 this.classname = strzone(ReadString());
848 this.spawnflags = ReadByte();
849
850 this.mdl = strzone(ReadString());
851 _setmodel(this, this.mdl);
852
853 trigger_common_read(this, true);
854
855 this.pos1 = ReadVector();
856 this.pos2 = ReadVector();
857
858 this.size = ReadVector();
859
860 this.wait = ReadShort();
861 this.speed = ReadShort();
862 this.lip = ReadByte();
863 this.state = ReadByte();
864 this.ltime = ReadCoord();
865
866 this.solid = SOLID_BSP;
868 this.use = door_use;
869
870 LinkDoors(this);
871
872 if(this.spawnflags & DOOR_START_OPEN)
874
875 this.move_time = time;
877 }
878
879 if(sf & SF_TRIGGER_RESET)
880 {
881 door_reset(this);
882 }
883
884 if(sf & SF_TRIGGER_UPDATE)
885 {
886 this.origin = ReadVector();
887 setorigin(this, this.origin);
888
889 this.pos1 = ReadVector();
890 this.pos2 = ReadVector();
891 }
892 return true;
893}
894
895#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
int items
Definition player.qh:227
#define IS_CLIENT(s)
Definition player.qh:242
#define IS_DEAD(s)
Definition player.qh:245
#define IS_PLAYER(s)
Definition player.qh:243
#define Q3COMPAT_COMMON
Definition stats.qh:368
void FindConnectedComponent(entity e,.entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
Definition util.qc:1766
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:503
#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:581
void door_init_startopen(entity this)
Definition door.qc:638
void door_link()
Definition door.qc:623
void door_use(entity this, entity actor, entity trigger)
Definition door.qc:216
void door_generic_plat_blocked(entity this, entity blocker)
Definition door.qc:319
bool door_check_keys(entity door, entity player)
Definition door.qc:160
void door_hit_bottom(entity this)
Definition door.qc:107
void door_reset(entity this)
Definition door.qc:649
void door_trigger_touch(entity this, entity toucher)
Definition door.qc:364
bool LinkDoors_isconnected(entity e1, entity e2, entity pass)
Definition door.qc:435
void door_init_shared(entity this)
Definition door.qc:667
void door_blocked(entity this, entity blocker)
Definition door.qc:28
float door_finished
Definition door.qc:286
void door_init_keys(entity this)
Definition door.qc:628
void LinkDoors(entity this)
Definition door.qc:454
void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition door.qc:265
void door_go_down(entity this)
Definition door.qc:114
void door_spawnfield(entity this, vector fmins, vector fmaxs)
Definition door.qc:401
entity LinkDoors_nextent(entity cur, entity near, entity pass)
Definition door.qc:426
void door_touch(entity this, entity toucher)
Definition door.qc:296
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:118
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:115
#define ReadVector()
Definition net.qh:367
#define WriteHeader(to, id)
Definition net.qh:221
#define REGISTER_NET_LINKED(id)
Definition net.qh:55
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
float ltime
Definition net.qc:10
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:540
bool InitMovingBrushTrigger(entity this)
Definition subs.qc:577
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:267
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:2209