]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/item_key.qc
Merge branch 'master' into terencehill/menu_gametype_tooltips_2
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / item_key.qc
1 #include "item_key.qh"
2 #include "_all.qh"
3
4 #include "../common/triggers/subs.qh"
5 #include "../common/monsters/all.qh"
6 #include "../common/notifications.qh"
7 #include "../common/util.qh"
8 #include "../warpzonelib/util_server.qh"
9
10 /*
11 TODO:
12 - add an unlock sound (here to trigger_keylock and to func_door)
13 - display available keys on the HUD
14 - make more tests
15 - think about adding NOT_EASY/NOT_NORMAL/NOT_HARD for Q1 compatibility
16 - should keys have a trigger?
17 */
18
19 bool item_keys_usekey(entity l, entity p)
20 {
21         float valid = l.itemkeys & p.itemkeys;
22
23         if (!valid) {
24                 // other has none of the needed keys
25                 return false;
26         } else if (l.itemkeys == valid) {
27                 // ALL needed keys were given
28                 l.itemkeys = 0;
29                 return true;
30         } else {
31                 // only some of the needed keys were given
32                 l.itemkeys &= ~valid;
33                 return true;
34         }
35 }
36
37 string item_keys_keylist(float keylist) {
38         // no keys
39         if (!keylist)
40                 return "";
41
42         // one key
43         if ((keylist & (keylist-1)) != 0)
44                 return strcat("the ", item_keys_names[lowestbit(keylist)]);
45
46         string n = "";
47         int base = 0;
48         while (keylist) {
49                 int l = lowestbit(keylist);
50                 if (n)
51                         n = strcat(n, ", the ", item_keys_names[base + l]);
52                 else
53                         n = strcat("the ", item_keys_names[base + l]);
54
55                 keylist = bitshift(keylist,  -(l + 1));
56                 base+= l + 1;
57         }
58
59         return n;
60 }
61
62
63 /*
64 ================================
65 item_key
66 ================================
67 */
68
69 /**
70  * Key touch handler.
71  */
72 void item_key_touch()
73 {SELFPARAM();
74         if (!IS_PLAYER(other))
75                 return;
76
77         // player already picked up this key
78         if (other.itemkeys & self.itemkeys)
79                 return;
80
81         other.itemkeys |= self.itemkeys;
82         play2(other, self.noise);
83
84         centerprint(other, self.message);
85 };
86
87 /**
88  * Spawn a key with given model, key code and color.
89  */
90 void spawn_item_key()
91 {SELFPARAM();
92         precache_model(self.model);
93
94         if (self.spawnflags & 1) // FLOATING
95                 self.noalign = 1;
96
97         if (self.noalign)
98                 self.movetype = MOVETYPE_NONE;
99         else
100                 self.movetype = MOVETYPE_TOSS;
101
102         precache_sound(self.noise);
103
104         self.mdl = self.model;
105         self.effects = EF_LOWPRECISION;
106         _setmodel(self, self.model);
107         //setsize(self, '-16 -16 -24', '16 16 32');
108         setorigin(self, self.origin + '0 0 32');
109         setsize(self, '-16 -16 -56', '16 16 0');
110         self.modelflags |= MF_ROTATE;
111         self.solid = SOLID_TRIGGER;
112
113         if (!self.noalign)
114         {
115                 // first nudge it off the floor a little bit to avoid math errors
116                 setorigin(self, self.origin + '0 0 1');
117                 // note droptofloor returns false if stuck/or would fall too far
118                 droptofloor();
119         }
120
121         self.touch = item_key_touch;
122 };
123
124
125 /*QUAKED item_key (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
126 A key entity.
127 The itemkeys should contain one of the following key IDs:
128 1 - GOLD key -
129 2 - SILVER key
130 4 - BRONZE key
131 8 - RED keycard
132 16 - BLUE keycard
133 32 - GREEN keycard
134 Custom keys:
135 ... - last key is 1<<23
136 Keys with bigger Id than 32 don't have a default netname and model, if you use one of them, you MUST provide those.
137 -----------KEYS------------
138 colormod: color of the key (default: '.9 .9 .9').
139 itemkeys: a key Id.
140 message: message to print when player picks up this key.
141 model: custom key model to use.
142 netname: the display name of the key.
143 noise: custom sound to play when player picks up the key.
144 -------- SPAWNFLAGS --------
145 FLOATING: the item will float in air, instead of aligning to the floor by falling
146 ---------NOTES----------
147 This is the only correct way to put keys on the map!
148
149 itemkeys MUST always have exactly one bit set.
150 */
151 spawnfunc(item_key)
152 {
153         string _netname;
154         vector _colormod;
155
156         // reject this entity if more than one key was set!
157         if (self.itemkeys>0 && (self.itemkeys & (self.itemkeys-1)) != 0) {
158                 objerror("item_key.itemkeys must contain only 1 bit set specifying the key it represents!");
159                 remove(self);
160                 return;
161         }
162
163         // find default netname and colormod
164         switch(self.itemkeys) {
165         case 1:
166                 _netname = "GOLD key";
167                 _colormod = '1 .9 0';
168                 break;
169
170         case 2:
171                 _netname = "SILVER key";
172                 _colormod = '.9 .9 .9';
173                 break;
174
175         case 4:
176                 _netname = "BRONZE key";
177                 _colormod = '.6 .25 0';
178                 break;
179
180         case 8:
181                 _netname = "RED keycard";
182                 _colormod = '.9 0 0';
183                 break;
184
185         case 16:
186                 _netname = "BLUE keycard";
187                 _colormod = '0 0 .9';
188                 break;
189
190         case 32:
191                 _netname = "GREEN keycard";
192                 _colormod = '0 .9 0';
193                 break;
194
195         default:
196                 _netname = "FLUFFY PINK keycard";
197                 _colormod = '1 1 1';
198
199                 if (self.netname == "") {
200                         objerror("item_key doesn't have a default name for this key and a custom one was not specified!");
201                         remove(self);
202                         return;
203                 }
204                 break;
205
206         }
207
208         // find default model
209         string _model = string_null;
210         if (self.itemkeys <= ITEM_KEY_BIT(2)) {
211                 _model = "models/keys/key.md3";
212         } else if (self.itemkeys >= ITEM_KEY_BIT(3) && self.itemkeys <= ITEM_KEY_BIT(5)) {
213                 _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
214         } else if (self.model == "") {
215                 objerror("item_key doesn't have a default model for this key and a custom one was not specified!");
216                 remove(self);
217                 return;
218         }
219
220         // set defailt netname
221         if (self.netname == "")
222                 self.netname = _netname;
223
224         // set default colormod
225         if (!self.colormod)
226                 self.colormod = _colormod;
227
228         // set default model
229         if (self.model == "")
230                 self.model = _model;
231
232         // set default pickup message
233         if (self.message == "")
234                 self.message = strzone(strcat("You've picked up the ", self.netname, "!"));
235
236         if (self.noise == "")
237                 self.noise = SND(ITEMPICKUP);
238
239         // save the name for later
240         item_keys_names[lowestbit(self.itemkeys)] = self.netname;
241
242         // put the key on the map
243         spawn_item_key();
244 }
245
246 /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
247 SILVER key.
248 -----------KEYS------------
249 colormod: color of the key (default: '.9 .9 .9').
250 message: message to print when player picks up this key.
251 model: custom model to use.
252 noise: custom sound to play when player picks up the key.
253 -------- SPAWNFLAGS --------
254 FLOATING: the item will float in air, instead of aligning to the floor by falling
255 ---------NOTES----------
256 Don't use this entity on new maps! Use item_key instead.
257 */
258 spawnfunc(item_key1)
259 {
260         this.classname = "item_key";
261         this.itemkeys = ITEM_KEY_BIT(1);
262         spawnfunc_item_key(this);
263 };
264
265 /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
266 GOLD key.
267 -----------KEYS------------
268 colormod: color of the key (default: '1 .9 0').
269 message: message to print when player picks up this key.
270 model: custom model to use.
271 noise: custom sound to play when player picks up the key.
272 -------- SPAWNFLAGS --------
273 FLOATING: the item will float in air, instead of aligning to the floor by falling
274 ---------NOTES----------
275 Don't use this entity on new maps! Use item_key instead.
276 */
277 spawnfunc(item_key2)
278 {
279         this.classname = "item_key";
280         this.itemkeys = ITEM_KEY_BIT(0);
281         spawnfunc_item_key(this);
282 };