133397876857999c1eecad47467b8a09fa86e8e1
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / trigger / keylock.qc
1 /**
2  * trigger given targets
3  */
4 void trigger_keylock_trigger(entity this, entity actor, string s)
5 {
6         for(entity t = NULL; (t = find(t, targetname, s)); )
7                 if(t.use)
8                         t.use(t, actor, this);
9 }
10
11 /**
12  * kill killtarget of trigger keylock.
13  */
14 void trigger_keylock_kill(string s)
15 {
16         entity t;
17         for(t = NULL; (t = find(t, targetname, s)); )
18                 remove(t);
19 }
20
21 void trigger_keylock_touch(entity this)
22 {
23         bool key_used = false;
24         bool started_delay = false;
25
26         // only player may trigger the lock
27         if(!IS_PLAYER(other))
28                 return;
29
30         // check silver key
31         if(this.itemkeys)
32                 key_used = item_keys_usekey(this, other);
33
34         if(this.itemkeys)
35         {
36 #ifdef SVQC
37                 // at least one of the keys is missing
38                 if(key_used)
39                 {
40                         // one or more keys were given, but others are still missing!
41                         play2(other, this.noise1);
42                         Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(this.itemkeys));
43                         other.key_door_messagetime = time + 2;
44                 }
45                 else if(other.key_door_messagetime <= time)
46                 {
47                         // no keys were given
48                         play2(other, this.noise2);
49                         Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(this.itemkeys));
50                         other.key_door_messagetime = time + 2;
51                 }
52 #endif
53
54                 // trigger target2
55                 if(this.delay <= time || started_delay == true)
56                 if(this.target2)
57                 {
58                         trigger_keylock_trigger(this, other, this.target2);
59                         started_delay = true;
60                         this.delay = time + this.wait;
61                 }
62         }
63         else
64         {
65 #ifdef SVQC
66                 // all keys were given!
67                 play2(other, this.noise);
68                 centerprint(other, this.message);
69 #endif
70
71                 if(this.target)
72                         trigger_keylock_trigger(this, other, this.target);
73
74                 if(this.killtarget)
75                         trigger_keylock_kill(this.killtarget);
76
77                 remove(this);
78         }
79
80 }
81
82 REGISTER_NET_LINKED(ENT_CLIENT_KEYLOCK)
83
84 #ifdef SVQC
85 bool trigger_keylock_send(entity this, entity to, int sf)
86 {
87         WriteHeader(MSG_ENTITY, ENT_CLIENT_KEYLOCK);
88
89         WriteInt24_t(MSG_ENTITY, this.itemkeys);
90         WriteByte(MSG_ENTITY, this.height);
91
92         trigger_common_write(this, true);
93
94         return true;
95 }
96
97 void trigger_keylock_link(entity this)
98 {
99         // uncomment to network keylocks
100         //Net_LinkEntity(this, false, 0, trigger_keylock_send);
101 }
102
103 /*QUAKED trigger_keylock (.0 .5 .8) ?
104 Keylock trigger.  Must target other entities.
105 This trigger will trigger target entities when all required keys are provided.
106 -------- KEYS --------
107 itemkeys: A bit field with key IDs that are needed to open this lock.
108 sounds: 1 to play misc/secret.wav, 2 to play misc/talk.wav, 3 to play misc/trigger1.wav (3 is default)
109 target: trigger all entities with this targetname when triggered and all keys have been given to it, then remove this trigger
110 target2: trigger all entities with this targetname when triggered without giving it all the required keys.
111 killtarget: remove all entities with this targetname when triggered with all the needed keys.
112 message: print this message to the player who activated the trigger when all needed keys have been given.
113 message2: print this message to the player who activated the trigger when not all of the needed keys have been given.
114 noise: sound to play when lock gets unlocked (default: see sounds)
115 noise1: sound to play when only some of the needed key were used but not all (default: misc/decreasevalue.wav)
116 noise2: sound to play when a key is missing (default: misc/talk.wav)
117 wait: prevent triggering again for this amount of time (default: 5) - applies to target2, target3, target4.
118 ---------NOTES----------
119 If spawned without any key specified in itemkeys, this trigger will display an error and remove itself.
120 message2 and noise2 will be resent to the player every 2 seconds while he is in the trigger zone.
121 */
122 spawnfunc(trigger_keylock)
123 {
124         if(!this.itemkeys) { remove(this); return; }
125
126         // set unlocked message
127         if(this.message == "")
128                 this.message = "Unlocked!";
129
130         // set default unlock noise
131         if(this.noise == "")
132         {
133                 if(this.sounds == 1)
134                         this.noise = "misc/secret.wav";
135                 else if(this.sounds == 2)
136                         this.noise = strzone(SND(TALK));
137                 else //if (this.sounds == 3) {
138                         this.noise = "misc/trigger1.wav";
139         }
140
141         // set default use key sound
142         if(this.noise1 == "")
143                 this.noise1 = "misc/decreasevalue.wav";
144
145         // set closed sourd
146         if(this.noise2 == "")
147                 this.noise2 = SND(TALK);
148
149         // delay between triggering message2 and trigger2
150         if(!this.wait) { this.wait = 5; }
151
152         // precache sounds
153         precache_sound(this.noise);
154         precache_sound(this.noise1);
155         precache_sound(this.noise2);
156
157         EXACTTRIGGER_INIT;
158
159         settouch(this, trigger_keylock_touch);
160
161         trigger_keylock_link(this);
162 }
163 #elif defined(CSQC)
164 void keylock_remove(entity this)
165 {
166         if(this.target) { strunzone(this.target); }
167         this.target = string_null;
168
169         if(this.target2) { strunzone(this.target2); }
170         this.target2 = string_null;
171
172         if(this.target3) { strunzone(this.target3); }
173         this.target3 = string_null;
174
175         if(this.target4) { strunzone(this.target4); }
176         this.target4 = string_null;
177
178         if(this.killtarget) { strunzone(this.killtarget); }
179         this.killtarget = string_null;
180
181         if(this.targetname) { strunzone(this.targetname); }
182         this.targetname = string_null;
183 }
184
185 NET_HANDLE(ENT_CLIENT_KEYLOCK, bool isnew)
186 {
187         this.itemkeys = ReadInt24_t();
188         this.height = ReadByte();
189
190         trigger_common_read(this, true);
191
192         return = true;
193
194         this.classname = "trigger_keylock";
195         this.entremove = keylock_remove;
196 }
197 #endif