/* 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));
}
}
/* Every spell that affects an area (room) runs through here. These are
* generally offensive spells. This calls mag_damage to do the actual damage.
* All spells listed here must also have a case in mag_damage() in order for
* them to work. Area spells have limited targets within the room. */
void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
{
struct char_data *tch, *next_tch;
const char *to_char = NULL, *to_room = NULL;
if (ch == NULL)
return;
/* to add spells just add the message here plus an entry in mag_damage for
* the damaging part of the spell. */
switch (spellnum) {
case SPELL_EARTHQUAKE:
to_char = "You gesture and the earth begins to shake all around you!";
to_room ="$n gracefully gestures and the earth begins to shake violently!";
break;
}
if (to_char != NULL)
act(to_char, FALSE, ch, 0, 0, TO_CHAR);
if (to_room != NULL)
act(to_room, FALSE, ch, 0, 0, TO_ROOM);
for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
next_tch = tch->next_in_room;
/* The skips: 1: the caster
* 2: immortals
* 3: if no pk on this mud, skips over all players
* 4: pets (charmed NPCs) */
if (tch == ch)
continue;
if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT)
continue;
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(tch))
continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue;
/* Doesn't matter if they die here so we don't check. -gg 6/24/98 */
mag_damage(level, ch, tch, spellnum, 1);
}
}
/*
* Every spell that affects an area (room) runs through here. These are
* generally offensive spells. This calls mag_damage to do the actual
* damage – all spells listed here must also have a case in mag_damage()
* in order for them to work.
*
* area spells have limited targets within the room.
*/
void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
{
struct char_data *tch, *next_tch;
const char *to_char = NULL, *to_room = NULL;
if (ch == NULL)
return;
/*
* to add spells to this fn, just add the message here plus an entry
* in mag_damage for the damaging part of the spell.
*/
switch (spellnum) {
case SPELL_EARTHQUAKE:
to_char = "You gesture and the earth begins to shake all around you!";
to_room ="$n gracefully gestures and the earth begins to shake violently!";
break;
case SPELL_CALL_LIGHTNING:
to_char = "You raise your hands to the heavens and call down lightning upon your enemies!";
to_room = "$n raises $s hands to the heavns and calls down lightning; it rains down upon the area!";
break;
case SPELL_BLIZZARD:
to_char = "You close your eyes and call out to the northern ice fields, summoning a raging blizzard!";
to_room = "$n closes $s eyes and calls out to the northern ice fields, summoning a raging blizzard!";
break;
}
if (to_char != NULL)
act(to_char, FALSE, ch, 0, 0, TO_CHAR);
if (to_room != NULL)
act(to_room, FALSE, ch, 0, 0, TO_ROOM);
for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
next_tch = tch->next_in_room;
/*
* The skips: 1: the caster
* 2: immortals
* 3: if no pk on this mud, skips over all players
* 4: pets (charmed NPCs)
* 5: NPC's that aren't charmed will not hit others that aren't
* 6: NPC's that ARE charmed will not hit others that are
* 7: !KILL flagged mobs are skipped… no message to player.
*/
if (tch == ch)
continue;
if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT && IS_IMMORT(tch) == TRUE)
continue;
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(tch))
continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue;
if (IS_NPC(ch) && IS_NPC(tch) && !AFF_FLAGGED(ch, AFF_CHARM) && !AFF_FLAGGED(tch, AFF_CHARM))
continue;
if (IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(ch, AFF_CHARM) && AFF_FLAGGED(tch, AFF_CHARM))
continue;
if (IS_NPC(tch) && MOB_FLAGGED(tch, MOB_NOKILL))
continue;
/* We check for skill improvement on every successfull smack down */
improve_skill(ch, spellnum, TRUE);
/* Doesn't matter if they die here so we don't check. -gg 6/24/98 */
mag_damage(level, ch, tch, spellnum, 1);
}
}
/*
* Every spell that does damage comes through here. This calculates the
* amount of damage, adds in any modifiers, determines what the saves are,
* tests for save and calls damage().
*
* -1 = dead, otherwise the amount of damage done.
*/
long mag_damage(int level, struct char_data *ch, struct char_data *victim,
int spellnum, int savetype)
{
long dam = 0;
int i;
bool save = mag_savingthrow(victim, savetype, 0);
if (victim == NULL || ch == NULL)
return (0);
switch (spellnum) {
/* Mostly mages */
case SPELL_LIGHTNING_BOLT:
dam = 100;
break;
case SPELL_COLOR_SPRAY:
dam = 250;
break;
case SPELL_FIREBALL:
dam = 500;
break;
case SPELL_DISINTIGRATE:
dam = 1500;
/* If we didn't save & aren't protected, then splat a random number of pieces of equipment that aren't protected from it */
if (affected_by_spell(victim, SPELL_FREE_ACTION))
send_to_char(victim, "Your free action protects you from disintigration!\r\n");
else if (save == FALSE)
destroy_equip(ch, victim, rand_number(1, 5), TRUE, "disintigrates under the intense onslaught!");
break;
/* Area spells */
case SPELL_EARTHQUAKE:
dam = 35 * level;
SET_BIT(TMP_FLAGS(victim), TMP_SPELL_STUN);
WAIT_STATE(victim, PULSE_VIOLENCE * spell_info[spellnum].stun);
break;
case SPELL_CALL_LIGHTNING:
dam = 20 * level;
break;
case SPELL_BLIZZARD:
dam = 35 * level;
SET_BIT(TMP_FLAGS(victim), TMP_SPELL_STUN);
WAIT_STATE(victim, PULSE_VIOLENCE * spell_info[spellnum].stun);
break;
} /* switch(spellnum) */
/* divide damage by two if victim makes his saving throw */
if (save)
dam /= 2;
/* and finally, inflict the damage */
return (damage(ch, victim, dam, spellnum));
}
victim=damage(ch, victim,…); at which point you can simply check if (victim) for anything else. You also wouldn't have to worry about changing anything else in your code to worry about dealing with pointers to pointers.
Note that not only victim but also ch (and potentially other people in the room) can die from a call to damage, if there is some kind of counter-damage spell/effect going on.
Moo.