]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/trigger/keylock.qc
A few trillion lines of untested junk, committing now so it doesn't become quadrillions
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / trigger / keylock.qc
1 /**
2  * trigger given targets
3  */
4 void trigger_keylock_trigger(string s)
5 {
6         entity stemp = self;
7         entity otemp = other;
8         entity atemp = activator;
9
10         entity t;
11         for(t = world; (t = find(t, targetname, s)); )
12                 if(t.use)
13                 {
14                         self = t;
15                         other = stemp;
16                         activator = atemp;
17                         self.use();
18                 }
19
20         self = stemp;
21         other = otemp;
22         activator = atemp;
23 }
24
25 /**
26  * kill killtarget of trigger keylock.
27  */
28 void trigger_keylock_kill(string s)
29 {
30         entity t;
31         for(t = world; (t = find(t, targetname, s)); )
32                 remove(t);
33 }
34
35 void trigger_keylock_touch()
36 {
37         bool key_used = false;
38         bool started_delay = false;
39
40         // only player may trigger the lock
41         if(!IS_PLAYER(other))
42                 return;
43
44         // check silver key
45         if(self.itemkeys)
46                 key_used = item_keys_usekey(self, other);
47
48         activator = other;
49
50         if(self.itemkeys)
51         {
52 #ifdef SVQC
53                 // at least one of the keys is missing
54                 if(key_used)
55                 {
56                         // one or more keys were given, but others are still missing!
57                         play2(other, self.noise1);
58                         Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(self.itemkeys));
59                         other.key_door_messagetime = time + 2;
60                 }
61                 else if(other.key_door_messagetime <= time)
62                 {
63                         // no keys were given
64                         play2(other, self.noise2);
65                         Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(self.itemkeys));
66                         other.key_door_messagetime = time + 2;
67                 }
68 #endif
69
70                 // trigger target2
71                 if(self.delay <= time || started_delay == true)
72                 if(self.target2)
73                 {
74                         trigger_keylock_trigger(self.target2);
75                         started_delay = true;
76                         self.delay = time + self.wait;
77                 }
78         }
79         else
80         {
81 #ifdef SVQC
82                 // all keys were given!
83                 play2(other, self.noise);
84                 centerprint(other, self.message);
85 #endif
86
87                 if(self.target)
88                         trigger_keylock_trigger(self.target);
89
90                 if(self.killtarget)
91                         trigger_keylock_kill(self.killtarget);
92
93                 remove(self);
94         }
95
96 }
97
98 #ifdef SVQC
99 bool trigger_keylock_send(entity to, int sf)
100 {
101         WriteByte(MSG_ENTITY, ENT_CLIENT_KEYLOCK);
102
103         WriteString(MSG_ENTITY, self.target);
104         WriteString(MSG_ENTITY, self.target2);
105         WriteString(MSG_ENTITY, self.target3);
106         WriteString(MSG_ENTITY, self.target4);
107         WriteString(MSG_ENTITY, self.killtarget);
108         WriteString(MSG_ENTITY, self.targetname);
109
110         WriteInt24_t(MSG_ENTITY, self.itemkeys);
111         WriteByte(MSG_ENTITY, self.warpzone_isboxy);
112         WriteByte(MSG_ENTITY, self.height);
113         WriteByte(MSG_ENTITY, self.scale);
114
115         WriteCoord(MSG_ENTITY, self.origin_x);
116         WriteCoord(MSG_ENTITY, self.origin_y);
117         WriteCoord(MSG_ENTITY, self.origin_z);
118
119         WriteCoord(MSG_ENTITY, self.mins_x);
120         WriteCoord(MSG_ENTITY, self.mins_y);
121         WriteCoord(MSG_ENTITY, self.mins_z);
122         WriteCoord(MSG_ENTITY, self.maxs_x);
123         WriteCoord(MSG_ENTITY, self.maxs_y);
124         WriteCoord(MSG_ENTITY, self.maxs_z);
125
126         WriteCoord(MSG_ENTITY, self.movedir_x);
127         WriteCoord(MSG_ENTITY, self.movedir_y);
128         WriteCoord(MSG_ENTITY, self.movedir_z);
129
130         return true;
131 }
132
133 void trigger_keylock_link()
134 {
135         // uncomment to network keylocks
136         //Net_LinkEntity(self, false, 0, trigger_keylock_send);
137 }
138
139 /*QUAKED trigger_keylock (.0 .5 .8) ?
140 Keylock trigger.  Must target other entities.
141 This trigger will trigger target entities when all required keys are provided.
142 -------- KEYS --------
143 itemkeys: A bit field with key IDs that are needed to open this lock.
144 sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav (3 is default)
145 target: trigger all entities with this targetname when triggered and all keys have been given to it, then remove this trigger
146 target2: trigger all entities with this targetname when triggered without giving it all the required keys.
147 killtarget: remove all entities with this targetname when triggered with all the needed keys.
148 message: print this message to the player who activated the trigger when all needed keys have been given.
149 message2: print this message to the player who activated the trigger when not all of the needed keys have been given.
150 noise: sound to play when lock gets unlocked (default: see sounds)
151 noise1: sound to play when only some of the needed key were used but not all (default: misc/decreasevalue.wav)
152 noise2: sound to play when a key is missing (default: misc/talk.wav)
153 wait: prevent triggering again for this amount of time (default: 5) - applies to target2, target3, target4.
154 ---------NOTES----------
155 If spawned without any key specified in itemkeys, this trigger will display an error and remove itself.
156 message2 and noise2 will be resent to the player every 2 seconds while he is in the trigger zone.
157 */
158 void spawnfunc_trigger_keylock(void)
159 {
160         if(!self.itemkeys) { remove(self); return; }
161
162         // set unlocked message
163         if(self.message == "")
164                 self.message = "Unlocked!";
165
166         // set default unlock noise
167         if(self.noise == "")
168         {
169                 if(self.sounds == 1)
170                         self.noise = "misc/secret.wav";
171                 else if(self.sounds == 2)
172                         self.noise = "misc/talk.wav";
173                 else //if (self.sounds == 3) {
174                         self.noise = "misc/trigger1.wav";
175         }
176
177         // set default use key sound
178         if(self.noise1 == "")
179                 self.noise1 = "misc/decreasevalue.wav";
180
181         // set closed sourd
182         if(self.noise2 == "")
183                 self.noise2 = "misc/talk.wav";
184
185         // delay between triggering message2 and trigger2
186         if(!self.wait) { self.wait = 5; }
187
188         // precache sounds
189         precache_sound(self.noise);
190         precache_sound(self.noise1);
191         precache_sound(self.noise2);
192
193         EXACTTRIGGER_INIT;
194
195         self.touch = trigger_keylock_touch;
196
197         trigger_keylock_link();
198 }
199 #elif defined(CSQC)
200 void keylock_remove()
201 {
202         if(self.target) { strunzone(self.target); }
203         self.target = string_null;
204
205         if(self.target2) { strunzone(self.target2); }
206         self.target2 = string_null;
207
208         if(self.target3) { strunzone(self.target3); }
209         self.target3 = string_null;
210
211         if(self.target4) { strunzone(self.target4); }
212         self.target4 = string_null;
213
214         if(self.killtarget) { strunzone(self.killtarget); }
215         self.killtarget = string_null;
216
217         if(self.targetname) { strunzone(self.targetname); }
218         self.targetname = string_null;
219 }
220
221 void ent_keylock()
222 {
223         self.target = strzone(ReadString());
224         self.target2 = strzone(ReadString());
225         self.target3 = strzone(ReadString());
226         self.target4 = strzone(ReadString());
227         self.killtarget = strzone(ReadString());
228         self.targetname = strzone(ReadString());
229
230         self.itemkeys = ReadInt24_t();
231         self.warpzone_isboxy = ReadByte();
232         self.height = ReadByte();
233         self.scale = ReadByte();
234
235         self.origin_x = ReadCoord();
236         self.origin_y = ReadCoord();
237         self.origin_z = ReadCoord();
238
239         self.mins_x = ReadCoord();
240         self.mins_y = ReadCoord();
241         self.mins_z = ReadCoord();
242         self.maxs_x = ReadCoord();
243         self.maxs_y = ReadCoord();
244         self.maxs_z = ReadCoord();
245
246         self.movedir_x = ReadCoord();
247         self.movedir_y = ReadCoord();
248         self.movedir_z = ReadCoord();
249
250         self.classname = "trigger_keylock";
251         self.drawmask = MASK_NORMAL;
252         self.draw = trigger_draw_generic;
253         self.trigger_touch = trigger_keylock_touch;
254         self.entremove = keylock_remove;
255 }
256 #endif