Code:
ACMD(do_cast)
{
struct char_data *tch = NULL;
struct obj_data *tobj = NULL;
char *s, *t;
int number, mana, spellnum, i, target = 0;
if (IS_NPC(ch))
return;
/* get: blank, spell name, target name */
s = strtok(argument, "'");
if (s == NULL) {
send_to_char(ch, "%s what where?\r\n", (SCMD_SING ? "Sing" : "Cast"));
return;
}
if (subcmd == SCMD_SING && GET_CLASS(ch) != CLASS_BARD) {
send_to_char(ch, "Only Bard's can entertain with song's..\r\n");
return;
}
if (subcmd == SCMD_CAST && GET_CLASS(ch) == CLASS_BARD) {
send_to_char(ch, "You fantasize about being able to cast magic..\r\n");
return;
}
s = strtok(NULL, "'");
if (s == NULL) {
send_to_char(ch, "Spell names must be enclosed in the Holy Magic Symbols: '\r\n");
return;
}
t = strtok(NULL, "\0");
skip_spaces(&s);
/* spellnum = search_block(s, spells, 0); */
spellnum = find_skill_num(s);
if ((spellnum < 1) || (spellnum > MAX_SPELLS) || !*s) {
send_to_char(ch, "Cast what?!?\r\n");
return;
}
if (GET_LEVEL(ch) < SINFO.min_level[(int) GET_CLASS(ch)]) {
send_to_char(ch, "You do not know that spell!\r\n");
return;
}
if (GET_SKILL(ch, spellnum) == 0) {
send_to_char(ch, "You are unfamiliar with that spell.\r\n");
return;
}
/* Find the target */
if (t != NULL) {
char arg[MAX_INPUT_LENGTH];
strlcpy(arg, t, sizeof(arg));
one_argument(arg, t);
skip_spaces(&t);
/* Copy target to global cast_arg2, for use in spells like locate object */
strcpy(cast_arg2, t);
}
if (IS_SET(SINFO.targets, TAR_IGNORE)) {
target = TRUE;
} else if (t != NULL && *t) {
number = get_number(&t);
if (!target && (IS_SET(SINFO.targets, TAR_CHAR_ROOM))) {
if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_ROOM)) != NULL)
target = TRUE;
}
if (!target && IS_SET(SINFO.targets, TAR_CHAR_WORLD))
if ((tch = get_char_vis(ch, t, &number, FIND_CHAR_WORLD)) != NULL)
target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_INV))
if ((tobj = get_obj_in_list_vis(ch, t, &number, ch->carrying)) != NULL)
target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_EQUIP)) {
for (i = 0; !target && i < NUM_WEARS; i++)
if (GET_EQ(ch, i) && isname(t, GET_EQ(ch, i)->name)) {
tobj = GET_EQ(ch, i);
target = TRUE;
}
}
if (!target && IS_SET(SINFO.targets, TAR_OBJ_ROOM))
if ((tobj = get_obj_in_list_vis(ch, t, &number, world[IN_ROOM(ch)].contents)) != NULL)
target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD))
if ((tobj = get_obj_vis(ch, t, &number)) != NULL)
target = TRUE;
} else { /* if target string is empty */
if (!target && IS_SET(SINFO.targets, TAR_FIGHT_SELF))
if (FIGHTING(ch) != NULL) {
tch = ch;
target = TRUE;
}
if (!target && IS_SET(SINFO.targets, TAR_FIGHT_VICT))
if (FIGHTING(ch) != NULL) {
tch = FIGHTING(ch);
target = TRUE;
}
/* if no target specified, and the spell isn't violent, default to self */
if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) &&
!SINFO.violent) {
tch = ch;
target = TRUE;
}
if (!target) {
send_to_char(ch, "Upon %s should the spell be cast?\r\n",
IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ? "what" : "who");
return;
}
}
if (target && (tch == ch) && SINFO.violent) {
send_to_char(ch, "You shouldn't cast that on yourself -- could be bad for your health!\r\n");
return;
}
if (!target) {
send_to_char(ch, "Upon %s should the spell be cast?\r\n",
IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ? "what" : "who");
return;
}
}
if (target && (tch == ch) && SINFO.violent) {
send_to_char(ch, "You shouldn't cast that on yourself -- could be bad for your health!\r\n");
return;
}
if (!target) {
send_to_char(ch, "Cannot find the target of your spell!\r\n");
return;
}
mana = mag_manacost(ch, spellnum);
if ((mana > 0) && (GET_MANA(ch) < mana) && (GET_LEVEL(ch) < LVL_IMMORT)) {
send_to_char(ch, "You haven't the energy to cast that spell!\r\n");
return;
}
/* You throws the dice and you takes your chances.. 101% is total failure */
if (rand_number(0, 101) > GET_SKILL(ch, spellnum)) {
WAIT_STATE(ch, PULSE_VIOLENCE);
if (!tch || !skill_message(0, ch, tch, spellnum))
send_to_char(ch, "You lost your concentration!\r\n");
if (mana > 0)
GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - (mana / 2)));
if (SINFO.violent && tch && IS_NPC(tch))
hit(tch, ch, TYPE_UNDEFINED);
} else { /* cast spell returns 1 on success; subtract mana & set waitstate */
if (cast_spell(ch, tch, tobj, spellnum)) {
WAIT_STATE(ch, PULSE_VIOLENCE);
if (mana > 0)
GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - mana));
}
}
}