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