00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <global.h>
00035 #ifndef __CEXTRACT__
00036 #include <sproto.h>
00037 #endif
00038 #include <spells.h>
00039 #include <skills.h>
00040 #include <newclient.h>
00041 #include <commands.h>
00042
00053 int command_invoke(object *op, char *params) {
00054 return command_cast_spell(op, params, 'i');
00055 }
00056
00067 int command_cast(object *op, char *params) {
00068 return command_cast_spell(op, params, 'c');
00069 }
00070
00082 int command_prepare(object *op, char *params) {
00083 return command_cast_spell(op, params, 'p');
00084 }
00085
00097 static void show_matching_spells(object *op, char *params) {
00098 object *spell;
00099 char spell_sort[NROFREALSPELLS][MAX_BUF], tmp[MAX_BUF], *cp;
00100 int num_found = 0, i;
00101
00102
00103
00104
00105
00106
00107 for (spell = op->inv; spell != NULL; spell = spell->below) {
00108
00109
00110
00111 if (spell->type == SPELL
00112 && (!params || !strncmp(params, spell->name, strlen(params)))) {
00113 if (spell->path_attuned&op->path_denied) {
00114 snprintf(spell_sort[num_found++], sizeof(spell_sort[0]),
00115 "%s:%-22s %3s %3s", spell->skill ? spell->skill : "generic",
00116 spell->name, "den", "den");
00117 } else {
00118 snprintf(spell_sort[num_found++], sizeof(spell_sort[0]),
00119 "%s:%-22s %3d %3d", spell->skill ? spell->skill : "generic",
00120 spell->name, spell->level,
00121 SP_level_spellpoint_cost(op, spell, SPELL_HIGHEST));
00122 }
00123 }
00124 }
00125 if (!num_found) {
00126
00127
00128
00129
00130
00131 if (params)
00132 show_matching_spells(op, NULL);
00133 else
00134 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00135 "You know no spells", NULL);
00136 } else {
00137
00138
00139
00140
00141
00142 qsort(spell_sort, num_found, MAX_BUF, (int (*)(const void *, const void *))strcmp);
00143 strcpy(tmp, "asdfg");
00144 for (i = 0; i < num_found; i++) {
00145
00146 if (strncmp(tmp, spell_sort[i], strlen(tmp))) {
00147 strcpy(tmp, spell_sort[i]);
00148 cp = strchr(tmp, ':');
00149 *cp = '\0';
00150
00151 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00152 "\n[fixed]%s spells %.*s <lvl> <sp>",
00153 "\n%s spells %.*s <lvl> <sp>",
00154 tmp, 12-strlen(tmp), " ");
00155 }
00156 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00157 "[fixed]%s",
00158 "%s",
00159 strchr(spell_sort[i], ':')+1);
00160 }
00161 }
00162 }
00163
00178 int command_cast_spell(object *op, char *params, char command) {
00179 int castnow = 0;
00180 char *cp;
00181 object *spob;
00182
00183 if (command == 'i')
00184 castnow = 1;
00185
00186 if (params != NULL) {
00187 tag_t spellnumber = 0;
00188 if ((spellnumber = atoi(params)) != 0)
00189 for (spob = op->inv; spob && spob->count != spellnumber; spob = spob->below)
00190 ;
00191 else
00192 spob = lookup_spell_by_name(op, params);
00193
00194 if (spob && spob->type == SPELL) {
00195
00196
00197
00198 if (spellnumber) {
00199
00200 cp = strchr(params, ' ');
00201 if (cp) {
00202 cp++;
00203 if (!strncmp(cp, "of ", 3))
00204 cp += 3;
00205 }
00206 } else if (strlen(params) > strlen(spob->name)) {
00207 cp = params+strlen(spob->name);
00208 *cp = 0;
00209 cp++;
00210 if (!strncmp(cp, "of ", 3))
00211 cp += 3;
00212 } else
00213 cp = NULL;
00214
00215 if (spob->skill && !find_skill_by_name(op, spob->skill)) {
00216 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING,
00217 "You need the skill %s to cast %s!",
00218 "You need the skill %s to cast %s!",
00219 spob->skill, spob->name);
00220 return 1;
00221 }
00222
00223
00224 if (op->contr->ranges[range_golem] != NULL) {
00225 if (op->contr->golem_count == op->contr->ranges[range_golem]->count) {
00226 remove_friendly_object(op->contr->ranges[range_golem]);
00227 remove_ob(op->contr->ranges[range_golem]);
00228 free_object(op->contr->ranges[range_golem]);
00229 }
00230 op->contr->ranges[range_golem] = NULL;
00231 op->contr->golem_count = 0;
00232 }
00233
00234 if (castnow) {
00235 cast_spell(op, op, op->facing, spob, cp);
00236 } else {
00237 op->contr->ranges[range_magic] = spob;
00238 op->contr->shoottype = range_magic;
00239 if (cp != NULL) {
00240 strncpy(op->contr->spellparam, cp, MAX_BUF);
00241 op->contr->spellparam[MAX_BUF-1] = '\0';
00242 } else {
00243 op->contr->spellparam[0] = '\0';
00244 }
00245 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00246 "You ready the spell %s",
00247 "You ready the spell %s",
00248 spob->name);
00249 }
00250 return 0;
00251 }
00252 }
00253
00254
00255
00256
00257 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00258 "Cast what spell? Choose one of:", NULL);
00259 show_matching_spells(op, params);
00260 return 1;
00261 }
00262
00263
00264
00282 int legal_range(object *op, int r) {
00283
00284 switch (r) {
00285 case range_none:
00286 return 1;
00287
00288 case range_bow:
00289 case range_misc:
00290 case range_magic:
00291 if (op->contr->ranges[r])
00292 return 1;
00293 else
00294 return 0;
00295
00296 case range_golem:
00297 if (op->contr->ranges[range_golem]
00298 && op->contr->ranges[range_golem]->count == op->contr->golem_count)
00299 return 1;
00300 else
00301 return 0;
00302
00303 case range_skill:
00304 if (op->chosen_skill)
00305 return 1;
00306 else
00307 return 0;
00308 }
00309
00310 return 0;
00311 }
00312
00321 void change_spell(object *op, char k) {
00322
00323 char name[MAX_BUF];
00324
00325 do {
00326 op->contr->shoottype += ((k == '+') ? 1 : -1);
00327 if (op->contr->shoottype >= range_size)
00328 op->contr->shoottype = range_none;
00329 else if (op->contr->shoottype <= range_bottom)
00330 op->contr->shoottype = (rangetype)(range_size-1);
00331 } while (!legal_range(op, op->contr->shoottype));
00332
00333
00334
00335
00336
00337 switch (op->contr->shoottype) {
00338 case range_none:
00339 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00340 "No ranged attack chosen.", NULL);
00341 break;
00342
00343 case range_golem:
00344 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00345 "You regain control of your golem.", NULL);
00346 break;
00347
00348 case range_bow:
00349 query_name(op->contr->ranges[range_bow], name, MAX_BUF);
00350 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00351 "Switched to %s and %s.",
00352 "Switched to %s and %s.",
00353 name,
00354 op->contr->ranges[range_bow]->race ? op->contr->ranges[range_bow]->race : "nothing");
00355 break;
00356
00357 case range_magic:
00358 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00359 "Switched to spells (%s).",
00360 "Switched to spells (%s).",
00361 op->contr->ranges[range_magic]->name);
00362 break;
00363
00364 case range_misc:
00365 query_base_name(op->contr->ranges[range_misc], 0, name, MAX_BUF);
00366 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00367 "Switched to %s.",
00368 "Switched to %s.",
00369 name);
00370 break;
00371
00372 case range_skill:
00373 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00374 "Switched to skill: %s",
00375 "Switched to skill: %s",
00376 op->chosen_skill ? op->chosen_skill->name : "none");
00377 break;
00378
00379 default:
00380 break;
00381 }
00382 }
00383
00394 int command_rotateshoottype(object *op, char *params) {
00395 if (!params)
00396 change_spell(op, '+');
00397 else
00398 change_spell(op, params[0]);
00399 return 0;
00400 }