-
Notifications
You must be signed in to change notification settings - Fork 1
/
keylock.qc
236 lines (185 loc) · 5.58 KB
/
keylock.qc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
========================================================================
COMMON CODE FOR ENTITIES WHICH CAN BE UNLOCKED WITH KEYS
========================================================================
This file was created for progs_dump by Ian "iw" Walshaw, December 2019.
It defines functions which implement the logic of the player using a key
to unlock a locked entity. These functions are based on parts of the
func_door code from the original game.
In the original game, func_door was the only type of entity which could
be unlocked with a key, however progs_dump also has trigger_usekey,
which previously duplicated the same unlocking logic as func_door. The
functions in this file were written to eliminate that duplication;
func_door and trigger_usekey have now both been refactored to call these
functions.
This file was created as part of the prep work for implementing
item_key_custom, with the intention of removing as much duplication as
possible in order to make the code easier to modify and extend.
Fields Set By These Functions
-----------------------------
The functions in this file set the following fields, therefore code
calling these functions must not use these fields for other purposes:
- self.customkeys
- self.items
- self.netname
- self.noise3
- self.noise4
========================================================================
*/
/*
================
keylock_init
Initialize self for use with the other keylock_* functions.
The following fields will be set to default values if they have not
already been set:
- self.noise3 (the "key required" sound file).
- self.noise4 (the "key used" sound file).
The default values are determined by world.worldtype. -- iw
================
*/
void() keylock_init =
{
local string default_noise3;
local string default_noise4;
if (world.worldtype == WORLDTYPE_BASE)
{
default_noise3 = "doors/basetry.wav";
default_noise4 = "doors/baseuse.wav";
}
else if (world.worldtype == WORLDTYPE_METAL)
{
default_noise3 = "doors/runetry.wav";
default_noise4 = "doors/runeuse.wav";
}
else
{
default_noise3 = "doors/medtry.wav";
default_noise4 = "doors/meduse.wav";
}
if (self.noise3 == "")
self.noise3 = default_noise3;
if (self.noise4 == "")
self.noise4 = default_noise4;
precache_sound (self.noise3);
precache_sound (self.noise4);
};
/*
================
keylock_set_silver_key
Make it so that the player will need to use the silver key in order to
unlock self. -- iw
================
*/
void() keylock_set_silver_key =
{
self.items = IT_KEY1;
self.customkeys = 0; // support for item_key_custom -- iw
self.netname = SilverKeyName ();
};
/*
================
keylock_set_gold_key
Make it so that the player will need to use the gold key in order to
unlock self. -- iw
================
*/
void() keylock_set_gold_key =
{
self.items = IT_KEY2;
self.customkeys = 0; // support for item_key_custom -- iw
self.netname = GoldKeyName ();
};
// support for item_key_custom -- iw
/*
================
keylock_set_custom_key
Make it so that the player will need to use the custom key named
key_name in order to unlock self. -- iw
================
*/
void(string key_name) keylock_set_custom_key =
{
self.items = 0;
self.customkeys = CustomKeyFlag (key_name);
self.netname = key_name;
};
/*
================
keylock_has_key_set
Return TRUE if one of the keylock_set_*_key functions has been called
for self, otherwise return FALSE. -- iw
================
*/
float() keylock_has_key_set =
{
// support for item_key_custom -- iw
return self.items != 0 || self.customkeys != 0;
};
/*
================
keylock_try_to_unlock
Handle the logic of the specified client trying to unlock self.
More specifically, if the client has the correct key to unlock self,
then do the following:
1. Remove the key from the client's inventory, unless self.cnt is
non-zero, in which case leave it in the client's inventory.
2. Print a message to let the player know which key they used.
3. Play the "key used" sound effect (self.noise4).
4. Call the function specified as the success_func parameter, which
should perform whatever entity-specific actions are required for
self.
Otherwise, if the client does not have the correct key to unlock self,
then do the following:
1. Centerprint the message "You need the [key name]", unless the
custom_message parameter is non-empty, in which case centerprint
that instead.
2. Play the "key required" sound effect (self.noise3).
The self.cnt functionality is a feature of progs_dump and was not part
of the original game. -- iw
================
*/
void(entity client, string failure_message, string success_message,
void() success_func, void() failure_func) keylock_try_to_unlock =
{
local string s = "";
// support for item_key_custom -- iw
if (!HasKeys (client, self.items, self.customkeys))
{
if (client.flags & FL_CLIENT)
{
if (failure_message != "")
centerprint (client, failure_message);
else
centerprint2 (client, "You need the ", self.netname);
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
failure_func();
return;
}
if (self.cnt)
{
s = "You used (and kept) the ";
}
else
{
// support for item_key_custom -- iw
RemoveKeys (client, self.items, self.customkeys);
s = "You used the ";
}
if (client.flags & FL_CLIENT)
{
if (success_message != "")
{
sprint (client, success_message);
sprint (client, "\n");
}
else
{
sprint (client, s);
sprint (client, self.netname);
sprint (client, "\n");
}
}
sound (self, CHAN_ITEM, self.noise4, 1, ATTN_NORM);
success_func ();
};