#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "emlen.h"
void
show_hitdam (int gsn, char *noun, int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
#ifdef NEW_WORLD
int ty;
char rvp[1024];
char rss[1024];
char *tt;
ty = 0;
if (victim->hit < 0)
return;
sprintf (rss, "$B$6Your %s *a $N.$R$7", noun);
for (tt = rss; *tt != '\0'; tt++)
{
if (*tt == '*')
{
tt++;
if (*tt == 'a')
{
strcat (rvp, (star_a (dam, victim->max_hit)));
ty = strlen (rvp);
}
}
else
{
rvp[ty] = *tt;
rvp[ty + 1] = '\0';
ty++;
}
}
act (rvp, ch, NULL, victim, TO_CHAR);
#else
dam_message (ch, victim, dam, gsn, 0);
#endif
return;
}
void
spell_summon (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vict;
if (!target_name || target_name[0] == '\0')
return;
if ((vict = get_char_world (ch, target_name)) == NULL)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (FIGHTING (vict) || LEVEL (vict) > LEVEL (ch) + 5 || !vict->in_room->area->open ||
vict->in_room->vnum < 1000 || vict == ch)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (IS_MOB (vict) && !pow.can_summon_mobs)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if ((vict->in_room && IS_SET (vict->in_room->room_flags, ROOM_NOSUMMON)) ||
(ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NOSUMMON)))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (IS_PLAYER (vict) && IS_PLAYER (ch) &&
((IS_EVIL (vict) && !IS_EVIL (ch)) || (IS_EVIL (ch) && !IS_EVIL (vict))))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
act ("$n disappears in a flash of bright light!", vict, NULL, vict, TO_ROOM);
char_from_room (vict);
char_to_room (vict, ch->in_room);
act ("$n appears in a blinding flash of light!", vict, NULL, vict, TO_ROOM);
send_to_char ("You have been summoned!!\n\r", vict);
do_look (vict, "auto");
return;
}
void
spell_teleport (int sn, int level, CHAR_DATA * ch, void *vo)
{
ROOM_DATA *rd;
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!victim)
victim = ch;
if (FIGHTING (ch))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
while ((rd = get_room_index (number_range (1001, 99999))) == NULL || !rd->area->open ||
rd->sector_type == SECT_WATER_NOSWIM || rd->sector_type == SECT_WATER_SWIM ||
IS_SET (rd->room_flags, ROOM_NOSUMMON)) ;
act ("$n disappears!", victim, NULL, victim, TO_ROOM);
char_from_room (victim);
char_to_room (victim, rd);
return;
}
void
spell_word_of_recall (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (IS_MOB (ch))
return;
if (!victim)
victim = ch;
if (IS_MOB (victim))
return;
if (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
if (FIGHTING (ch))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
if ((IS_EVIL (ch) && !IS_EVIL (victim)) || (!IS_EVIL (ch) && IS_EVIL (victim)))
return;
if (IS_AFFECTED (victim, AFF_CURSE)) {
if (victim==ch) {
send_to_char("A powerful curse is preventing you from recalling!\n\r", ch);
} else {
send_to_char("A powerful curse prevents your spell from succeeding!\n\r",ch);
}
return;
}
if (IS_EVIL (victim))
{
act ("$n disappears!", victim, NULL, victim, TO_ROOM);
char_from_room (victim);
char_to_room (victim, get_room_index (99));
return;
}
if (!IS_EVIL (victim))
{
act ("$n disappears!", victim, NULL, victim, TO_ROOM);
char_from_room (victim);
char_to_room (victim, get_room_index (100));
return;
}
return;
}
void
scatter_mob (CHAR_DATA * mob)
{
int just_moved_dir = -1;
int moved_rooms = 0;
int move_tries = 0;
int move_dir;
if (!mob->in_room)
return;
while (move_tries < 20 && moved_rooms < 3)
{
move_dir = number_range (0, 5);
while (move_dir == rev_dir[just_moved_dir])
move_dir = number_range (0, 5);
if (move_char (mob, move_dir))
{
move_tries++;
moved_rooms++;
just_moved_dir = move_dir;
continue;
}
else
move_tries++;
}
return;
}
void
do_spray (CHAR_DATA * ch, char *argy)
{
char buf[500];
char arg1[500];
SINGLE_OBJECT *spray;
CHAR_DATA *victim;
DEFINE_COMMAND ("spray", do_spray, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to spray a bottle of repellant at a mob.")
argy = one_argy (argy, arg1);
if (!str_prefix ("with", argy))
argy = one_argy (argy, buf);
if (argy == "" || argy[0] == '\0')
{
if ((spray = get_item_held (ch, ITEM_REPELLANT)) == NULL)
{
send_to_char ("Spray who with what?\n\r", ch);
return;
}
}
else if ((spray = get_obj_carry (ch, argy)) == NULL)
{
if ((spray = get_obj_wear (ch, argy)) == NULL)
{
send_to_char ("You don't seem to be carrying that.\n\r", ch);
return;
}
}
if (spray->pIndexData->item_type != ITEM_REPELLANT)
{
send_to_char ("You can't spray that!\n\r", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
send_to_char ("I don't see a creature or person like that to spray it on.\n\r", ch);
return;
}
/* Spraying it.. remove a 'squirt' */
((I_SPRAY *) spray->more)->sprays--;
if (IS_PLAYER (victim))
{
act ("You spray $N, but $E doesn't seem to be affected.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid in your face, but nothing happens.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid in $N's face, but nothing seems to happen.", ch, NULL, victim, TO_NOTVICT);
}
if (IS_MOB (victim))
{
int i;
bool yes_no = FALSE;
for (i = 0; i < 9; i++)
if (((I_SPRAY *) spray->more)->repels[i] == victim->pIndexData->vnum)
{
yes_no = TRUE;
break;
}
if (!yes_no)
{
act ("You spray $N, but $E doesn't seem to be affected.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid at you, but nothing happens.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid at $N, but nothing seems to happen.", ch, NULL, victim, TO_NOTVICT);
}
else
{
act ("You spray $N.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid at you.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid at $N.", ch, NULL, victim, TO_NOTVICT);
if (FIGHTING (victim))
{
if (HUNTING (victim) && !str_cmp (HUNTING (victim), NAME (ch)))
{
free_string (HUNTING (victim));
victim->fgt->hunting = NULL;
}
stop_fighting (FIGHTING (victim), TRUE);
stop_fighting (victim, TRUE);
}
scatter_mob (victim);
}
}
if (((I_SPRAY *) spray->more)->sprays < 1)
{
send_to_char ("The spray is empty, and magically disappears!\n\r", ch);
free_it (spray);
}
return;
}
/* Fix this!!! */
void
spell_dispel_magic (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int affected_by;
if (victim->affected_by == 0
|| level + 30 < LEVEL (victim)
|| (saves_spell (level, victim) && saves_spell (level, victim)))
{
send_to_char ("You failed.\n\r", ch);
return;
}
for (;;)
{
affected_by = 1 << number_bits (5);
if (IS_SET (victim->affected_by, affected_by))
break;
}
REMOVE_BIT (victim->affected_by, affected_by);
send_to_char ("You successfully removed a spell from the victim!\n\r", ch);
act ("$n just removed a spell effect from you!", ch, NULL, victim, TO_VICT);
return;
}
void
spell_create_object (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
SINGLE_OBJECT *obj;
if ((obj = create_object (get_obj_index (spell->creates_obj), 0)) == NULL)
{
send_to_char ("A god has set up this spell wrong.. please contact a god.\n\r", ch);
return;
}
if (IS_SET (spell->spell_bits, SPELL_OBJ_TO_ROOM))
obj_to (obj, ch->in_room);
else
{
obj_to (obj, ch);
obj->wear_loc = -1;
}
return;
}
bool
remove_sa (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!is_affectedt (victim, spell->bitvector))
{
send_to_char ("Your spell fails!\n\r", ch);
return FALSE;
}
affect_strip_bits (victim, spell->bitvector);
return TRUE;
}
void
write_stuff (SPELL_DATA * spell, CHAR_DATA * ch, CHAR_DATA * victim)
{
if (spell->act_to_ch_1)
act (spell->act_to_ch_1, ch, NULL, victim, TO_CHAR);
if (spell->act_to_ch_2)
act (spell->act_to_ch_2, ch, NULL, victim, TO_CHAR);
if (victim && spell->act_to_vict_1)
act (spell->act_to_vict_1, ch, NULL, victim, TO_VICT);
if (victim && spell->act_to_vict_2)
act (spell->act_to_vict_2, ch, NULL, victim, TO_VICT);
if (victim && ch == victim && spell->act_to_vict_1)
act (spell->act_to_vict_1, ch, NULL, victim, TO_CHAR);
if (victim && ch == victim && spell->act_to_vict_2)
act (spell->act_to_vict_2, ch, NULL, victim, TO_CHAR);
if (spell->act_to_notvict_1)
act (spell->act_to_notvict_1, ch, NULL, victim, TO_NOTVICT);
if (spell->act_to_notvict_2)
act (spell->act_to_notvict_2, ch, NULL, victim, TO_NOTVICT);
return;
}
void
general_spell (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
AFFECT_DATA paf;
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *next = NULL;
bool wrote = FALSE;
bool once = FALSE;
int dur = 0;
bool sskip = FALSE;
bool cast_at_n = FALSE;
bzero (&paf, sizeof (paf));
if (IS_SET (spell->spell_bits, SPELL_NOT_SELF) && ch == victim && !IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
{
send_to_char ("You find that you cannot cast this spell upon yourself...\n\r", ch);
return;
}
if (IS_SET (spell->spell_bits, SPELL_FAIL_1_3))
{
if (number_range (1, 3) == 2)
{
send_to_char ("Your spell failed...\n\r", ch);
return;
}
}
if (IS_SET (spell->spell_bits, SPELL_FAIL_1_4))
{
if (number_range (1, 4) == 2)
{
send_to_char ("Your spell failed...\n\r", ch);
return;
}
}
if (IS_SET (spell->spell_bits, SPELL_FAIL_1_2))
{
if (number_range (1, 2) == 2)
{
send_to_char ("Your spell failed...\n\r", ch);
return;
}
}
if (/*spell->spell_type != TAR_CHAR_OFFENSIVE &&*/ IS_SET (spell->spell_bits, SPELL_HURT_GOOD) && IS_EVIL (victim))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (/*spell->spell_type != TAR_CHAR_OFFENSIVE &&*/ IS_SET (spell->spell_bits, SPELL_HURT_EVIL) && !IS_EVIL (victim))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (spell->creates_obj != 0)
{
spell_create_object (spell, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_MESSAGE))
{
spell_message (spell->gsn, level, ch, vo);
return;
}
if (!IS_SET (spell->spell_bits, SPELL_ONLY_MULTI_MOBS) || IS_MOB (victim))
{
if (ch && victim && IS_PLAYER (ch) && !IS_MOB (victim) && IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM) &&
spell->spell_type == TAR_CHAR_OFFENSIVE &&
((IS_EVIL (ch) && IS_EVIL (victim)) ||
(!IS_EVIL (ch) && !IS_EVIL (victim))))
{
sskip = TRUE;
}
if (!sskip && IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
{
cast_at_n = TRUE;
victim = ch->in_room->more->people;
next = victim->next_in_room;
}
}
for (once = TRUE; ((once || next != NULL) && (!victim || (victim && victim->data_type!=50))); victim = next)
{
if (victim && IS_PLAYER (victim) && cast_at_n && IS_SET (spell->spell_bits, SPELL_ONLY_MULTI_MOBS))
{
next = victim->next_in_room;
continue;
}
else if (!sskip && IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
next = victim->next_in_room; else
next = NULL;
once = FALSE;
if (!sskip && IS_SET (spell->spell_bits, SPELL_ONLY_GROUP) && ch &&
(((IS_EVIL (ch) && !IS_EVIL (victim))
|| (!IS_EVIL (ch) && IS_EVIL (victim)))
|| ((IS_PLAYER (ch) && IS_MOB (victim))
|| (IS_MOB (ch) && IS_PLAYER (victim)))))
continue;
if (!sskip && IS_SET (spell->spell_bits, SPELL_ONLY_NOT_GROUP) && ch &&
((IS_EVIL (ch) && IS_EVIL (victim))
|| (!IS_EVIL (ch) && !IS_EVIL (victim)))
&& ((IS_PLAYER (ch) && IS_MOB (victim) && spell->spell_type != TAR_CHAR_OFFENSIVE)
|| (IS_MOB (ch) && IS_PLAYER (victim) && spell->spell_type != TAR_CHAR_OFFENSIVE)
|| (IS_PLAYER (ch) && !IS_MOB (victim)) ||
(IS_MOB (ch) && IS_MOB (victim))))
continue;
if (IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM) && IS_SET (spell->spell_bits, SPELL_NOT_SELF) &&
ch == victim)
continue;
if (!victim)
victim = ch;
if (IS_SET (spell->spell_bits, SPELL_CHARM_PERSON))
{
spell_charm_person (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_SCRY))
{
spell_scry (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_LOCATE_PERSON))
{
spell_locate_person (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_REMOVES_BIT))
{
if (!remove_sa (spell, level, ch, vo))
{};
}
if (IS_SET (spell->spell_bits, SPELL_DISPEL_MAGIC))
{
spell_dispel_magic (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_IDENTIFY))
{
spell_identify (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_LOCATE_OBJECT))
{
spell_locate_object (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_TELEPORT))
{
spell_teleport (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_SUMMON))
{
spell_summon (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_RECALL))
{
spell_word_of_recall (spell->gsn, level, ch, vo);
}
if (IS_SET (spell->spell_bits, SPELL_ADD_MOVE))
{
victim->move += translate (spell->damage, level, ch);
if (victim->move > victim->max_move) {
victim->move = victim->max_move;
}
if (victim->move < 1) {
victim->move = 1;
}
}
if (IS_SET (spell->spell_bits, SPELL_HEALS_DAM))
{
victim->hit += translate (spell->damage, level, ch);
if (victim->hit > victim->max_hit)
victim->hit = victim->max_hit;
}
if (IS_SET (spell->spell_bits, SPELL_FIRE))
{
spell_fire_breath (spell->gsn, level, ch, (void *) victim);
}
if (IS_SET (spell->spell_bits, SPELL_ACID))
{
spell_acid_breath (spell->gsn, level, ch, (void *) victim);
}
if (spell->spell_type == TAR_CHAR_OFFENSIVE && spell->damage != NULL)
{
if (!ch || !victim)
return;
if (IS_SET (spell->spell_bits, SPELL_HURT_UNDEAD) && (IS_PLAYER (victim) || (IS_MOB (victim) &&
victim->pIndexData->mobtype != MOB_GHOST && victim->pIndexData->mobtype != MOB_UNDEAD)))
{
send_to_char ("This spell can only do harm to undead creatures.\n\r", ch);
return;
}
if (IS_SET (spell->spell_bits, SPELL_HURT_GOOD) && IS_EVIL (victim))
{
send_to_char ("This spell can only do harm to good.\n\r", ch);
return;
}
if (IS_SET (spell->spell_bits, SPELL_HURT_EVIL) && !IS_EVIL (victim))
{
send_to_char ("This spell can only do harm to evil.\n\r", ch);
return;
}
write_stuff (spell, ch, victim);
wrote = TRUE;
if (IS_AFFECTED_EXTRA (victim, AFF_MINDSHIELD))
{
int dam = (translate (spell->damage, level, ch) * 2) / 3;
show_hitdam (spell->gsn, spell->noun_damage, dam, ch, victim);
damage (ch, victim, dam, spell->gsn);
if (victim->data_type==50) continue;
}
else if (IS_SET (spell->spell_bits, SPELL_HALVED_SAVE) && saves_spell (level, victim))
{
int dam = (translate (spell->damage, level, ch) / 2);
show_hitdam (spell->gsn, spell->noun_damage, dam, ch, victim);
damage (ch, victim, dam, spell->gsn);
if (victim->data_type==50) continue;
}
else
{
int dam = translate (spell->damage, level, ch);
show_hitdam (spell->gsn, spell->noun_damage, dam, ch, victim);
damage (ch, victim, dam, spell->gsn);
if (victim->data_type==50) continue;
}
}
if (str_cmp (spell->duration, "N/A") && translate (spell->duration, level, ch) > 0)
{
dur = translate (spell->duration, level, ch);
if (spell->spell_type == TAR_CHAR_OFFENSIVE)
{
if (victim && (saves_spell (level, victim)) && ch != victim)
{
act ("$N resisted the effects of your spell!", ch, NULL, victim, TO_CHAR);
act ("You resisted the effects of $n's spell!", ch, NULL, victim, TO_VICT);
if (FIGHTING (victim) == NULL)
set_fighting (victim, ch);
goto dunny;
}
if (IS_AFFECTED_EXTRA (victim, AFF_MINDSHIELD))
{
dur /= 2;
}
}
paf.type = spell->gsn;
paf.duration = dur;
paf.location = spell->location;
paf.modifier = translate (spell->modifier, level, ch);
paf.bitvector = spell->bitvector;
paf.bitvector2 = spell->bitvector2;
renew_affect (victim, &paf);
if (paf.bitvector == AFF_SLEEP)
{
do_sleep (victim, "");
NEW_POSITION(victim, POSITION_SLEEPING);
}
}
if (!wrote)
write_stuff (spell, ch, victim);
dunny:
if (ch) {};
}
if (spell && spell->linked_to != NULL)
{
SPELL_DATA *sp;
if ((sp = skill_lookup (spell->linked_to, -1)) != NULL)
{
general_spell (sp, level, ch, vo);
}
}
if (IS_PLAYER (ch))
skill_gain (ch, spell->gsn, TRUE);
return;
}
void
spell_message (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *rec;
char buf[STD_LENGTH];
char targname[SML_LENGTH];
if (!target_name || target_name[0] == '\0')
{
send_to_char ("A voice booms from the heavens:\n\r", ch);
send_to_char ("\x1B[1mSyntax\x1B[0m: cast 'message' <\x1B[1mtarget\x1B[0m> <\x1B[1mmsg\x1B[0m>\n\r", ch);
return;
}
target_name = one_argy (target_name, targname);
if ((rec = get_char_world (ch, targname)) == NULL)
{
send_to_char ("You send a voice, but you get the feeling it could not deliver.\n\r", ch);
return;
}
sprintf (buf, "\x1B[1;32mA voice from afar tells you '\x1B[0m%s\x1B[1;32m'\x1B[0m\n\r",
target_name);
send_to_char (buf, rec);
sprintf (buf, "You send a mystical voice to talk to %s.", NAME (rec));
send_to_char (buf, ch);
return;
}
void
spell_charm_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
bzero (&af, sizeof (af));
if (victim == ch)
{
send_to_char ("You like yourself even better!\n\r", ch);
return;
}
if (IS_MOB (victim) && (victim->pIndexData->mobtype == MOB_GHOST))
{
act ("$N doesn't have a body to charm.", ch, NULL, victim, TO_CHAR);
return;
}
if (IS_MOB (victim) && IS_SET (victim->act, ACT_UNTOUCHABLE))
{
send_to_char ("You failed.\n\r", ch);
return;
}
if (IS_AFFECTED (victim, AFF_CHARM)
|| IS_AFFECTED (ch, AFF_CHARM)
|| level < LEVEL (victim) - 6
|| IS_PLAYER (victim)
|| IS_AFFECTED (victim, AFF_NOCHARM)
|| saves_spell (level, victim))
{
act ("$N snarls at you in complete hatred!", ch, NULL, victim, TO_CHAR);
act ("$n just tried to charm you!!", ch, NULL, victim, TO_VICT);
return;
}
if (MASTER (victim) != NULL)
stop_follower (victim);
add_follower (victim, ch);
af.type = sn;
af.duration = number_fuzzy (level / 10);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char (victim, &af);
act ("You feel compelled to follow $n.", ch, NULL, victim, TO_VICT);
if (ch != victim)
act ("$N gazes at you as if $S life revolved around you.",
ch, NULL, victim, TO_CHAR);
return;
}
void
spell_scry (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[STD_LENGTH];
if (target_name == '\0')
{
return;
}
if (!scry (ch, level, target_name))
{
sprintf (buf, "You were unable to scry %s.\n\r", target_name);
send_to_char (buf, ch);
}
return;
}
void
spell_locate_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[STD_LENGTH];
if (target_name == '\0')
{
return;
}
if (!locate_person (ch, level, target_name))
{
sprintf (buf, "You were unable to locate %s.\n\r", target_name);
send_to_char (buf, ch);
}
return;
}
void
spell_identify (int sn, int level, CHAR_DATA * ch, void *vo)
{
SINGLE_OBJECT *obj = (SINGLE_OBJECT *) vo;
SPELL_DATA *spp;
char buf3[500];
char buf2[STD_LENGTH];
char buf[STD_LENGTH];
AFFECT_DATA *paf;
send_to_char (
"\x1B[0m-----------------------------------------------------------------------------\n\r",
ch);
sprintf (buf, "'\x1B[1m%s\x1B[0m' is some sort of \x1B[1m%s\x1B[0m.\n\r",
STR (obj, short_descr),
item_type_name (obj->pIndexData->item_type));
send_to_char (buf, ch);
sprintf (buf, "It weighs \x1B[1m%d\x1B[0m kg, and is apparantly worth \x1B[1m%d\x1B[0;33m copper\x1B[0m.\n\r",
obj->pIndexData->weight, obj->cost);
send_to_char (buf, ch);
sprintf (buf, "It is affected by \x1B[34m[\x1B[1m%s\x1B[0;34m]\x1B[0m.\n\r",
extra_bit_name (obj->extra_flags));
send_to_char (buf, ch);
sprintf (buf,
"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\r");
switch (obj->pIndexData->item_type)
{
case ITEM_SCROLL:
case ITEM_POTION:
{
I_POTION *pot = (I_POTION *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Level \x1B[1m%d\x1B[0m spells of:", pot->spell_level);
send_to_char (buf, ch);
if (pot->spells[0] >= 0 && pot->spells[0] < SKILL_COUNT)
{
send_to_char (" '\x1B[1m", ch);
if ((spp = skill_lookup (NULL, pot->spells[0])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
if (pot->spells[1] >= 0 && pot->spells[1] < SKILL_COUNT)
{
send_to_char (" '\x1B[1m", ch);
if ((spp = skill_lookup (NULL, pot->spells[1])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
if (pot->spells[2] >= 0 && pot->spells[2] < SKILL_COUNT)
{
send_to_char (" '\x1B[1m", ch);
if ((spp = skill_lookup (NULL, pot->spells[2])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
send_to_char (".\n\r", ch);
}
break;
case ITEM_WAND:
case ITEM_STAFF:
{
I_WAND *wnd = (I_WAND *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Has \x1B[34m%d\x1B[0m of \x1B[1;34m%d\x1B[0m charges of level \x1B[1m%d\x1B[0m",
wnd->current_charges, wnd->max_charges, wnd->spell_level);
send_to_char (buf, ch);
if (wnd->spells[0] >= 0 && wnd->spells[0] < SKILL_COUNT)
{
send_to_char (" '\x1B[1m", ch);
if ((spp = skill_lookup (NULL, wnd->spells[0])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
send_to_char (".\n\r", ch);
break;
}
case ITEM_GEM:
{
I_GEM *gem = (I_GEM *) obj->more;
sprintf (buf2, "Mana Type(s): ");
if (IS_SET (gem->gem_type, MANA_FIRE))
strcat (buf2, "\x1B[31;1mFIRE ");
if (IS_SET (gem->gem_type, MANA_WATER))
strcat (buf2, "\x1B[34;1mWATER ");
if (IS_SET (gem->gem_type, MANA_EARTH))
strcat (buf2, "\x1B[33;0mEARTH ");
if (IS_SET (gem->gem_type, MANA_AIR))
strcat (buf2, "\x1B[30;1mAIR ");
strcat (buf2, "\x1B[37;0m");
sprintf (buf3, "\n\rMaximum mana: \x1B[37;1m%d\x1B[0m.", gem->max_mana);
strcat (buf2, buf3);
send_to_char (buf2, ch);
send_to_char ("\n\rGems may not give you their max mana if you have low intelligence or wisdom.\n\r", ch);
sprintf (buf2, "Max spell level for this gem: %d\n\r", gem->max_level);
send_to_char (buf2, ch);
break;
}
case ITEM_WEAPON:
{
I_WEAPON *weap = (I_WEAPON *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "This weapon is capable of \x1B[1;34m%d\x1B[0md\x1B[1;34m%d\x1B[0m damage.\n\r",
weap->firstdice, weap->seconddice);
send_to_char (buf, ch);
break;
}
case ITEM_ARMOR:
{
I_ARMOR *arm = (I_ARMOR *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Leg AC: %d Body AC: %d Head AC: %d Arm AC: %d.\n\r", arm->protects_legs,
arm->protects_body, arm->protects_head, arm->protects_arms);
send_to_char (buf, ch);
break;
}
}
for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next)
{
if (paf->location != APPLY_NONE && paf->modifier != 0)
{
if (paf->modifier > 0)
sprintf (buf, "It is +\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier, affect_loc_name (paf->location));
else
sprintf (buf, "It is -\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier * -1, affect_loc_name (paf->location));
send_to_char (buf, ch);
}
}
send_to_char (
"-----------------------------------------------------------------------------\n\r", ch);
return;
}
void
spell_locate_object (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[SML_LENGTH];
SINGLE_OBJECT *obj;
SINGLE_OBJECT *in_obj;
bool found;
int number = 0;
found = FALSE;
if (level > 100 || LEVEL (ch) > 100)
return;
for (obj = object_list; obj != NULL && number <= LEVEL (ch);
obj = obj->next)
{
if (!can_see_obj (ch, obj) || !is_name (target_name, obj->pIndexData->name))
continue;
found = TRUE;
number++;
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj)
;
if (in_obj->carried_by != NULL)
{
sprintf (buf, "%s carried by %s.\n\r",
STR (obj, short_descr), PERS (in_obj->carried_by, ch));
}
else
{
sprintf (buf, "%s in %s.\n\r",
STR (obj, short_descr), in_obj->in_room == NULL
? "somewhere" : in_obj->in_room->name);
}
buf[0] = UPPER (buf[0]);
send_to_char (buf, ch);
}
if (!found)
send_to_char ("Nothing like that in hell, heaven or earth.\n\r", ch);
return;
}
void
spell_acid_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
if (number_percent () < 2 * level)
{
for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
{
int iWear;
obj_next = obj_lose->next_content;
if (number_range (1, 10) > 6)
continue;
switch (obj_lose->pIndexData->item_type)
{
case ITEM_ARMOR:
if (((I_ARMOR *) obj_lose->more)->condition_now > 0)
{
act ("$p is covered with acid!",
victim, obj_lose, NULL, TO_CHAR);
if ((iWear = obj_lose->wear_loc) != WEAR_NONE)
victim->armor += apply_ac (obj_lose, iWear);
if (((I_ARMOR *) obj_lose->more)->condition_now > 3)
((I_ARMOR *) obj_lose->more)->condition_now -= 3;
if (iWear != WEAR_NONE)
victim->armor -= apply_ac (obj_lose, iWear);
}
break;
case ITEM_CONTAINER:
act ("$p fumes and dissolves!",
victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
break;
}
}
}
return;
}
void
spell_fire_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
if (number_percent () < 2 * level && !saves_spell (level, victim))
{
for (obj_lose = victim->carrying; obj_lose != NULL;
obj_lose = obj_next)
{
char *msg;
obj_next = obj_lose->next_content;
if (number_range (1, 100) > 11)
continue;
switch (obj_lose->pIndexData->item_type)
{
default:
continue;
case ITEM_CONTAINER:
msg = "$p ignites and burns!";
break;
case ITEM_POTION:
msg = "$p bubbles and boils!";
break;
case ITEM_SCROLL:
msg = "$p crackles and burns!";
break;
case ITEM_STAFF:
msg = "$p smokes and chars!";
break;
case ITEM_WAND:
msg = "$p sparks and sputters!";
break;
case ITEM_FOOD:
msg = "$p blackens and crisps!";
break;
case ITEM_PILL:
msg = "$p melts and drips!";
break;
}
act (msg, victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
}
return;
}