… | |
… | |
151 | * if not successful, return null. If they do have the skill tool |
151 | * if not successful, return null. If they do have the skill tool |
152 | * but not the skill itself, give it to them. |
152 | * but not the skill itself, give it to them. |
153 | */ |
153 | */ |
154 | if (skill_tool) |
154 | if (skill_tool) |
155 | { |
155 | { |
156 | if (!QUERY_FLAG (skill_tool, FLAG_APPLIED)) |
|
|
157 | if (apply_special (who, skill_tool, 0)) |
|
|
158 | return 0; |
|
|
159 | |
|
|
160 | if (!skill) |
156 | if (!skill) |
161 | { |
157 | { |
162 | skill = give_skill_by_name (who, skill_tool->skill); |
158 | skill = give_skill_by_name (who, skill_tool->skill); |
163 | link_player_skills (who); |
159 | link_player_skills (who); |
164 | } |
160 | } |
165 | |
161 | |
|
|
162 | if (!QUERY_FLAG (skill_tool, FLAG_APPLIED)) |
|
|
163 | if (apply_special (who, skill_tool, 0)) |
|
|
164 | return 0; |
|
|
165 | |
166 | return skill; |
166 | return skill; |
167 | } |
167 | } |
168 | |
168 | |
169 | return 0; |
169 | return 0; |
170 | } |
170 | } |
171 | |
171 | |
|
|
172 | static object * |
|
|
173 | find_skill (object *who, const shstr &sh) |
|
|
174 | { |
|
|
175 | for (object *tmp = who->inv; tmp; tmp = tmp->below) |
|
|
176 | if (tmp->skill == sh && tmp->type == SKILL) |
|
|
177 | return tmp; |
|
|
178 | |
|
|
179 | return 0; |
|
|
180 | } |
|
|
181 | |
|
|
182 | // like the other function above, but for exact matches using a shstr |
|
|
183 | // which is very common inside the server. unlike the above function, |
|
|
184 | // we always return the skill. |
|
|
185 | object * |
|
|
186 | find_skill_by_name (object *who, const shstr &sh) |
|
|
187 | { |
|
|
188 | object *skill_tool = 0; |
|
|
189 | |
|
|
190 | for (object *tmp = who->inv; tmp; tmp = tmp->below) |
|
|
191 | if (tmp->skill == sh) |
|
|
192 | { |
|
|
193 | if (tmp->type == SKILL && (tmp->flag [FLAG_CAN_USE_SKILL] || tmp->flag [FLAG_APPLIED])) |
|
|
194 | /* If this is a skill that can be used without applying tool, return it */ |
|
|
195 | return tmp->inv_splay (); |
|
|
196 | /* Try to find appropriate skilltool. If the player has one already |
|
|
197 | * applied, we try to keep using that one. |
|
|
198 | */ |
|
|
199 | else if (tmp->type == SKILL_TOOL && !skill_tool) |
|
|
200 | skill_tool = tmp; |
|
|
201 | } |
|
|
202 | |
|
|
203 | if (!skill_tool) |
|
|
204 | return 0; |
|
|
205 | |
|
|
206 | /* Player has a tool to use the skill. If not applied, apply it - |
|
|
207 | * if not successful, return null. If they do have the skill tool |
|
|
208 | * but not the skill itself, give it to them. |
|
|
209 | */ |
|
|
210 | object *skill = find_skill (who, skill_tool->skill); |
|
|
211 | |
|
|
212 | if (!skill) |
|
|
213 | { |
|
|
214 | skill = give_skill_by_name (who, skill_tool->skill); |
|
|
215 | link_player_skills (who); |
|
|
216 | } |
|
|
217 | |
|
|
218 | skill->inv_splay (); |
|
|
219 | |
|
|
220 | if (!skill_tool->flag [FLAG_APPLIED]) |
|
|
221 | if (apply_special (who, skill_tool, AP_APPLY)) |
|
|
222 | return 0; |
|
|
223 | |
|
|
224 | return skill; |
|
|
225 | } |
|
|
226 | |
172 | /* This returns the skill pointer of the given name (the |
227 | /* This returns the skill pointer of the given name (the |
173 | * one that accumlates exp, has the level, etc). |
228 | * one that accumulates exp, has the level, etc). |
174 | * |
229 | * |
175 | * It is presumed that the player will be needing to actually |
230 | * It is presumed that the player will be needing to actually |
176 | * use the skill, so thus if use of the skill requires a skill |
231 | * use the skill, so thus if use of the skill requires a skill |
177 | * tool, this code will equip it. |
232 | * tool, this code will equip it. |
178 | * |
233 | * |
… | |
… | |
194 | skill = tmp; |
249 | skill = tmp; |
195 | |
250 | |
196 | /* Try to find appropriate skilltool. If the player has one already |
251 | /* Try to find appropriate skilltool. If the player has one already |
197 | * applied, we try to keep using that one. |
252 | * applied, we try to keep using that one. |
198 | */ |
253 | */ |
|
|
254 | //TODO: afaics, skill tools have subtype 0 always |
199 | else if (tmp->type == SKILL_TOOL && tmp->subtype == skillno) |
255 | else if (tmp->type == SKILL_TOOL && tmp->subtype == skillno) |
200 | { |
256 | { |
201 | if (QUERY_FLAG (tmp, FLAG_APPLIED)) |
257 | if (QUERY_FLAG (tmp, FLAG_APPLIED)) |
202 | skill_tool = tmp; |
258 | skill_tool = tmp; |
203 | else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED)) |
259 | else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED)) |
… | |
… | |
276 | clear_skill (object *who) |
332 | clear_skill (object *who) |
277 | { |
333 | { |
278 | who->chosen_skill = 0; |
334 | who->chosen_skill = 0; |
279 | CLEAR_FLAG (who, FLAG_READY_SKILL); |
335 | CLEAR_FLAG (who, FLAG_READY_SKILL); |
280 | |
336 | |
281 | if (who->type == PLAYER) |
337 | if (player *pl = who->contr) |
282 | if (who->contr->ranged_ob && who->contr->ranged_ob->type == SKILL) |
338 | if (pl->ranged_ob && pl->ranged_ob->type == SKILL) |
283 | who->contr->ranged_ob = 0; |
339 | pl->ranged_ob = 0; |
284 | } |
340 | } |
285 | |
341 | |
286 | /* do_skill() - Main skills use function-similar in scope to cast_spell(). |
342 | /* do_skill() - Main skills use function-similar in scope to cast_spell(). |
287 | * We handle all requests for skill use outside of some combat here. |
343 | * We handle all requests for skill use outside of some combat here. |
288 | * We require a separate routine outside of fire() so as to allow monsters |
344 | * We require a separate routine outside of fire() so as to allow monsters |