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:244
#define Q3COMPAT_COMMON
Definition stats.qh:370
string classname
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
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 159 of file door.qc.

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}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define IS_PLAYER(s)
Definition player.qh:242
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:1500
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 264 of file door.qc.

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}
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.
entity owner
Definition main.qh:87
#define DEATH_ISSPECIAL(t)
Definition all.qh:41
const int HITTYPE_SPLASH
automatically set by RadiusDamage
Definition all.qh:32
const int NOSPLASH
Definition defs.qh:12
void door_use(entity this, entity actor, entity trigger)
Definition door.qc:215
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
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 318 of file door.qc.

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}
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:266
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 = this.message;
145 this.message = "";
146 SUB_UseTargets(this, actor, trigger);
147 this.message = oldmessage;
148}
string message
Definition powerups.qc:19
float ltime
Definition net.qh:10
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
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 627 of file door.qc.

628{
629 // Quake 1 and QL keys compatibility
631 this.itemkeys |= BIT(0);
633 this.itemkeys |= BIT(1);
634}
#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 666 of file door.qc.

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}
int items
Definition player.qh:226
void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition door.qc:264
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 637 of file door.qc.

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

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

Referenced by spawnfunc().

◆ door_link()

void door_link ( )

Definition at line 622 of file door.qc.

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

Referenced by LinkDoors().

◆ door_reset()

void door_reset ( entity this)

Definition at line 648 of file door.qc.

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}
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:627
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 580 of file door.qc.

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}
vector size
const int SF_TRIGGER_INIT
Definition defs.qh:22
WriteString(chan, ent.netname)
model
Definition ent_cs.qc:164
WriteByte(chan, ent.angles.y/DEC_FACTOR)
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
void WriteShort(float data, float dest, float desto)
void WriteCoord(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 400 of file door.qc.

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

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 295 of file door.qc.

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

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 363 of file door.qc.

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

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 215 of file door.qc.

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}
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 453 of file door.qc.

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

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 434 of file door.qc.

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}

References entity(), pass, and Q3COMPAT_COMMON.

Referenced by LinkDoors().

◆ LinkDoors_nextent()

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

Definition at line 425 of file door.qc.

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}
#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 771 of file door.qc.

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}
const int INITPRIO_SETLOCATION
Definition constants.qh:98
const int INITPRIO_LINKDOORS
Definition constants.qh:99
const float SOLID_NOT
float effects
float solid
#define use
void door_init_startopen(entity this)
Definition door.qc:637
void door_reset(entity this)
Definition door.qc:648
void door_init_shared(entity this)
Definition door.qc:666
void door_blocked(entity this, entity blocker)
Definition door.qc:28
void LinkDoors(entity this)
Definition door.qc:453
void door_touch(entity this, entity toucher)
Definition door.qc:295
const int DOOR_START_OPEN
Definition door.qh:7
const int DOOR_NONSOLID
Definition door.qh:13
float EF_LOWPRECISION
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:539
bool InitMovingBrushTrigger(entity this)
Definition subs.qc:576
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2229

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 285 of file door.qc.

Referenced by secret_blocked(), and secret_touch().