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