Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
keys.qc
Go to the documentation of this file.
1#include "keys.qh"
2
3#ifdef CSQC
5{
6 int valid = (l.itemkeys & p.itemkeys); // TODO: itemkeys isn't networked or anything!
7 l.itemkeys &= ~valid; // only some of the needed keys were given
8 return valid != 0;
9}
10#endif
11
12#ifdef SVQC
13/*
14TODO:
15- add an unlock sound (here to trigger_keylock and to func_door)
16- display available keys on the HUD
17- make more tests
18- think about adding NOT_EASY/NOT_NORMAL/NOT_HARD for Q1 compatibility
19- should keys have a trigger?
20*/
21
23{
24 int valid = l.itemkeys & p.itemkeys;
25
26 if (!valid) {
27 // player has none of the needed keys
28 return false;
29 } else if (l.itemkeys == valid) {
30 // ALL needed keys were given
31 l.itemkeys = 0;
32 return true;
33 } else {
34 // only some of the needed keys were given
35 l.itemkeys &= ~valid;
36 return true;
37 }
38}
39
40string item_keys_keylist(float keylist)
41{
42 // no keys
43 if (!keylist)
44 return "";
45
46 // one key
47 if ((keylist & (keylist-1)) == 0)
48 return strcat("the ", item_keys_names[lowestbit(keylist)]);
49
50 string n = "";
51 int base = 0;
52 while (keylist)
53 {
54 int l = lowestbit(keylist);
55 if (n)
56 n = strcat(n, ", the ", item_keys_names[base + l]);
57 else
58 n = strcat("the ", item_keys_names[base + l]);
59
60 keylist = bitshift(keylist, -(l + 1));
61 base += l + 1;
62 }
63
64 return n;
65}
66
67
68/*
69================================
70item_key
71================================
72*/
73
78{
79 if (!IS_PLAYER(toucher))
80 return;
81
82 // player already picked up this key
83 if (PS(toucher).itemkeys & this.itemkeys)
84 return;
85
86 PS(toucher).itemkeys |= this.itemkeys;
87 play2(toucher, this.noise);
88
90
91 string oldmsg = this.message;
92 this.message = "";
93 SUB_UseTargets(this, toucher, toucher); // TODO: should we be using toucher for the trigger here?
94 this.message = oldmsg;
95}
96
101{
102 precache_model(this.model);
103
104 if (this.spawnflags & 1) // FLOATING
105 this.noalign = 1;
106
107 if (this.noalign)
109 else
111
112 precache_sound(this.noise);
113
114 this.mdl = this.model;
116 _setmodel(this, this.model);
117 this.modelflags |= MF_ROTATE;
118 this.solid = SOLID_TRIGGER;
119
120 // The origin.z was raised within the bbox to support the current model
121 //setsize(this, '-16 -16 -24', '16 16 32');
122 setorigin(this, this.origin + '0 0 32');
123 setsize(this, '-16 -16 -56', '16 16 0');
124
125 if (Q3COMPAT_COMMON) // QL compat, Q3 has no keys
126 // QL bbox is '-16 -16 -16' '16 16 16' so raise to match QL absmin.z
127 setorigin(this, this.origin + '0 0 8');
128
129 // NOTE: this isn't an FL_ITEM so it doesn't get the special treatment in DropToFloor_QC()
130 if (!this.noalign)
132
134}
135
136
137/*QUAKED item_key (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
138A key entity.
139The itemkeys bitfield should contain one of the following key IDs:
1401 - GOLD key -
1412 - SILVER key
1424 - BRONZE key
1438 - RED keycard
14416 - BLUE keycard
14532 - GREEN keycard
14616777215 (0xffffff) - MASTER key (all 24 bits set)
147Custom keys:
148 - first key ID is 64
149 - last key ID is 8388608 (1<<23 or 0x800000)
150Keys (other than master keys) with bigger ID than 32 don't have a default netname and model,
151if you use one of them, you MUST provide those.
152-----------KEYS------------
153colormod: color of the key (default: '.9 .9 .9').
154itemkeys: a key Id.
155message: message to print when player picks up this key.
156model: custom key model to use.
157netname: the display name of the key.
158noise: custom sound to play when player picks up the key.
159-------- SPAWNFLAGS --------
160FLOATING: the item will float in air, instead of aligning to the floor by falling
161---------NOTES----------
162This is the only correct way to put keys on the map!
163
164itemkeys MUST always have exactly one bit set (unless it's a master key).
165*/
166spawnfunc(item_key)
167{
168 string _netname;
169 vector _colormod;
170 string _model = "models/keys/key.md3";
171
172 // reject this entity if more than one key was set!
173 if (this.itemkeys>0 && (this.itemkeys & (this.itemkeys-1)) != 0)
174 if (this.itemkeys != 0xffffff) // unless it's a master key
175 {
176 objerror(this, "item_key.itemkeys must contain only 1 bit set specifying the key it represents!");
177 delete(this);
178 return;
179 }
180
181 // find default netname and colormod
182 switch(this.itemkeys) {
183 case BIT(0):
184 _netname = "GOLD key";
185 _colormod = '1 .9 0';
186 break;
187
188 case BIT(1):
189 _netname = "SILVER key";
190 _colormod = '.9 .9 .9';
191 break;
192
193 case BIT(2):
194 _netname = "BRONZE key";
195 _colormod = '.6 .25 0';
196 break;
197
198 case BIT(3):
199 _netname = "RED keycard";
200 _colormod = '.9 0 0';
201 _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
202 break;
203
204 case BIT(4):
205 _netname = "BLUE keycard";
206 _colormod = '0 0 .9';
207 _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
208 break;
209
210 case BIT(5):
211 _netname = "GREEN keycard";
212 _colormod = '0 .9 0';
213 _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
214 break;
215
216 case 0xffffff: // an unlisted key...
217 _netname = "MASTER key";
218 _colormod = '1 0.25 0.25';
219 break;
220
221 default:
222 _netname = "FLUFFY PINK keycard";
223 _colormod = '1 1 1';
224
225 if (this.netname == "")
226 {
227 objerror(this, "item_key doesn't have a default name for this key and a custom one was not specified!");
228 delete(this);
229 return;
230 }
231 if (this.model == "")
232 {
233 objerror(this, "item_key doesn't have a default model for this key and a custom one was not specified!");
234 delete(this);
235 return;
236 }
237 break;
238 }
239
240 // set default netname
241 if (this.netname == "")
242 this.netname = _netname;
243
244 // set default colormod
245 if (!this.colormod)
246 this.colormod = _colormod;
247
248 // set default model
249 if (this.model == "")
250 this.model = _model;
251
252 // set default pickup message
253 if (this.message == "")
254 this.message = strzone(strcat("You've picked up the ", this.netname, "!"));
255
256 if (this.noise == "")
257 this.noise = strzone(SND(ITEMPICKUP));
258
259 // save the name for later
261
262 // put the key on the map
263 spawn_item_key(this);
264}
265
266/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
267SILVER key.
268-----------KEYS------------
269colormod: color of the key (default: '.9 .9 .9').
270message: message to print when player picks up this key.
271model: custom model to use.
272noise: custom sound to play when player picks up the key.
273-------- SPAWNFLAGS --------
274FLOATING: the item will float in air, instead of aligning to the floor by falling
275---------NOTES----------
276Don't use this entity on new maps! Use item_key instead.
277*/
278spawnfunc(item_key1)
279{
280 this.itemkeys = BIT(1);
281 spawnfunc_item_key(this);
282}
283
284/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
285GOLD key.
286-----------KEYS------------
287colormod: color of the key (default: '1 .9 0').
288message: message to print when player picks up this key.
289model: custom model to use.
290noise: custom sound to play when player picks up the key.
291-------- SPAWNFLAGS --------
292FLOATING: the item will float in air, instead of aligning to the floor by falling
293---------NOTES----------
294Don't use this entity on new maps! Use item_key instead.
295*/
296spawnfunc(item_key2)
297{
298 this.itemkeys = BIT(0);
299 spawnfunc_item_key(this);
300}
301
302 // Quake Live Keys
303/*QUAKED item_key_gold (1 .66 0) (-16 -16 -16) (16 16 16) SUSPENDED */
304spawnfunc(item_key_gold)
305{
306 this.itemkeys = BIT(0);
307 spawnfunc_item_key(this);
308}
309/*QUAKED item_key_silver (.56 .56 .56) (-16 -16 -16) (16 16 16) SUSPENDED */
310spawnfunc(item_key_silver)
311{
312 this.itemkeys = BIT(1);
313 spawnfunc_item_key(this);
314}
315/*QUAKED item_key_master (1 0 0) (-16 -16 -16) (16 16 16) SUSPENDED
316Master key, opens silver and gold doors.
317
318-------- KEYS --------
319target : picking up the item will trigger the entity this points to.
320targetname : a target_give entity can point to this for respawn freebies.
321notfree : when set to 1, entity will not spawn in "Free for all", "Race", and "Duel" modes.
322notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
323notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
324not_gametype : space delineated list of gametype shortnames (ffa duel race tdm ca ctf 1f ob har ft dom ad rr) in which to inhibit the entity.
325gametype : space delineated list of gametype shortnames (ffa duel race tdm ca ctf 1f ob har ft dom ad rr) to only spawn entity in this gametype.
326notbot : when set to 1, used to make an item invisible for bot attraction.
327
328-------- SPAWNFLAGS --------
3291 = suspended : item will spawn where it was placed in map and won't drop to the floor.
330*/
331spawnfunc(item_key_master)
332{
333 // We have more key types than QL, may as well open them all.
334 this.itemkeys = 0xffffff;
335 spawnfunc_item_key(this);
336}
337
338#endif
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
ERASEABLE int lowestbit(int f)
Definition bits.qh:17
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
string netname
Definition powerups.qc:20
string message
Definition powerups.qc:19
vector colormod
Definition powerups.qc:21
int spawnflags
Definition ammo.qh:15
string mdl
Definition item.qh:89
#define IS_PLAYER(s)
Definition player.qh:243
#define Q3COMPAT_COMMON
Definition stats.qh:368
const float SOLID_TRIGGER
float effects
vector origin
int modelflags
const int MF_ROTATE
float EF_LOWPRECISION
model
Definition ent_cs.qc:139
solid
Definition ent_cs.qc:165
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
bool item_keys_usekey(entity l, entity p)
Use keys from p on l.
Definition keys.qc:4
void item_key_touch(entity this, entity toucher)
Key touch handler.
Definition keys.qc:77
void spawn_item_key(entity this)
Spawn a key with given model, key code and color.
Definition keys.qc:100
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
string item_keys_names[ITEM_KEY_MAX]
list of key names.
Definition keys.qh:9
string precache_sound(string sample)
void centerprint(string text,...)
string strzone(string s)
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:129
const int MOVETYPE_TOSS
Definition movetypes.qh:135
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define objerror
Definition pre.qh:8
vector
Definition self.qh:92
entity entity toucher
Definition self.qh:72
#define settouch(e, f)
Definition self.qh:73
bool noalign
Definition items.qh:36
void play2(entity e, string filename)
Definition all.qc:116
#define SND(id)
Definition all.qh:35
#define spawnfunc(id)
Definition spawnfunc.qh:96
#define PS(this)
Definition state.qh:18
string noise
Definition subs.qh:83
float itemkeys
Definition subs.qh:61
void DropToFloor_QC_DelayedInit(entity this)
Definition world.qc:2407