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: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 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.
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:215
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
model
Definition ent_cs.qc:139
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
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 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: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 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: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 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: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 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
#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
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:539
bool InitMovingBrushTrigger(entity this)
Definition subs.qc:576
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2230

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().