]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/trigger/keylock.qc
Merge branch 'master' into Mario/vaporizer_damage
[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         WriteInt24_t(MSG_ENTITY, self.itemkeys);
104         WriteByte(MSG_ENTITY, self.height);
105
106         trigger_common_write(true);
107
108         return true;
109 }
110
111 void trigger_keylock_link()
112 {
113         // uncomment to network keylocks
114         //Net_LinkEntity(self, false, 0, trigger_keylock_send);
115 }
116
117 /*QUAKED trigger_keylock (.0 .5 .8) ?
118 Keylock trigger.  Must target other entities.
119 This trigger will trigger target entities when all required keys are provided.
120 -------- KEYS --------
121 itemkeys: A bit field with key IDs that are needed to open this lock.
122 sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav (3 is default)
123 target: trigger all entities with this targetname when triggered and all keys have been given to it, then remove this trigger
124 target2: trigger all entities with this targetname when triggered without giving it all the required keys.
125 killtarget: remove all entities with this targetname when triggered with all the needed keys.
126 message: print this message to the player who activated the trigger when all needed keys have been given.
127 message2: print this message to the player who activated the trigger when not all of the needed keys have been given.
128 noise: sound to play when lock gets unlocked (default: see sounds)
129 noise1: sound to play when only some of the needed key were used but not all (default: misc/decreasevalue.wav)
130 noise2: sound to play when a key is missing (default: misc/talk.wav)
131 wait: prevent triggering again for this amount of time (default: 5) - applies to target2, target3, target4.
132 ---------NOTES----------
133 If spawned without any key specified in itemkeys, this trigger will display an error and remove itself.
134 message2 and noise2 will be resent to the player every 2 seconds while he is in the trigger zone.
135 */
136 void spawnfunc_trigger_keylock(void)
137 {
138         if(!self.itemkeys) { remove(self); return; }
139
140         // set unlocked message
141         if(self.message == "")
142                 self.message = "Unlocked!";
143
144         // set default unlock noise
145         if(self.noise == "")
146         {
147                 if(self.sounds == 1)
148                         self.noise = "misc/secret.wav";
149                 else if(self.sounds == 2)
150                         self.noise = "misc/talk.wav";
151                 else //if (self.sounds == 3) {
152                         self.noise = "misc/trigger1.wav";
153         }
154
155         // set default use key sound
156         if(self.noise1 == "")
157                 self.noise1 = "misc/decreasevalue.wav";
158
159         // set closed sourd
160         if(self.noise2 == "")
161                 self.noise2 = "misc/talk.wav";
162
163         // delay between triggering message2 and trigger2
164         if(!self.wait) { self.wait = 5; }
165
166         // precache sounds
167         precache_sound(self.noise);
168         precache_sound(self.noise1);
169         precache_sound(self.noise2);
170
171         EXACTTRIGGER_INIT;
172
173         self.touch = trigger_keylock_touch;
174
175         trigger_keylock_link();
176 }
177 #elif defined(CSQC)
178 void keylock_remove()
179 {
180         if(self.target) { strunzone(self.target); }
181         self.target = string_null;
182
183         if(self.target2) { strunzone(self.target2); }
184         self.target2 = string_null;
185
186         if(self.target3) { strunzone(self.target3); }
187         self.target3 = string_null;
188
189         if(self.target4) { strunzone(self.target4); }
190         self.target4 = string_null;
191
192         if(self.killtarget) { strunzone(self.killtarget); }
193         self.killtarget = string_null;
194
195         if(self.targetname) { strunzone(self.targetname); }
196         self.targetname = string_null;
197 }
198
199 void ent_keylock()
200 {
201         self.itemkeys = ReadInt24_t();
202         self.height = ReadByte();
203
204         trigger_common_read(true);
205
206         self.classname = "trigger_keylock";
207         self.drawmask = MASK_NORMAL;
208         self.draw = trigger_draw_generic;
209         self.trigger_touch = trigger_keylock_touch;
210         self.entremove = keylock_remove;
211 }
212 #endif