]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/item_key.qc
Merge branch 'TimePath/deathtypes' into 'master'
[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 "../lib/warpzone/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         activator = other;
86         SUB_UseTargets();
87 };
88
89 /**
90  * Spawn a key with given model, key code and color.
91  */
92 void spawn_item_key()
93 {SELFPARAM();
94         precache_model(self.model);
95
96         if (self.spawnflags & 1) // FLOATING
97                 self.noalign = 1;
98
99         if (self.noalign)
100                 self.movetype = MOVETYPE_NONE;
101         else
102                 self.movetype = MOVETYPE_TOSS;
103
104         precache_sound(self.noise);
105
106         self.mdl = self.model;
107         self.effects = EF_LOWPRECISION;
108         _setmodel(self, self.model);
109         //setsize(self, '-16 -16 -24', '16 16 32');
110         setorigin(self, self.origin + '0 0 32');
111         setsize(self, '-16 -16 -56', '16 16 0');
112         self.modelflags |= MF_ROTATE;
113         self.solid = SOLID_TRIGGER;
114
115         if (!self.noalign)
116         {
117                 // first nudge it off the floor a little bit to avoid math errors
118                 setorigin(self, self.origin + '0 0 1');
119                 // note droptofloor returns false if stuck/or would fall too far
120                 droptofloor();
121         }
122
123         self.touch = item_key_touch;
124 };
125
126
127 /*QUAKED item_key (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
128 A key entity.
129 The itemkeys should contain one of the following key IDs:
130 1 - GOLD key -
131 2 - SILVER key
132 4 - BRONZE key
133 8 - RED keycard
134 16 - BLUE keycard
135 32 - GREEN keycard
136 Custom keys:
137 ... - last key is 1<<23
138 Keys with bigger Id than 32 don't have a default netname and model, if you use one of them, you MUST provide those.
139 -----------KEYS------------
140 colormod: color of the key (default: '.9 .9 .9').
141 itemkeys: a key Id.
142 message: message to print when player picks up this key.
143 model: custom key model to use.
144 netname: the display name of the key.
145 noise: custom sound to play when player picks up the key.
146 -------- SPAWNFLAGS --------
147 FLOATING: the item will float in air, instead of aligning to the floor by falling
148 ---------NOTES----------
149 This is the only correct way to put keys on the map!
150
151 itemkeys MUST always have exactly one bit set.
152 */
153 spawnfunc(item_key)
154 {
155         string _netname;
156         vector _colormod;
157
158         // reject this entity if more than one key was set!
159         if (self.itemkeys>0 && (self.itemkeys & (self.itemkeys-1)) != 0) {
160                 objerror("item_key.itemkeys must contain only 1 bit set specifying the key it represents!");
161                 remove(self);
162                 return;
163         }
164
165         // find default netname and colormod
166         switch(self.itemkeys) {
167         case 1:
168                 _netname = "GOLD key";
169                 _colormod = '1 .9 0';
170                 break;
171
172         case 2:
173                 _netname = "SILVER key";
174                 _colormod = '.9 .9 .9';
175                 break;
176
177         case 4:
178                 _netname = "BRONZE key";
179                 _colormod = '.6 .25 0';
180                 break;
181
182         case 8:
183                 _netname = "RED keycard";
184                 _colormod = '.9 0 0';
185                 break;
186
187         case 16:
188                 _netname = "BLUE keycard";
189                 _colormod = '0 0 .9';
190                 break;
191
192         case 32:
193                 _netname = "GREEN keycard";
194                 _colormod = '0 .9 0';
195                 break;
196
197         default:
198                 _netname = "FLUFFY PINK keycard";
199                 _colormod = '1 1 1';
200
201                 if (self.netname == "") {
202                         objerror("item_key doesn't have a default name for this key and a custom one was not specified!");
203                         remove(self);
204                         return;
205                 }
206                 break;
207
208         }
209
210         // find default model
211         string _model = string_null;
212         if (self.itemkeys <= ITEM_KEY_BIT(2)) {
213                 _model = "models/keys/key.md3";
214         } else if (self.itemkeys >= ITEM_KEY_BIT(3) && self.itemkeys <= ITEM_KEY_BIT(5)) {
215                 _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
216         } else if (self.model == "") {
217                 objerror("item_key doesn't have a default model for this key and a custom one was not specified!");
218                 remove(self);
219                 return;
220         }
221
222         // set defailt netname
223         if (self.netname == "")
224                 self.netname = _netname;
225
226         // set default colormod
227         if (!self.colormod)
228                 self.colormod = _colormod;
229
230         // set default model
231         if (self.model == "")
232                 self.model = _model;
233
234         // set default pickup message
235         if (self.message == "")
236                 self.message = strzone(strcat("You've picked up the ", self.netname, "!"));
237
238         if (self.noise == "")
239                 self.noise = SND(ITEMPICKUP);
240
241         // save the name for later
242         item_keys_names[lowestbit(self.itemkeys)] = self.netname;
243
244         // put the key on the map
245         spawn_item_key();
246 }
247
248 /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
249 SILVER key.
250 -----------KEYS------------
251 colormod: color of the key (default: '.9 .9 .9').
252 message: message to print when player picks up this key.
253 model: custom model to use.
254 noise: custom sound to play when player picks up the key.
255 -------- SPAWNFLAGS --------
256 FLOATING: the item will float in air, instead of aligning to the floor by falling
257 ---------NOTES----------
258 Don't use this entity on new maps! Use item_key instead.
259 */
260 spawnfunc(item_key1)
261 {
262         this.classname = "item_key";
263         this.itemkeys = ITEM_KEY_BIT(1);
264         spawnfunc_item_key(this);
265 };
266
267 /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
268 GOLD key.
269 -----------KEYS------------
270 colormod: color of the key (default: '1 .9 0').
271 message: message to print when player picks up this key.
272 model: custom model to use.
273 noise: custom sound to play when player picks up the key.
274 -------- SPAWNFLAGS --------
275 FLOATING: the item will float in air, instead of aligning to the floor by falling
276 ---------NOTES----------
277 Don't use this entity on new maps! Use item_key instead.
278 */
279 spawnfunc(item_key2)
280 {
281         this.classname = "item_key";
282         this.itemkeys = ITEM_KEY_BIT(0);
283         spawnfunc_item_key(this);
284 };