]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/item_key.qc
removed debug messages, now on a player can pickup the key
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / item_key.qc
1 /*
2 TODO:
3 - add an unlock sound (here to trigger_keylock and to func_door)
4 - display available keys on the HUD
5 - make more tests
6 - think about adding NOT_EASY/NOT_NORMAL/NOT_HARD for Q1 compatibility
7 - should keys have a trigger?
8 */
9
10 /*
11 ================================
12 item_key1 / item_key2
13 ================================
14 */
15
16 /*
17 Key touch handler.
18 */
19 void item_key_touch(void) {
20         if (other.classname != "player")
21                 return;
22                 
23         // player already picked up this key
24         if (other.itemkeys & self.itemkeys)
25                 return;
26         
27         other.itemkeys |= self.itemkeys;
28         play2(other, self.noise);
29         
30         if (self.message) {
31                 centerprint(other, self.message);
32         }
33 };
34
35 /*
36 Spawn a key with given model, key code and color.
37 */
38 void spawn_item_key(float key_code) {
39         self.itemkeys = key_code;
40         precache_model(self.model);
41         
42         if (self.spawnflags & 1) // FLOATING
43                 self.noalign = 1;
44         
45         if (self.noalign)
46                 self.movetype = MOVETYPE_NONE;
47         else
48                 self.movetype = MOVETYPE_TOSS;
49                 
50         if (!self.noise)
51                 self.noise = "misc/itempickup.wav";
52         
53         precache_sound(self.noise);
54                 
55         self.mdl = self.model;
56         self.effects = EF_LOWPRECISION;
57         setmodel(self, self.model);
58         //setsize(self, '-16 -16 -24', '16 16 32');
59         setorigin(self, self.origin + '0 0 32');
60         setsize(self, '-16 -16 -56', '16 16 0');
61         self.modelflags |= MF_ROTATE;
62         self.solid = SOLID_TRIGGER;
63         
64         if (!self.noalign)
65         {
66                 // first nudge it off the floor a little bit to avoid math errors
67                 setorigin(self, self.origin + '0 0 1');
68                 // note droptofloor returns FALSE if stuck/or would fall too far
69                 droptofloor();
70         }
71
72         self.touch = item_key_touch;
73 };
74
75
76 /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
77 SILVER key.
78 -----------KEYS------------
79 colormod: color of the key (default: '.9 .9 .9').
80 message: message to print when player picks up this key.
81 model: custom model to use.
82 noise: custom sound to play when player picks up the key.
83 -------- SPAWNFLAGS --------
84 FLOATING: the item will float in air, instead of aligning to the floor by falling
85 ---------NOTES----------
86 */
87 void spawnfunc_item_key1(void) {
88         if (!self.model)
89                 self.model = "models/keys/key.md3";
90         
91         if (!self.colormod)
92                 self.colormod = '.9 .9 .9';
93         
94         if (!self.message)
95                 self.message = "You've picked up the silver key!";
96                 
97         spawn_item_key(KEYS_SILVER_KEY);
98 };
99
100 /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
101 GOLD key.
102 -----------KEYS------------
103 colormod: color of the key (default: '1 .9 0').
104 message: message to print when player picks up this key.
105 model: custom model to use.
106 noise: custom sound to play when player picks up the key.
107 -------- SPAWNFLAGS --------
108 FLOATING: the item will float in air, instead of aligning to the floor by falling
109 ---------NOTES----------
110 */
111 void spawnfunc_item_key2(void) {
112         if (!self.model)
113                 self.model = "models/keys/key.md3";
114                 
115         if (!self.colormod)
116                 self.colormod = '1 .9 0';
117         
118         if (!self.message)
119                 self.message = "You've picked up the gold key!";
120                 
121         spawn_item_key(KEYS_GOLD_KEY);
122 };
123
124
125 /*
126 ================================
127 trigger_keylock
128 ================================
129 */
130
131 /*
132 trigger givent targets
133 */
134 void trigger_keylock_trigger(string s) {
135         local entity t, stemp, otemp, atemp;
136         
137         stemp = self;
138         otemp = other;
139         atemp = activator;
140         
141         
142         for(t = world; (t = find(t, targetname, s)); )
143                 if (t.use) {
144                         self = t;
145                         other = stemp;
146                         activator = atemp;
147                         self.use();
148                 }
149         
150         self = stemp;
151         other = otemp;
152         activator = atemp;
153 };
154
155 /*
156 kill killtarget of trigger keylock.
157 */
158 void trigger_keylock_kill(string s) {
159         local entity t, stemp, otemp, atemp;
160         
161         stemp = self;
162         otemp = other;
163         atemp = activator;
164
165         for(t = world; (t = find(t, targetname, s)); )
166                 if (t.use) {
167                         remove(t);
168                 }
169         
170         self = stemp;
171         other = otemp;
172         activator = atemp;
173 };
174
175 void trigger_keylock_touch(void) {
176         local float key_used, silver_key_missing, gold_key_missing, started_delay;
177         
178         key_used = FALSE;
179         silver_key_missing = FALSE;
180         gold_key_missing = FALSE;
181         started_delay = FALSE;
182         
183         // only player may trigger the lock
184         if (other.classname != "player")
185                 return;
186         
187         
188         // check silver key
189         if (self.itemkeys & KEYS_SILVER_KEY) {
190                 // lock still requires the SILVER key
191                 if (other.itemkeys & KEYS_SILVER_KEY) {
192                         self.itemkeys &~= KEYS_SILVER_KEY;
193                         key_used = TRUE;
194                 } else {
195                         silver_key_missing = TRUE;
196                 }
197         }
198         
199         // check gold key
200         if (self.itemkeys & KEYS_GOLD_KEY) {
201                 // lock still requires the GOLD key
202                 if (other.itemkeys & KEYS_GOLD_KEY) {
203                         self.itemkeys &~= KEYS_GOLD_KEY;
204                         key_used = TRUE;
205                 } else {
206                         gold_key_missing = TRUE;
207                 }
208         }
209         
210         
211         activator = other;
212         
213         if (silver_key_missing) {
214                 // silver key is missing
215                 if (self.delay <= time) {
216                         if (self.target4) {
217                                 trigger_keylock_trigger(self.target4);
218                                 started_delay = TRUE;
219                                 self.delay = time + self.wait;
220                         }
221                 }
222         }
223                 
224         if (gold_key_missing) {
225                 // gold key is missing
226                 if (self.delay <= time || started_delay) {
227                         if (self.target3) {
228                                 trigger_keylock_trigger(self.target3);
229                                 started_delay = TRUE;
230                                 self.delay = time + self.wait;
231                         }
232                 }
233                 
234         }
235         
236         if (silver_key_missing || gold_key_missing) {
237                 // at least one of the keys is missing
238                 
239                 if (key_used) {
240                         // one key was given, but an other one is missing!
241                         play2(other, self.noise1);
242                         if (silver_key_missing)
243                                 centerprint(other, "You also need the silver key!");
244                         else if (gold_key_missing)
245                                 centerprint(other, "You also need the gold key!");
246                         other.key_door_messagetime = time + 2;
247                 } else {
248                         if (other.key_door_messagetime <= time) {
249                                 play2(other, self.noise2);
250                                 centerprint(other, self.message2);
251                                 other.key_door_messagetime = time + 2;
252                         }
253                 }
254                 
255                 if (self.delay <= time || started_delay == TRUE) {
256                         if (self.target2) {
257                                 trigger_keylock_trigger(self.target2);
258                                 started_delay = TRUE;
259                                 self.delay = time + self.wait;
260                         }
261                 
262                 }
263         } else {
264                 // all keys were given!
265                 play2(other, self.noise);
266                 centerprint(other, self.message);
267                 
268                 if (self.target)
269                         trigger_keylock_trigger(self.target);
270                         
271                 if (self.killtarget)
272                         trigger_keylock_kill(self.killtarget);
273                 
274                 remove(self);
275         }
276         
277 };
278
279 /*QUAKED trigger_keylock (.0 .5 .8) ? - - - GOLD_KEY SILVER_KEY
280 Keylock trigger.  Must target other entities.
281 This trigger will trigger target entities when all required keys are provided.
282 -------- KEYS --------
283 wait: prevent triggering again for this amount of time (default: 5) - applies to target2, target3, target4.
284 sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav
285 target: trigger all entities with this targetname when triggered and all keys have been given to it, then remove this trigger
286 target2: trigger all entities with this targetname when triggered without giving it all the required keys.
287 target3: trigger all entities with this targetname when triggered with GOLD_KEY missing (requires GOLD_KEY spawnflag)
288 target4: trigger all entities with this targetname when triggered with SILVER_KEY missing (requires SILVER_KEY spawnflag)
289 message: print this message to the player who activated the trigger when all needed keys have been given.
290 message2: print this message to the player who activated the trigger when not all of the needed keys have been given.
291 noise: sound to play when lock gets unlocked (default: see sounds)
292 noise1: sound to play when only one of the needed key was used (default: misc/decreasevalue.wav)
293 noise2: sound to play when a key is missing (default: misc/talk.wav)
294 killtarget: remove all entities with this targetname when triggered with all the needed keys.
295 -------- SPAWNFLAGS --------
296 GOLD_KEY: causes the door to open only if the activator holds a gold key.
297 SILVER_KEY: causes the door to open only if the activator holds a silver key.
298 ---------NOTES----------
299 If spawned without any key specified, this trigger will remove itself.
300 message2 and noise2 will be resent to the player every 2 seconds while he is in the trigger zone.
301 */
302 void spawnfunc_trigger_keylock(void) {
303         if (!(self.spawnflags & (SPAWNFLAGS_SILVER_KEY | SPAWNFLAGS_GOLD_KEY))) {
304                 remove(self);
305                 return;
306         }
307
308         // give the trigger the silver key      
309         if (self.spawnflags & SPAWNFLAGS_SILVER_KEY)
310                 self.itemkeys |= KEYS_SILVER_KEY;
311         
312         // give the trigger the gold key
313         if (self.spawnflags & SPAWNFLAGS_GOLD_KEY)
314                 self.itemkeys |= KEYS_GOLD_KEY;
315
316         if (!self.message2) {
317                 // generate default missing key message
318                 if (self.itemkeys & (KEYS_GOLD_KEY | KEYS_SILVER_KEY) == KEYS_GOLD_KEY | KEYS_SILVER_KEY) {
319                         self.message2 = "Silver key and gold key required!";
320                 } else if (self.itemkeys & KEYS_GOLD_KEY) {
321                         self.message2 = "Gold key required!";
322                 } else if (self.itemkeys & KEYS_SILVER_KEY) {
323                         self.message2 = "Silver key required!";
324                 }
325         }
326         
327         if (!self.message) {
328                 self.message = "Unlocked!";
329         }
330         
331         if (!self.noise) {
332                 if (self.sounds == 1) {
333                         self.noise = "misc/secret.wav";
334                 } else if (self.sounds == 2) {
335                         self.noise = "misc/talk.wav";
336                 } else { //if (self.sounds == 3) {
337                         self.noise = "misc/trigger1.wav";
338                 }
339         }
340                 
341         if (!self.noise1)
342                 self.noise1 = "misc/decreasevalue.wav";
343                 
344         if (!self.noise2)
345                 self.noise2 = "misc/talk.wav";
346         
347         if (!self.wait)
348                 self.wait = 5;
349         
350         precache_sound(self.noise);
351         precache_sound(self.noise1);
352         precache_sound(self.noise2);
353         
354         EXACTTRIGGER_INIT;
355         
356         self.touch = trigger_keylock_touch;
357 };
358