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