Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
door.qc File Reference
#include "door.qh"
#include "door_rotating.qh"
Include dependency graph for door.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void door_blocked (entity this, entity blocker)
bool door_check_keys (entity door, entity player)
void door_damage (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void door_generic_plat_blocked (entity this, entity blocker)
void door_go_down (entity this)
void door_go_up (entity this, entity actor, entity trigger)
void door_hit_bottom (entity this)
void door_hit_top (entity this)
void door_init_keys (entity this)
void door_init_shared (entity this)
void door_init_startopen (entity this)
void door_link ()
void door_reset (entity this)
float door_send (entity this, entity to, float sf)
void door_spawnfield (entity this, vector fmins, vector fmaxs)
void door_touch (entity this, entity toucher)
void door_trigger_touch (entity this, entity toucher)
void door_use (entity this, entity actor, entity trigger)
void LinkDoors (entity this)
bool LinkDoors_isconnected (entity e1, entity e2, entity pass)
entity LinkDoors_nextent (entity cur, entity near, entity pass)
 spawnfunc (func_door)

Variables

float door_finished

Function Documentation

◆ door_blocked()

void door_blocked ( entity this,
entity blocker )

Definition at line 28 of file door.qc.

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}
float dmg
Definition breakable.qc:12
int spawnflags
Definition ammo.qh:15
#define IS_DEAD(s)
Definition player.qh:245
#define Q3COMPAT_COMMON
Definition stats.qh:368
string classname
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
void door_go_down(entity this)
Definition door.qc:114
void door_go_up(entity this, entity actor, entity trigger)
Definition door.qc:128
const int DOOR_CRUSH
Definition door.qh:14
#define Q3_DOOR_CRUSHER
Definition door.qh:16
void door_rotating_go_up(entity this, entity oth)
void door_rotating_go_down(entity this)
#define NULL
Definition post.qh:14
void SUB_CalcMovePause(entity this)
Definition subs.qc:105
const int DAMAGE_NO
Definition subs.qh:79
entity move_controller
Definition subs.qh:68
#define STATE_DOWN
Definition sys-pre.qh:31

References classname, Damage(), DAMAGE_NO, dmg, DMG_NOWEP, DOOR_CRUSH, door_go_down(), door_go_up(), door_rotating_go_down(), door_rotating_go_up(), entity(), IS_DEAD, move_controller, NULL, Q3_DOOR_CRUSHER, Q3COMPAT_COMMON, spawnflags, state, STATE_DOWN, and SUB_CalcMovePause().

Referenced by spawnfunc(), and spawnfunc().

◆ door_check_keys()

bool door_check_keys ( entity door,
entity player )

Definition at line 160 of file door.qc.

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}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define IS_PLAYER(s)
Definition player.qh:243
float time
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
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
void play2(entity e, string filename)
Definition all.qc:116
#define PS(this)
Definition state.qh:18

References entity(), IS_PLAYER, item_keys_keylist(), play2(), PS, Send_Notification(), and time.

Referenced by door_trigger_touch().

◆ door_damage()

void door_damage ( entity this,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

Definition at line 265 of file door.qc.

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}
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.
entity owner
Definition main.qh:87
#define DEATH_ISSPECIAL(t)
Definition all.qh:39
const int HITTYPE_SPLASH
Definition all.qh:30
const int NOSPLASH
Definition defs.qh:12
void door_use(entity this, entity actor, entity trigger)
Definition door.qc:216
float itemkeys
Definition subs.qh:61

References DAMAGE_NO, DEATH_ISSPECIAL, door_use(), entity(), GetResource(), HITTYPE_SPLASH, itemkeys, NOSPLASH, NULL, owner, SetResourceExplicit(), spawnflags, TakeResource(), and vector.

Referenced by door_init_shared().

◆ door_generic_plat_blocked()

void door_generic_plat_blocked ( entity this,
entity blocker )

Definition at line 319 of file door.qc.

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}
float wait
Definition items.qc:17
const int DAMAGE_YES
Definition subs.qh:80

References Damage(), DAMAGE_NO, DAMAGE_YES, dmg, DMG_NOWEP, DOOR_CRUSH, door_rotating_go_down(), door_rotating_go_up(), entity(), IS_DEAD, spawnflags, state, STATE_DOWN, and wait.

◆ door_go_down()

void door_go_down ( entity this)

Definition at line 114 of file door.qc.

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}
float max_health
void door_hit_bottom(entity this)
Definition door.qc:107
float speed
Definition dynlight.qc:9
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 SUB_CalcMove(entity this, vector tdest, float tspeedtype, float tspeed, void(entity this) func)
Definition subs.qc:267
vector pos1
Definition subs.qh:50
string noise2
Definition subs.qh:83
const int TSPEED_LINEAR
Definition subs.qh:71
float takedamage
Definition subs.qh:78

References _sound, ATTEN_NORM, CH_TRIGGER_SINGLE, DAMAGE_YES, door_hit_bottom(), entity(), max_health, noise2, pos1, SetResourceExplicit(), speed, state, STATE_DOWN, SUB_CalcMove(), takedamage, TSPEED_LINEAR, and VOL_BASE.

Referenced by door_blocked(), door_hit_top(), and door_use().

◆ door_go_up()

void door_go_up ( entity this,
entity actor,
entity trigger )

Definition at line 128 of file door.qc.

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}
string message
Definition powerups.qc:19
float nextthink
void door_hit_top(entity this)
Definition door.qc:90
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
float ltime
Definition net.qc:10
vector pos2
Definition subs.qh:50
#define STATE_UP
Definition sys-pre.qh:30
#define STATE_TOP
Definition sys-pre.qh:28

References _sound, ATTEN_NORM, CH_TRIGGER_SINGLE, door_hit_top(), entity(), ltime, message, nextthink, noise2, pos2, speed, state, STATE_TOP, STATE_UP, SUB_CalcMove(), SUB_UseTargets(), TSPEED_LINEAR, VOL_BASE, and wait.

Referenced by door_blocked(), and door_use().

◆ door_hit_bottom()

void door_hit_bottom ( entity this)

Definition at line 107 of file door.qc.

108{
109 if (this.noise1 != "")
111 this.state = STATE_BOTTOM;
112}
string noise1
Definition subs.qh:83
#define STATE_BOTTOM
Definition sys-pre.qh:29

References _sound, ATTEN_NORM, CH_TRIGGER_SINGLE, entity(), noise1, state, STATE_BOTTOM, and VOL_BASE.

Referenced by door_go_down().

◆ door_hit_top()

void door_hit_top ( entity this)

Definition at line 90 of file door.qc.

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}
const int DOOR_TOGGLE
Definition door.qh:11
#define setthink(e, f)

References _sound, ATTEN_NORM, CH_TRIGGER_SINGLE, classname, door_go_down(), door_rotating_go_down(), DOOR_TOGGLE, entity(), ltime, nextthink, noise1, setthink, spawnflags, state, STATE_TOP, VOL_BASE, and wait.

Referenced by door_go_up().

◆ door_init_keys()

void door_init_keys ( entity this)

Definition at line 628 of file door.qc.

629{
630 // Quake 1 and QL keys compatibility
632 this.itemkeys |= BIT(0);
634 this.itemkeys |= BIT(1);
635}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
const int SPAWNFLAGS_GOLD_KEY
Definition door.qh:9
const int SPAWNFLAGS_SILVER_KEY
Definition door.qh:10

References BIT, entity(), itemkeys, spawnflags, SPAWNFLAGS_GOLD_KEY, and SPAWNFLAGS_SILVER_KEY.

Referenced by door_reset(), and spawnfunc().

◆ door_init_shared()

void door_init_shared ( entity this)

Definition at line 667 of file door.qc.

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}
int items
Definition player.qh:227
void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition door.qc:265
bool autocvar_sv_doors_always_open
Definition door.qh:4
string precache_sound(string sample)
string strzone(string s)
q3compat
Definition quake3.qc:59
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
string noise
Definition subs.qh:83
float lip
Definition subs.qh:40
float sounds
Definition subs.qh:42
string noise3
Definition subs.qh:83
string message2
Definition triggers.qh:19
string targetname
Definition triggers.qh:56

References autocvar_sv_doors_always_open, DAMAGE_YES, dmg, DOOR_CRUSH, door_damage(), entity(), FindFileInMapPack(), GetField_fullspawndata(), GetResource(), items, lip, max_health, message, message2, noise, noise1, noise2, noise3, precache_sound(), q3compat, sounds, spawnflags, state, STATE_BOTTOM, strzone(), takedamage, targetname, and wait.

Referenced by spawnfunc(), and spawnfunc().

◆ door_init_startopen()

void door_init_startopen ( entity this)

Definition at line 638 of file door.qc.

639{
640 setorigin(this, this.pos2);
641 this.pos2 = this.pos1;
642 this.pos1 = this.origin;
643
644#ifdef SVQC
646#endif
647}
vector origin
const int SF_TRIGGER_UPDATE
Definition defs.qh:23
int SendFlags
Definition net.qh:118

References entity(), origin, pos1, pos2, SendFlags, and SF_TRIGGER_UPDATE.

Referenced by spawnfunc().

◆ door_link()

void door_link ( )

Definition at line 623 of file door.qc.

624{
625 //Net_LinkEntity(this, false, 0, door_send);
626}

Referenced by LinkDoors().

◆ door_reset()

void door_reset ( entity this)

Definition at line 649 of file door.qc.

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}
vector velocity
const int SF_TRIGGER_RESET
Definition defs.qh:24
int active
Definition defs.qh:34
const int ACTIVE_ACTIVE
Definition defs.qh:37
void door_init_keys(entity this)
Definition door.qc:628
var void func_null()

References active, ACTIVE_ACTIVE, door_init_keys(), entity(), func_null(), nextthink, pos1, SendFlags, setthink, SF_TRIGGER_RESET, state, STATE_BOTTOM, and velocity.

Referenced by spawnfunc().

◆ door_send()

float door_send ( entity this,
entity to,
float sf )

Definition at line 581 of file door.qc.

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}
vector size
const int SF_TRIGGER_INIT
Definition defs.qh:22
model
Definition ent_cs.qc:139
const int MSG_ENTITY
Definition net.qh:115
#define WriteHeader(to, id)
Definition net.qh:221
void WriteString(string data, float dest, float desto)
void WriteShort(float data, float dest, float desto)
void WriteCoord(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
void trigger_common_write(entity this, bool withtarget)
Definition triggers.qc:110

References classname, entity(), lip, ltime, model, MSG_ENTITY, origin, pos1, pos2, SF_TRIGGER_INIT, SF_TRIGGER_RESET, SF_TRIGGER_UPDATE, size, spawnflags, speed, state, trigger_common_write(), wait, WriteByte(), WriteCoord(), WriteHeader, WriteShort(), and WriteString().

◆ door_spawnfield()

void door_spawnfield ( entity this,
vector fmins,
vector fmaxs )

Definition at line 401 of file door.qc.

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}
const float SOLID_TRIGGER
void door_trigger_touch(entity this, entity toucher)
Definition door.qc:364
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:129
vector
Definition self.qh:92
#define settouch(e, f)
Definition self.qh:73

References door_trigger_touch(), entity(), MOVETYPE_NONE, set_movetype(), settouch, SOLID_TRIGGER, and vector.

Referenced by LinkDoors().

◆ door_touch()

void door_touch ( entity this,
entity toucher )

Definition at line 296 of file door.qc.

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}
#define IS_CLIENT(s)
Definition player.qh:242
void centerprint(string text,...)
entity entity toucher
Definition self.qh:72

References ACTIVE_ACTIVE, centerprint(), entity(), IS_CLIENT, IS_PLAYER, owner, play2(), time, and toucher.

Referenced by spawnfunc(), and spawnfunc().

◆ door_trigger_touch()

void door_trigger_touch ( entity this,
entity toucher )

Definition at line 364 of file door.qc.

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}
const int FL_PROJECTILE
Definition constants.qh:85
bool door_check_keys(entity door, entity player)
Definition door.qc:160

References ACTIVE_ACTIVE, door_check_keys(), door_use(), entity(), FL_PROJECTILE, GetResource(), IS_CLIENT, IS_DEAD, NULL, owner, STATE_TOP, STATE_UP, and toucher.

Referenced by door_spawnfield().

◆ door_use()

void door_use ( entity this,
entity actor,
entity trigger )

Definition at line 216 of file door.qc.

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}
const int DOOR_ROTATING_BIDIR_IN_DOWN
const int DOOR_ROTATING_BIDIR

References ACTIVE_ACTIVE, door_go_down(), door_go_up(), DOOR_ROTATING_BIDIR, DOOR_ROTATING_BIDIR_IN_DOWN, door_rotating_go_down(), door_rotating_go_up(), DOOR_TOGGLE, entity(), NULL, owner, spawnflags, state, STATE_BOTTOM, STATE_DOWN, STATE_TOP, and STATE_UP.

Referenced by door_damage(), door_trigger_touch(), spawnfunc(), and spawnfunc().

◆ LinkDoors()

void LinkDoors ( entity this)

Definition at line 454 of file door.qc.

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}
int team
Definition main.qh:188
void FindConnectedComponent(entity e,.entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
Definition util.qc:1766
vector absmax
vector absmin
void door_link()
Definition door.qc:623
bool LinkDoors_isconnected(entity e1, entity e2, entity pass)
Definition door.qc:435
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
const int DOOR_DONT_LINK
Definition door.qh:8
#define LOG_TRACE(...)
Definition log.qh:76
string etos(entity e)
entity enemy
Definition sv_ctf.qh:153

References absmax, absmin, DOOR_DONT_LINK, door_link(), door_spawnfield(), enemy, entity(), etos(), FindConnectedComponent(), GetResource(), items, LinkDoors_isconnected(), LinkDoors_nextent(), LOG_TRACE, message, NULL, owner, Q3COMPAT_COMMON, SetResourceExplicit(), spawnflags, targetname, team, and vector.

Referenced by spawnfunc(), and spawnfunc().

◆ LinkDoors_isconnected()

bool LinkDoors_isconnected ( entity e1,
entity e2,
entity pass )

Definition at line 435 of file door.qc.

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}

References entity(), pass, and Q3COMPAT_COMMON.

Referenced by LinkDoors().

◆ LinkDoors_nextent()

entity LinkDoors_nextent ( entity cur,
entity near,
entity pass )

Definition at line 426 of file door.qc.

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}
#define pass(name, colormin, colormax)
entity find(entity start,.string field, string match)

References classname, DOOR_DONT_LINK, entity(), find(), pass, and Q3COMPAT_COMMON.

Referenced by LinkDoors().

◆ spawnfunc()

spawnfunc ( func_door )

Definition at line 772 of file door.qc.

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}
const int INITPRIO_SETLOCATION
Definition constants.qh:98
const int INITPRIO_LINKDOORS
Definition constants.qh:99
const float SOLID_NOT
float effects
#define use
void door_init_startopen(entity this)
Definition door.qc:638
void door_reset(entity this)
Definition door.qc:649
void door_init_shared(entity this)
Definition door.qc:667
void door_blocked(entity this, entity blocker)
Definition door.qc:28
void LinkDoors(entity this)
Definition door.qc:454
void door_touch(entity this, entity toucher)
Definition door.qc:296
const int DOOR_START_OPEN
Definition door.qh:7
const int DOOR_NONSOLID
Definition door.qh:13
float EF_LOWPRECISION
solid
Definition ent_cs.qc:165
vector movedir
Definition viewloc.qh:18
float fabs(float f)
float max(float f,...)
#define setblocked(e, f)
void SetMovedir(entity this)
Definition subs.qc:540
bool InitMovingBrushTrigger(entity this)
Definition subs.qc:577
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2209

References active, ACTIVE_ACTIVE, autocvar_sv_doors_always_open, classname, dmg, door_blocked(), door_init_keys(), door_init_shared(), door_init_startopen(), DOOR_NONSOLID, door_reset(), DOOR_START_OPEN, door_touch(), door_use(), EF_LOWPRECISION, effects, fabs(), GetField_fullspawndata(), InitializeEntity(), InitMovingBrushTrigger(), INITPRIO_LINKDOORS, INITPRIO_SETLOCATION, LinkDoors(), lip, max(), movedir, origin, pos1, pos2, q3compat, setblocked, SetMovedir(), settouch, size, solid, SOLID_NOT, spawnflags, speed, team, use, and vector.

Variable Documentation

◆ door_finished

float door_finished

Definition at line 286 of file door.qc.

Referenced by secret_blocked(), and secret_touch().