/************************************************************************ Realms of Aurealis James Rhone aka Vall of RoA magic.c Spells, the actual code of each spell... arrive here from sparse. ******** Heavily modified and expanded ******** *** BE AWARE OF ALL RIGHTS AND RESERVATIONS *** ******** Heavily modified and expanded ******** All rights reserved henceforth. Please note that no guarantees are associated with any code from Realms of Aurealis. All code which has been released to the general public has been done so with an 'as is' pretense. RoA is based on both Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well as the RoA license. *** Read, Learn, Understand, Improve *** NOTE: All spells1.c and spells2.c have been COMBINED with this magic.c file, in an attempt to put the spells closer together to make additions and alterations much easier than having to hop from file to file. ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structures.h" #include "utils.h" #include "comm.h" #include "magic.h" #include "handler.h" #include "mudlimits.h" #include "interpreter.h" #include "acmd.h" #include "db.h" #include "fight.h" #include "affect.h" #include "lists.h" #include "htown.h" #include "global.h" #include "darkenelf.h" /* extern variables */ extern char *dirs[]; extern char *comm_dirs[]; extern int rev_dir[]; extern char *item_types[]; extern char *extra_bits[]; extern char *extra_bits2[]; extern char *apply_types[]; extern char *affected_bits[]; extern char *affected2_bits[]; extern char *wv_bits[]; /* extern functions */ BOOL saves_spell(chdata *ch, int spell); void weight_change_object(obdata *obj, int weight); int check_room_affects(chdata *ch, int room); // replace old USE_MANA macro with function, -jtrhone 8/16/98 int manause(chdata *ch, int spl) { // madepts special case switch(GET_CLASS(ch)) { case CLASS_MADEPT: return MAX(spell_info[spl].min_usesmana, 100/MAX(1, (2+GET_LEVEL(ch) - (LEV_IMM/2)))); break; default: break; } return MAX(spell_info[spl].min_usesmana, 100/MAX(1, (2+GET_LEVEL(ch) - get_spell_min_level(ch, spl)))); } // the main interface to all the ASPELLS now... void do_cast_spell(int spl, chdata *ch, char *arg, int type, chdata *victim, obdata *obj) { int retval; if (IN_NOWHERE(ch)) return; if (WAITING(ch)) { send_to_char("You cannot cast anything right now!\n\r",ch); return; } switch (type) { case SPELL_TYPE_SPELL: if (SPELL_FLAGGED(spl, S_CASTABLE)) { // cant cast if room is silenced if (spell_affects_room(ch->in_room, SPELL_SILENCE) && spl < 230) /* regular, non-breath */ { act("This area is %Bsilenced%0!", FALSE, ch, 0, 0, TO_CHAR); act("$n cannot cast $s spell because this area is %Bsilenced!%0", FALSE, ch, 0, 0, TO_ROOM); return; } else retval = (*spell_info[spl].spell_pointer)(ch, arg, victim, obj); switch(retval) { case SPELL_SUCCESS: act("Success!", FALSE, ch, 0, 0, TO_CHAR); break; case SPELL_FAILED: act("Your spell failed...", FALSE, ch, 0, 0, TO_CHAR); break; case SPELL_NORMAL: default: break; } } break; case SPELL_TYPE_POTION: if(SPELL_FLAGGED(spl, S_POTION)) (*spell_info[spl].spell_pointer)(ch, arg, victim, obj); break; case SPELL_TYPE_SCROLL: if(SPELL_FLAGGED(spl, S_SCROLL)) { if (victim) (*spell_info[spl].spell_pointer)(ch, arg, victim, obj); else if (obj) (*spell_info[spl].spell_pointer)(ch, arg, NULL, obj); else if (!obj) (*spell_info[spl].spell_pointer)(ch, arg, ch, NULL); } break; case SPELL_TYPE_WAND: if(SPELL_FLAGGED(spl, S_WAND) && victim) (*spell_info[spl].spell_pointer)(ch, arg, victim, obj); break; case SPELL_TYPE_STAFF: if(SPELL_FLAGGED(spl, S_STAFF)) for (victim = world[ch->in_room].people; victim; victim = victim->next_in_room) if (victim != ch) (*spell_info[spl].spell_pointer)(ch, arg, victim, obj); break; default : log("SYSERR: unknown spell type to do_cast_spell!"); break; } } ASPELL(spell_chain_lightning) { int size_die, dam; if (!victim) return SPELL_FAILED; /* Mana(ch) -= (Level(ch) * 2); */ size_die = (Level(ch) / 2); dam = dice(size_die, 6); SpellDamage(ch, victim, dam, SPELL_CHAIN_LIGHTNING, FALSE); size_die -= 5; CharsInRoom(ch, victim) { if (!InSameGroup(ch, victim)) { dam = dice(size_die, 6); SpellDamage(ch, victim, dam, SPELL_CHAIN_LIGHTNING, FALSE); size_die -= 5; } } return SPELL_NORMAL; } ASPELL(spell_fireball) { int size_die, dam; /* Mana(ch) -= (Level(ch) * 2); */ size_die = (Level(ch) / 2); dam = dice(size_die, 6); CharsInRoom(ch, victim) { if (!InSameGroup(ch, victim)) { dam = dice(size_die, 6); SpellDamage(ch, victim, dam, SPELL_FIREBALL, FALSE); } } return SPELL_NORMAL; } // Animate dead added per request of Mouseglove... 08/06/98 -callahan ASPELL(spell_animate_dead) { AffType af, af2; CharData *mob; ObjData *corpse, *next_corpse, *tobj, *next_obj; int mobnum, corpses = 0; if (affected_by_spell(ch, SPELL_ANIMATE_DEAD)) { SendChar("You are already in the process of animating the dead.\r\n", ch); return SPELL_FAILED; } if (MaxSummons(ch)) return SPELL_FAILED; for (corpse = world[InRoom(ch)].contents; corpse; corpse = next_corpse) { next_corpse = corpse->next_content; if (CAN_SEE_OBJ(ch, corpse) && (ITEM_TYPE(corpse) == ITEM_CONTAINER) && corpse->value[3]) { corpses++; if (corpses < (Level(ch) / 10)) { if (Mana(ch) < Level(ch)) { SendChar(tprintf("You haven't enough energy to animate anything%s." "\r\n", (corpses > 1) ? " else" : ""), ch); return SPELL_NORMAL; } if (InRange(Level(ch), 60, 75)) mobnum = 739; else if (InRange(Level(ch), 55, 75)) mobnum = 738; else if (InRange(Level(ch), 50, 75)) mobnum = 737; else if (InRange(Level(ch), 45, 75)) mobnum = 736; else if (InRange(Level(ch), 40, 75)) mobnum = 735; else if (InRange(Level(ch), 35, 75)) mobnum = 734; else if (InRange(Level(ch), 30, 75)) mobnum = 733; else if (InRange(Level(ch), 25, 75)) mobnum = 732; else if (InRange(Level(ch), 20, 75)) mobnum = 731; else if (InRange(Level(ch), 15, 75)) mobnum = 730; mobnum = number(730, mobnum); if (!(mob = read_mobile(mobnum, VIRTUAL))) { SendChar("Seek immortal assistance, undead non-existance error.\n\r", ch); return SPELL_FAILED; } Mana(ch) -= Level(ch); SET_BIT(CHAR_FLAGS(mob), CH_SUMMONED); SUMMONER(mob) = GET_IDNUM(ch); char_to_room(mob, InRoom(ch)); act(tprintf("$n waves $s arms over %s, chanting in dark undertones.", corpse->shdesc), TRUE, ch, 0, 0, TO_ROOM); SendChar(tprintf("You wave your arms, and begin to animate %s.\r\n", corpse->shdesc), ch); act("$n slowly rises from the ground.", FALSE, mob, 0, 0, TO_ROOM); add_follower(mob, ch); for (tobj = corpse->contains; tobj; tobj = next_obj) { next_obj = tobj->next_content; obj_from_obj(tobj); obj_to_char(tobj, mob); } NewAffect(&af); af.type = SPELL_ANIMATE_DEAD; af.bitvector = AFF_CHARM; af.duration = -1; affect_to_char(mob, &af); NewAffect(&af2); af2.type = SPELL_ANIMATE_DEAD; af2.duration = 1; af2.bitvector = AFF_HOLD; affect_to_char(mob, &af2); extract_obj(corpse); } else return SPELL_NORMAL; } } // If anything was animated, set spell on char to notify when animation // is finished. 08/10/98 -callahan if (corpses) { NewAffect(&af); af.type = SPELL_ANIMATE_DEAD; af.duration = 1; affect_to_char(ch, &af); } else { SendChar("You do not see anything dead around here...\r\n", ch); return SPELL_FAILED; } return SPELL_NORMAL; } ASPELL(spell_magic_missile) { int dam = 0, num_missile = 0, missile_cnt = 0; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; num_missile = (level/10) + 1; for (missile_cnt=1; missile_cnt <= num_missile; missile_cnt++) dam += number(1,4); SpellDamage(ch, victim, dam, SPELL_MAGIC_MISSILE, FALSE); return SPELL_NORMAL; } ASPELL(spell_chill_touch) { struct affected_type af; int dam; if (!victim) return SPELL_FAILED; dam = number(1,7) + 7; if (!saves_spell(victim, SPELL_CHILL_TOUCH)) { af.type = SPELL_CHILL_TOUCH; af.duration = 6; af.modifier = -1; af.location = APPLY_STR; af.bitvector = 0; af.bitvector2 = 0; affect_join(victim, &af, TRUE, FALSE); } else dam >>= 1; damage(ch, victim, dam, SPELL_CHILL_TOUCH, FALSE); return SPELL_NORMAL; } ASPELL(spell_burning_hands) { int dam; if (!victim) return SPELL_FAILED; dam = number(10,20); SpellDamage(ch, victim, dam, SPELL_BURNING_HANDS, FALSE); return SPELL_NORMAL; } ASPELL(spell_shocking_grasp) { int dam; if (!victim) return SPELL_FAILED; dam = number(1,10) + 25; SpellDamage(ch, victim, dam, SPELL_SHOCKING_GRASP, FALSE); return SPELL_NORMAL; } // Modified damage. 08/13/98 -callahan ASPELL(spell_lightning_bolt) { int dam; if (!victim) return SPELL_FAILED; /* Mana(ch) -= Level(ch); */ dam = dice(Level(ch) / 2, 6); SpellDamage(ch, victim, dam, SPELL_LIGHTNING_BOLT, FALSE); return SPELL_NORMAL; } ASPELL(spell_colour_spray) { int dam; if (!victim) return SPELL_FAILED; dam = number(40,60); SpellDamage(ch, victim, dam, SPELL_COLOUR_SPRAY, FALSE); return SPELL_NORMAL; } ASPELL(spell_energy_drain) { int dam, xp, mana; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if (IN_ARENA(ch) || IN_ARENA(victim)) { act("You can no longer use this spell in an arena.",FALSE,ch,0,0,TO_CHAR); return SPELL_FAILED; } if (!saves_spell(victim, SPELL_ENERGY_DRAIN)) { GET_ALIGNMENT(ch) = MAX(-1000, GET_ALIGNMENT(ch) - 200); if (GET_LEVEL(victim) <= 2) damage(ch, victim, 100, SPELL_ENERGY_DRAIN, FALSE); else { xp = number(level >> 1, level) * 1000; gain_exp(victim, -xp); dam = dice(1, 10); mana = GET_MANA(victim) >> 1; GET_MOVE(victim) >>= 1; GET_MANA(victim) = mana; GET_MANA(ch) += mana >> 1; GET_HIT(ch) += dam; act("Your life energy is drained!",FALSE,victim,0,0,TO_CHAR); damage(ch, victim, dam, SPELL_ENERGY_DRAIN, FALSE); } } else damage(ch, victim, 0, SPELL_ENERGY_DRAIN, FALSE); /* Miss */ return SPELL_NORMAL; } // Changed from spell_fireball. 08/13/98 -callahan ASPELL(spell_fireflash) { int dam; if (!victim) return SPELL_FAILED; /* Mana(ch) -= Level(ch); */ dam = dice(Level(ch) / 2, 6); SpellDamage(ch, victim, dam, SPELL_FIREFLASH, FALSE); return SPELL_NORMAL; } ASPELL(spell_earthquake) { int dam; chdata *tmp_victim, *temp; BOOL pc = 0; int level = GET_LEVEL(ch); if (IN_NOWHERE(ch)) return SPELL_FAILED; dam = dice(1, 8) + level; act("The earth trembles beneath your feet!", FALSE, ch, 0, 0, TO_CHAR); act("$n makes the earth tremble and shiver!\n\rYou fall, and hit yourself!", FALSE, ch, 0, 0, TO_ROOM); if (IS_PC(ch)) pc = TRUE; for (tmp_victim = character_list; tmp_victim; tmp_victim = temp) { temp = tmp_victim->next; if (SAME_ROOM(ch, tmp_victim) && ch != tmp_victim && ((pc && IS_NPC(tmp_victim)) || (!pc && IS_PC(tmp_victim)))) { if (GET_POS(tmp_victim) == POS_SLEEPING) do_wake(tmp_victim, "", 0, 0); // fix NOKILL mobs taking damage here 5/29/98 -jtrhone // also ppl in flight or truced... if (!SPC_FLAGGED(tmp_victim, SPC_NOKILL) && !IS_FLYING(tmp_victim) && check_truce(ch, tmp_victim)) damage(ch, tmp_victim, dam, SPELL_EARTHQUAKE, FALSE); } else if (world[ch->in_room].zone == world[tmp_victim->in_room].zone) send_to_char("The earth trembles and shivers!\n\r", tmp_victim); } return SPELL_NORMAL; } ASPELL(spell_dispel_evil) { int dam; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if (IS_EVIL(ch)) victim = ch; else if (!IS_EVIL(victim)) { act("$N is not evil.", FALSE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } if ((GET_LEVEL(victim) <= level) || (victim == ch)) dam = 100; else { dam = dice(level, 4); if (saves_spell(victim, SPELL_DISPEL_EVIL)) dam >>= 1; } damage(ch, victim, dam, SPELL_DISPEL_EVIL, FALSE); return SPELL_NORMAL; } ASPELL(spell_call_lightning) { int dam; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; dam = dice(MIN(level, 15), 8); SpellDamage(ch, victim, dam, SPELL_CALL_LIGHTNING, FALSE); return SPELL_NORMAL; } ASPELL(spell_harm) { int dam; if (!victim) return SPELL_FAILED; dam = GET_HIT(victim) - dice(1, 4); if (dam < 0) dam = 0; else if (saves_spell(victim, SPELL_HARM)) dam = MIN(30, dam / 3); damage(ch, victim, dam, SPELL_HARM, FALSE); return SPELL_NORMAL; } ASPELL(spell_armor) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_ARMOR) && !affected_by_spell(victim, SPELL_STONE_SKIN) && !affected_by_spell(victim, SPELL_BARKSKIN)) { af.type = SPELL_ARMOR; af.duration = 24; af.modifier = -GET_LEVEL(ch); af.location = APPLY_AC; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(victim, &af); if (ch == victim) { act("You protect yourself with a mystical armor!", FALSE, ch, 0, 0, TO_CHAR); act("$n protects $mself with a mystical armor!", FALSE, ch, 0, 0, TO_ROOM); } else { act("You protect $N with a mystical armor!", FALSE, ch, 0, victim, TO_CHAR); act("$n protects you with $s mystical armor!", FALSE, ch, 0, victim, TO_VICT); } } else { if (victim == ch) act("You are already protected!", FALSE, ch, 0, 0, TO_CHAR); else act("$N is already protected!", FALSE, ch, 0, victim, TO_CHAR); } return SPELL_NORMAL; } ASPELL(spell_teleport) { int to_room; if (ROOM_FLAGGED(ch->in_room, NO_TELEPORT)) { send_to_char("Forces beyond your comprehension prevent you from teleporting.\n\r",ch); return SPELL_NORMAL; } do { to_room = number(0, (top_of_world-1)); } while (ROOM_FLAGGED(to_room, PRIVATE) || ROOM_FLAGGED(to_room, NO_TELEPORT) || ZONE_FLAGGED(world[to_room].zone, Z_CLOSED) || ZONE_FLAGGED(world[to_room].zone, Z_LOCKED) || ZONE_FLAGGED(world[to_room].zone, Z_TEST) || ZONE_FLAGGED(world[to_room].zone, Z_IMMORT) || (IN_ARENA(ch) != ZONE_FLAGGED(world[to_room].zone, Z_ARENA)) || (MOB_FLAGGED(ch, MOB_STAY_ZONE) && world[to_room].zone != GET_MOB_VNUM(ch) / 100) ) ; act("You slowly fade out of existence.", FALSE, ch, 0, 0, TO_CHAR); act("$n slowly fades out of existence.", FALSE, ch, 0, 0, TO_ROOM); char_from_room(ch); char_to_room(ch, to_room); act("You slowly fade into existence.", FALSE, ch, 0, 0, TO_CHAR); act("$n slowly fades into existence.", FALSE, ch, 0, 0, TO_ROOM); do_look_at_room(ch, 15, 0); if (check_room_affects(ch, ch->in_room) == CHAR_DIED) return SPELL_NORMAL; if (check_death_trap(ch, NULL)) return SPELL_NORMAL; return SPELL_NORMAL; } ASPELL(spell_bless) { struct affected_type af; if (obj) { if (GET_LEVEL(ch) < obj->min_level) send_to_char("That object is too powerful for you to bless.\n\r",ch); else if ( (5 * GET_LEVEL(ch) > GET_OBJ_WEIGHT(obj)) && (!FIGHTING(ch)) && !OBJ_FLAGGED(obj, ITEM_EVIL)) { SET_BIT(OBJ_EXTRAS(obj), ITEM_BLESS); act("$p briefly glows %4%Bblue%0.", FALSE, ch, obj, 0, TO_ROOM); } } else { if (!victim) return SPELL_FAILED; if (FIGHTING(victim)) { send_to_char("You cannot be blessed while fighting!\n\r",victim); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_BLESS)) { af.type = SPELL_BLESS; af.duration = 6; af.modifier = 1; af.location = APPLY_HITROLL; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(victim, &af); af.location = APPLY_SV_MAGIC; af.modifier = 5; /* Make better */ affect_to_char(victim, &af); if (ch == victim) { act("You bless yourself with the goodness of the gods!", FALSE, ch, 0, 0, TO_CHAR); act("$n blesses $mself!", FALSE, ch, 0, 0, TO_ROOM); } else { act("You bless $N with the goodness of the gods!", FALSE, ch, 0, victim, TO_CHAR); act("$n blesses you with $s mystical spell!", FALSE, ch, 0, victim, TO_VICT); } } else send_to_char("You are already affected by some type of blessing.\n\r",victim); } return SPELL_NORMAL; } ASPELL(spell_blindness) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!check_mortal_combat(ch, victim)) /* then its worth a saving throw*/ return SPELL_FAILED; if (saves_spell(victim, SPELL_BLINDNESS) || MOB_FLAGGED(victim, MOB_NO_BLIND)) { if (ch != victim) act("$N repels your spell.",TRUE,ch,0,victim,TO_CHAR); else act("You repel your spell...?",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_BLINDNESS)) { af.type = SPELL_BLINDNESS; af.location = APPLY_HITROLL; af.modifier = -(GET_LEVEL(ch)/3); /* Make hitroll WAY worse */ af.duration = 1; af.bitvector = AFF_BLIND; af.bitvector2 = 0; affect_to_char(victim, &af); af.location = APPLY_AC; af.modifier = + 20; /* Make AC Worse! */ affect_to_char(victim, &af); act("$n seems to be blinded!", TRUE, victim, 0, 0, TO_ROOM); act("You have been blinded!",FALSE,victim,0,0,TO_CHAR); } else send_to_char("Luckily, you are already blind!\n\r",victim); return SPELL_NORMAL; } // spell knock, opens locked or jammed doors... 4/26/98 -jtrhone ASPELL(spell_knock) { int dir, other_room; rmdirdata *d, *back; char *argu = arg; skip_spaces(&argu); if (!*argu) { send_to_char("You must supply the direction...\n\r",ch); return SPELL_NORMAL; } dir = search_block(argu, comm_dirs, FALSE); if (dir < 0 || dir > NUM_OF_DIRS) { send_to_char("You must supply the direction...\n\r",ch); return SPELL_NORMAL; } if (!(d = EXIT(ch, dir))) { act("It would be fairly difficult to do that there.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } if (!EXIT_ISDOOR(d)) act("It would be fairly difficult to do that there.",FALSE,ch,0,0,TO_CHAR); else if (EXIT_OPEN(d)) send_to_char("It's open!\n\r", ch); else if (!EXIT_LOCKED(d) && !EXIT_JAMMED(d)) send_to_char("It's not locked or jammed!\n\r", ch); else if (EXIT_FLAGGED(d, EX_NOBASH) || EXIT_FLAGGED(d, EX_PICKPROOF)) send_to_char("You fail to knock that exit.\n\r", ch); else { UNFLAG_EXIT(d, EX_LOCKED | EX_JAMMED); if (d->keyword) { act("You knock the $F open!", FALSE, ch, 0, d->keyword, TO_CHAR); act("$n knocks the $F open!", TRUE, ch, 0, d->keyword, TO_ROOM); } else { act("You knock it open!", FALSE, ch, 0, 0, TO_CHAR); act("$n knocks something open!", TRUE, ch, 0, 0, TO_ROOM); } /* now for jamming the other side, too */ if ((other_room = d->to_room) != NOWHERE) if ((back = DIR(other_room, rev_dir[dir]))) if (back->to_room == ch->in_room) UNFLAG_EXIT(back, EX_LOCKED | EX_JAMMED); } return SPELL_NORMAL; } ASPELL(spell_control_weather) { char *argu = arg; int zone, temp; void stop_precip(int zone); void begin_precip(int zone); void send_zone_temp_updates(int zone); if (!*argu) { send_to_char("Usage: cast 'control weather' " "< wetter | drier | warmer | cooler >\n\r",ch); return SPELL_NORMAL; } if (INVALID_ROOM(ch->in_room) || !WEATHER_ROOM(ch->in_room)) { send_to_char("You cannot control the weather from this area.\n\r",ch); return SPELL_NORMAL; } zone = world[ch->in_room].zone; skip_spaces(&argu); if (is_abbrev(argu, "wetter")) { if (IS_PRECIPPING(zone)) { send_to_char("Your spell has no affect.\n\r",ch); return SPELL_NORMAL; } if (GET_LEVEL(ch) > number(1, 100)) begin_precip(zone); } else if (is_abbrev(argu, "drier")) { if (!IS_PRECIPPING(zone)) { send_to_char("Your spell has no affect.\n\r",ch); return SPELL_NORMAL; } if (GET_LEVEL(ch) > number(1, 100)) stop_precip(zone); } else if (is_abbrev(argu, "warmer")) { temp = GET_LEVEL(ch) / 2 + GET_INT(ch); zone_table[zone].current_gtemp += temp; send_zone_temp_updates(zone); } else if (is_abbrev(argu, "cooler")) { temp = GET_LEVEL(ch) / 2 + GET_INT(ch); zone_table[zone].current_gtemp -= temp; send_zone_temp_updates(zone); } else { send_to_char("Usage: cast 'control weather' " "< wetter | drier | warmer | cooler >\n\r",ch); return SPELL_NORMAL; } return SPELL_NORMAL; } ASPELL(spell_create_water) { int water; int level = GET_LEVEL(ch); void name_to_drinkcon(obdata *obj, int type); void name_from_drinkcon(obdata *obj); // ok, if its a canteen or fountain type... if ((ITEM_TYPE(obj) == ITEM_DRINKCON) || (ITEM_TYPE(obj) == ITEM_FOUNTAIN)) { // if it doesn't have wawa in it, AND it's not empty (better both be right) if ((obj->value[2] != LIQ_WATER) && (obj->value[1] != 0)) { // pull the first liquid name from it name_from_drinkcon(obj); // replace it with slime obj->value[2] = LIQ_SLIME; name_to_drinkcon(obj, LIQ_SLIME); } else { water = 2 * level; /* Calculate water it can contain, or water created */ water = MIN(obj->value[0] - obj->value[1], water); if (water > 0) { obj->value[2] = LIQ_WATER; obj->value[1] += water; weight_change_object(obj, water); name_from_drinkcon(obj); name_to_drinkcon(obj, LIQ_WATER); act("$p is filled.", FALSE, ch, obj, 0, TO_CHAR); } } } else act("You try, but are unable to fill $p!", FALSE, ch, obj, 0, TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_cure_blind) { if (!victim) return SPELL_FAILED; if (affected_by_spell(victim, SPELL_BLINDNESS)) { affect_from_char(victim, SPELL_BLINDNESS); if (ch == victim) act("Your vision returns!",FALSE,victim,0,0,TO_CHAR); else act("$N's vision returns!",FALSE, ch, 0, victim, TO_NOTVICT); return SPELL_NORMAL; } if (affected_by_spell(victim, SPELL_SPIRITLEAVES)) { affect_from_char(victim, SPELL_SPIRITLEAVES); if (ch == victim) act("Your vision returns!",FALSE,victim,0,0,TO_CHAR); else act("$N's vision returns!",FALSE, ch, 0, victim, TO_NOTVICT); return SPELL_NORMAL; } if (ch == victim) act("You are not blind!",FALSE,victim,0,0,TO_CHAR); else act("$N is not blind!",FALSE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_cure_critic) { int healpoints; if (!victim) return SPELL_FAILED; healpoints = dice(4, 8) + 3; if ( (healpoints + GET_HIT(victim)) > GET_MAX_HIT(victim)) GET_HIT(victim) = GET_MAX_HIT(victim); else GET_HIT(victim) += healpoints; if (ch != victim) { act("$n cures some of your wounds.",FALSE,ch,0,victim,TO_VICT); act("You cure some of $S wounds.",FALSE,ch,0,victim,TO_CHAR); } else act("You cure some of your wounds.",FALSE,ch,0,0,TO_CHAR); update_pos(victim); return SPELL_NORMAL; } ASPELL(spell_cure_light) { int healpoints; if (!victim) return SPELL_FAILED; healpoints = dice(2, 8); if ( (healpoints + GET_HIT(victim)) > GET_MAX_HIT(victim)) GET_HIT(victim) = GET_MAX_HIT(victim); else GET_HIT(victim) += healpoints; if (ch != victim) { act("$n cures some of your wounds.",FALSE,ch,0,victim,TO_VICT); act("You cure some of $S wounds.",FALSE,ch,0,victim,TO_CHAR); } else act("You cure some of your wounds.",FALSE,ch,0,0,TO_CHAR); update_pos( victim ); return SPELL_NORMAL; } ASPELL(spell_curse) { struct affected_type af; if (obj) { SET_BIT(OBJ_EXTRAS(obj), ITEM_EVIL); SET_BIT(OBJ_EXTRAS(obj), ITEM_NODROP); /* LOWER ATTACK DICE BY -1 */ if (IS_WEAPON(obj)) { if (obj->value[2] > 1) { obj->value[2]--; act("$p glows red.", FALSE, ch, obj, 0, TO_CHAR); } else send_to_char("Nothing happens.\n\r", ch); } else send_to_char("Nothing happens.\n\r", ch); } else { if (!victim) return SPELL_FAILED; if (saves_spell(victim, SPELL_CURSE)) { act("$N resists your attempt!",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_CURSE)) { af.type = SPELL_CURSE; af.duration = 24 * 7; /* 7 Days */ af.modifier = -1; af.location = APPLY_HITROLL; af.bitvector = AFF_CURSE; af.bitvector2 = 0; affect_to_char(victim, &af); af.location = APPLY_SV_MAGIC; af.modifier = -30; /* Make worse */ affect_to_char(victim, &af); act("$n briefly reveals a red aura!", FALSE, victim, 0, 0, TO_ROOM); act("You feel very uncomfortable.", FALSE, victim, 0, 0, TO_CHAR); } else send_to_char("Luckily, you are already cursed!\n\r",victim); } return SPELL_NORMAL; } ASPELL(spell_detect_evil) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_DETECT_EVIL)) { af.type = SPELL_DETECT_EVIL; af.duration = level * 5; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_EVIL; af.bitvector2 = 0; affect_to_char(victim, &af); send_to_char("You can now detect the presence of %1evil%0.\n\r",victim); } else send_to_char("You are already affected by detect evil.\n\r",victim); return SPELL_NORMAL; } ASPELL(spell_detect_invisibility) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; af.type = SPELL_DETECT_INVISIBLE; af.duration = level * 5; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_INVISIBLE; af.bitvector2 = 0; affect_join(victim, &af, TRUE, FALSE); send_to_char("Your eyes tingle.\n\r", victim); return SPELL_NORMAL; } ASPELL(spell_detect_magic) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if ( affected_by_spell(victim, SPELL_DETECT_MAGIC) ) { if (ch != victim) act("$E is already affected by detect magic.",FALSE,ch,0,victim,TO_CHAR); else act("You are already affected by detect magic.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.type = SPELL_DETECT_MAGIC; af.duration = level * 5; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_MAGIC; af.bitvector2 = 0; affect_to_char(victim, &af); send_to_char("Your eyes tingle.\n\r", victim); return SPELL_NORMAL; } ASPELL(spell_detect_poison) { if (victim) { if (victim == ch) { if (IS_AFFECTED(victim, AFF_POISON)) send_to_char("You can sense poison in your blood.\n\r", ch); else send_to_char("You feel healthy.\n\r", ch); } else if (IS_AFFECTED(victim, AFF_POISON)) act("You sense that $E is poisoned.", FALSE, ch, 0, victim, TO_CHAR); else act("You sense that $E is healthy.", FALSE, ch, 0, victim, TO_CHAR); } else // it's an object { if ((obj->type_flag == ITEM_DRINKCON) || (obj->type_flag == ITEM_FOUNTAIN) || (obj->type_flag == ITEM_FOOD)) { if (obj->value[3]) act("Poisonous fumes are revealed.", FALSE, ch, 0, 0, TO_CHAR); else send_to_char("It looks very delicious.\n\r", ch); } else send_to_char("You are unsure...\n\r", ch); } return SPELL_NORMAL; } ASPELL(spell_enchant_weapon) { int i; int level = GET_LEVEL(ch); if (IS_WEAPON(obj) && !IS_SET(OBJ_EXTRAS(obj), ITEM_MAGIC)) { for (i = 0; i < MAX_OBJ_AFFECT; i++) if (obj->affected[i].location != APPLY_NONE) { act("$p cannot be enchanted any further.", FALSE, ch, obj, 0,TO_CHAR); return SPELL_NORMAL; } SET_BIT(OBJ_EXTRAS(obj), ITEM_MAGIC); obj->affected[0].location = APPLY_HITROLL; obj->affected[0].modifier = 1 + (level >= 18); obj->affected[1].location = APPLY_DAMROLL; obj->affected[1].modifier = 1 + (level >= 20); if (IS_GOOD(ch)) { SET_BIT(OBJ_EXTRAS(obj), ITEM_ANTI_EVIL); act("$p glows %B%4blue%0.", FALSE, ch, obj, 0, TO_CHAR); } else if (IS_EVIL(ch)) { SET_BIT(OBJ_EXTRAS(obj), ITEM_ANTI_GOOD); act("$p glows %1red%0.", FALSE, ch, obj, 0, TO_CHAR); } else { act("$p glows %B%3yellow%0.", FALSE, ch, obj, 0, TO_CHAR); } } else if (IS_SET(OBJ_EXTRAS(obj), ITEM_MAGIC)) act("$p cannot be enchanted any further.",FALSE,ch,obj,0,TO_CHAR); else if (!IS_WEAPON(obj)) act("$p is not an enchantable object.",FALSE,ch,obj,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_recharge) { if ((ITEM_TYPE(obj) != ITEM_STAFF && ITEM_TYPE(obj) != ITEM_WAND) || !OBJ_FLAGGED(obj, ITEM_RECHARGE)) { act("$p cannot be recharged.", FALSE, ch, obj, 0, TO_CHAR); return SPELL_NORMAL; } if (MAX_CHARGES(obj) < 1) { act("$p cannot be recharged.", FALSE, ch, obj, 0, TO_CHAR); return SPELL_NORMAL; } if (CHARGES_LEFT(obj) >= MAX_CHARGES(obj)) { act("$p is already fully charged.", FALSE, ch, obj, 0, TO_CHAR); return SPELL_NORMAL; } // if the minlevel is too high OR the spell level is too high, no go if (obj->min_level > GET_LEVEL(ch) || obj->value[0] > GET_LEVEL(ch)) { act("$p is too powerful for you to recharge.", FALSE, ch, obj, 0, TO_CHAR); return SPELL_NORMAL; } CHARGES_LEFT(obj) = MAX_CHARGES(obj); act("You recharge $p.", FALSE, ch, obj, 0, TO_CHAR); act("$n recharges $p.", FALSE, ch, obj, 0, TO_ROOM); return SPELL_NORMAL; } ASPELL(spell_heal) { if (!victim) return SPELL_FAILED; if (affected_by_spell(victim, SPELL_BLINDNESS) || affected_by_spell(victim, SPELL_SPIRITLEAVES)) spell_cure_blind(ch, arg, victim, obj); GET_HIT(victim) += (100 - dice(1,4)); /* changed this spell -jtrhone*/ GET_HIT(victim) = MIN(GET_MAX_HIT(victim), GET_HIT(victim)); update_pos(victim); act("A %1warm%0 feeling fills your body...",FALSE,victim,0,0,TO_CHAR); act("You suddenly feel much better!",FALSE,victim,0,0,TO_CHAR); act("$n suddenly looks much healthier.", FALSE, victim, 0, 0, TO_ROOM); return SPELL_NORMAL; } ASPELL(spell_invisibility) { struct affected_type af; if (obj) { if (IS_SET(OBJ_EXTRAS(obj), ITEM_NOINVIS)) { act("$p resists all your efforts.",FALSE,ch,obj,0,TO_CHAR); return SPELL_NORMAL; } if (!IS_SET(OBJ_EXTRAS(obj), ITEM_INVISIBLE) ) { act("$p %4fades out of existence%0.", FALSE, ch, obj, 0, TO_CHAR); act("$p %4fades out of existence%0.", TRUE, ch, obj, 0, TO_ROOM); SET_BIT(OBJ_EXTRAS(obj), ITEM_INVISIBLE); } } else if (victim) { if (!affected_by_spell(victim, SPELL_INVISIBLE)) { af.type = SPELL_INVISIBLE; af.duration = 24; af.modifier = -40; af.location = APPLY_AC; af.bitvector = AFF_INVISIBLE; af.bitvector2 = 0; affect_to_char(victim, &af); act("$n slowly %4fades out of existence%0.", TRUE, victim, 0, 0, TO_ROOM); act("You feel yourself fade out of existence.",FALSE,victim,0,0,TO_CHAR); } else send_to_char("You are already invisible.\n\r",victim); } return SPELL_NORMAL; } ASPELL(spell_locate_object) { int j, level = GET_LEVEL(ch); obdata *i; if (strlen(arg) > MAX_INPUT_LENGTH - 10) { send_to_char("Argument too long.\n\r",ch); return SPELL_FAILED; } j = level >> 1; act("You concentrate yourself....", FALSE, ch, 0, 0, TO_CHAR); act("$n sinks into deep concentration.", FALSE, ch, 0, 0, TO_ROOM); // added some more error protection... 7/9/98 -jtrhone for (i = object_list; i && j; i = i->next) if (i->name && *i->name && i->shdesc && *i->shdesc) if (isname(arg, i->name) && !OBJ_FLAGGED(i, ITEM_NOLOCATE)) { if (i->carried_by && GET_LEVEL(ch) >= GET_INVIS_LEV(i->carried_by)) { sprintf(buf, "%s carried by %s.\n\r", i->shdesc, PERS(i->carried_by, ch)); CCAP(buf); S2C(); j--; } else if (i->in_obj) { sprintf(buf, "%s in %s.\n\r", i->shdesc, i->in_obj->shdesc ? i->in_obj->shdesc : "something"); CCAP(buf); S2C(); j--; } else if (!INVALID_ROOM(i->in_room)) { sprintf(buf, "%s in %s.\n\r", i->shdesc, world[i->in_room].name ? world[i->in_room].name : "somewhere"); CCAP(buf); S2C(); j--; } } if (!j) send_to_char("Your head begins to pound.\n\r", ch); else if (j == (level >> 1)) send_to_char("No such object.\n\r", ch); return SPELL_NORMAL; } ASPELL(spell_poison) { struct affected_type af; if (victim) { if (affected_by_spell(victim, SKILL_CLEANSE)) { act("$N resists the poison!",TRUE, ch, 0, victim, TO_NOTVICT); act("You resist the poison!",TRUE, ch, 0, victim, TO_VICT); act("$N resists your poisonous attempt!",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } else if (!saves_spell(victim, SPELL_POISON)) { af.type = SPELL_POISON; af.duration = GET_LEVEL(ch) * 2; af.modifier = -2; af.location = APPLY_STR; af.bitvector = AFF_POISON; af.bitvector2 = 0; affect_join(victim, &af, FALSE, FALSE); act("You feel very sick.", TRUE, victim, 0, 0, TO_CHAR); act("$n suddenly looks sick.", TRUE, victim, 0, 0, TO_ROOM); } else { act("$N resists the poison!",TRUE, ch, 0, victim, TO_NOTVICT); act("You resist the poison!",TRUE, ch, 0, victim, TO_VICT); act("$N resists your poisonous attempt!",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } } else if (obj) if ((obj->type_flag == ITEM_DRINKCON) || (obj->type_flag == ITEM_FOUNTAIN) || (obj->type_flag == ITEM_FOOD)) { obj->value[3] = TRUE; act("You poison $p!",TRUE, ch, obj, 0, TO_CHAR); act("$n poisons $p!",TRUE, ch, obj, 0, TO_ROOM); } return SPELL_NORMAL; } ASPELL(spell_poison_dart) { struct affected_type af; if (victim) { if (affected_by_spell(victim, SKILL_CLEANSE)) { act("$N resists the poison!",TRUE, ch, 0, victim, TO_NOTVICT); act("You resist the poison!",TRUE, ch, 0, victim, TO_VICT); act("$N resists your poisonous attempt!",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } else if (!saves_spell(victim, SPELL_POISON_DART)) { af.type = SPELL_POISON_DART; af.duration = GET_LEVEL(ch) * 2; af.modifier = -2; af.location = APPLY_STR; af.bitvector = AFF_POISON; af.bitvector2 = 0; affect_join(victim, &af, FALSE, FALSE); act("You feel very sick.", TRUE, victim, 0, 0, TO_CHAR); act("$n suddenly looks sick.", TRUE, victim, 0, 0, TO_ROOM); } else { act("$N resists the poison!",TRUE, ch, 0, victim, TO_NOTVICT); act("You resist the poison!",TRUE, ch, 0, victim, TO_VICT); act("$N resists your poisonous attempt!",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } } else if (obj) if ((obj->type_flag == ITEM_DRINKCON) || (obj->type_flag == ITEM_FOUNTAIN) || (obj->type_flag == ITEM_FOOD)) { obj->value[3] = TRUE; act("You poison $p!",TRUE, ch, obj, 0, TO_CHAR); act("$n poisons $p!",TRUE, ch, obj, 0, TO_ROOM); } return SPELL_NORMAL; } ASPELL(spell_protection_from_evil) { struct affected_type af; if (!victim) return SPELL_NORMAL; if (!affected_by_spell(victim, SPELL_PROTECT_FROM_EVIL)) { af.type = SPELL_PROTECT_FROM_EVIL; af.duration = 24; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_PROTECT_EVIL; af.bitvector2 = 0; affect_to_char(victim, &af); act("You have a righteous feeling!",FALSE,victim,0,0,TO_CHAR); act("A faint %Bwhite%0 aura surrounds $n.", TRUE, victim, 0, 0, TO_ROOM); } else send_to_char("You are already protected from evil.\n\r",victim); return SPELL_NORMAL; } ASPELL(spell_remove_curse) { if (obj) { if (GET_LEVEL(ch) < obj->min_level) send_to_char("That object is too powerful for you, the curse remains.\n\r",ch); else if (IS_SET(OBJ_EXTRAS(obj), ITEM_EVIL) || IS_SET(OBJ_EXTRAS(obj), ITEM_NODROP)) { act("$p briefly glows %B%6blue%0.", TRUE, ch, obj, 0, TO_CHAR); REMOVE_BIT(OBJ_EXTRAS(obj), ITEM_EVIL); REMOVE_BIT(OBJ_EXTRAS(obj), ITEM_NODROP); } } else { /* Then it is a PC | NPC */ if (!victim) return SPELL_FAILED; if (affected_by_spell(victim, SPELL_CURSE) ) { act("$n briefly glows %1red%0, then %6blue%0.", FALSE, victim, 0, 0, TO_ROOM); act("You feel better.", FALSE, victim, 0, 0, TO_CHAR); affect_from_char(victim, SPELL_CURSE); } else act("$N is not cursed.", FALSE, ch, 0, victim, TO_CHAR); } return SPELL_NORMAL; } ASPELL(spell_remove_poison) { if (victim) { if (affected_by_spell(victim, SPELL_POISON)) { affect_from_char(victim, SPELL_POISON); act("You feel %6ice%0 flow through your body.", FALSE, victim, 0, 0, TO_CHAR); act("You feel better!", FALSE, victim, 0, 0, TO_CHAR); act("$N's eyes open wide for a brief moment.", FALSE, ch, 0, victim, TO_ROOM); if (ch != victim) act("You remove the %2poison%0 from $S blood.",FALSE,ch,0,victim,TO_CHAR); else act("You remove the %2poison%0 from your blood.",FALSE,ch,0,0,TO_CHAR); } else if (affected_by_spell(victim, SPELL_POISON_DART)) { affect_from_char(victim, SPELL_POISON_DART); act("You feel %6ice%0 flow through your body.", FALSE, victim, 0, 0, TO_CHAR); act("You feel better!", FALSE, victim, 0, 0, TO_CHAR); act("$N's eyes open wide for a brief moment.", FALSE, ch, 0, victim, TO_ROOM); if (ch != victim) act("You remove the %2poison%0 from $S blood.",FALSE,ch,0,victim,TO_CHAR); else act("You remove the %2poison%0 from your blood.",FALSE,ch,0,0,TO_CHAR); } } else if (obj) { if ((obj->type_flag == ITEM_DRINKCON) || (obj->type_flag == ITEM_FOUNTAIN) || (obj->type_flag == ITEM_FOOD)) { obj->value[3] = 0; act("$p steams briefly.", FALSE, ch, obj, 0, TO_CHAR); } } return SPELL_NORMAL; } ASPELL(spell_sanctuary) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!IS_AFFECTED(victim, AFF_SANCTUARY) && !IS_AFFECTED2(victim,AFF2_CROW)) { af.type = SPELL_SANCTUARY; af.duration = IS_IMMORTAL(ch) ? GET_LEVEL(ch) : 3; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_SANCTUARY; af.bitvector2 = 0; affect_to_char(victim, &af); act("You start %Bglowing%0.", TRUE, victim, 0, 0, TO_CHAR); act("$n is surrounded by a bright %Bwhite%0 aura.", TRUE, victim, 0, 0, TO_ROOM); } else send_to_char("You are already protected by a powerful force.\n\r",victim); return SPELL_NORMAL; } ASPELL(spell_sleep) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!check_mortal_combat(ch, victim)) /* then its worth a saving throw*/ return SPELL_FAILED; if ( !saves_spell(victim, SPELL_SLEEP) ) { af.type = SPELL_SLEEP; af.duration = 2 + number(1, 2); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_SLEEP; af.bitvector2 = 0; affect_join(victim, &af, FALSE, FALSE); if (GET_POS(victim) > POS_SLEEPING) { act("You feel very sleepy ..... zzzzzz.....", FALSE, victim, 0, 0, TO_CHAR); act("$n slowly falls asleep.", TRUE, victim, 0, 0, TO_ROOM); GET_POS(victim) = POS_SLEEPING; } } else { if (ch != victim) act("$N repels your spell.",TRUE,ch,0,victim,TO_CHAR); else act("You repel your spell...?",TRUE,ch,0,victim,TO_CHAR); } return SPELL_NORMAL; } ASPELL(spell_strength) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_STRENGTH)) { af.type = SPELL_STRENGTH; af.duration = GET_LEVEL(ch); af.modifier = 1 + (GET_LEVEL(ch) > 31); af.location = APPLY_STR; af.bitvector = 0; af.bitvector2 = 0; act("You feel stronger!", FALSE, victim, 0, 0, TO_CHAR); act("$n looks stronger!", FALSE, victim, 0, 0, TO_ROOM); affect_to_char(victim, &af); } else act("You're already stronger than normal!", FALSE, victim, 0, 0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_ventriloquate) { send_to_char("This spell is currently not implemented.\n\r",ch); return SPELL_NORMAL; } ASPELL(spell_word_of_recall) { int loc_nr, location; BOOL found = FALSE; if (!victim || (IS_NPC(victim) && !victim->desc)) return SPELL_FAILED; if (IS_IMMORTAL(victim) && ch != victim) { send_to_char("Your puny mortal spell has no affect on an IMMORTAL!\n\r",ch); return SPELL_FAILED; } if (ROOM_FLAGGED(victim->in_room, NO_RECALL) || PLR_FLAGGED(victim, PLR_ARENA)) { act("$n tries to recall, but is unsuccessful!", TRUE, victim, 0, 0, TO_ROOM); send_to_char("Forces beyond your comprehension prevent you from recalling.\n\r",ch); return SPELL_FAILED; } if (!(loc_nr = GET_LOADROOM(victim))) loc_nr = (GET_LEVEL(victim) < LEV_IMM) ? DEF_GATEWAY : 1204; for (location = 0; location < top_of_world; location++) if (world[location].number == loc_nr) { found = TRUE; break; } if ((location >= top_of_world) || !found) { send_to_char("You are completely lost.\n\r", victim); return SPELL_FAILED; } /* a location has been found. */ act("$n disappears in a %4cone of darkness%0.", TRUE, victim, 0, 0, TO_ROOM); char_from_room(victim); char_to_room(victim, location); act("$n appears amidst a %1flash of light%0.", TRUE, victim, 0, 0, TO_ROOM); do_look_at_room(victim, 0, 0); if (check_room_affects(victim, victim->in_room) == CHAR_DIED) return SPELL_NORMAL; if (check_death_trap(victim, NULL)) return SPELL_NORMAL; return SPELL_NORMAL; } ASPELL(spell_summon) { sh_int target; sh_int zone; int level = GET_LEVEL(ch); if (IN_NOWHERE(ch)) return SPELL_FAILED; if (!victim) return SPELL_FAILED; if (IN_ARENA(ch) && !arena_info.locked) { send_to_char("You must wait until the arena begins.\n\r",ch); return SPELL_FAILED; } if (GET_LEVEL(victim) > MIN(LEV_IMM - 1, level + 3)) return SPELL_FAILED; if (MOB_FLAGGED(victim, MOB_AGGR)) { sprintf(buf, "As the words escape your lips and %s travels\n\r" "through time and space towards you, you realize that %s is\n\r" "aggressive and might harm you, so you wisely send it back.\n\r", victim->player.short_descr, HMHR(victim)); S2C(); return SPELL_NORMAL; } zone = world[victim->in_room].zone; if (IS_NPC(victim)) { if (MOB_FLAGGED(victim, MOB_NOSUMMON) || ZONE_FLAGGED(zone, Z_CLOSED) || ZONE_FLAGGED(zone, Z_LOCKED)) { act("$N is protected from summoning.",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } if (world[ch->in_room].zone != zone && MOB_FLAGGED(victim, MOB_STAY_ZONE)) { act("$N cannot be summoned from here.",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } if (ROOM_FLAGGED(ch->in_room, NO_MOB)) { act("$N cannot be summoned into this area.",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } // no mobs from outside the arena 6/25/98 -jtrhone if (INVALID_ROOM(victim->in_room) || ZONE_FLAGGED(world[victim->in_room].zone, Z_ARENA)) { act("$N cannot be summoned into this area.",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } } if (ROOM_FLAGGED2(ch->in_room, R_NO_SUMMON)) { act("$N cannot be summoned into this area.",TRUE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } if (IS_PC(victim) && !PRF_FLAGGED(victim, PRF_SUMMONABLE)) { sprintf(buf, "%s just tried to summon you to: %s.\n\r" "%s failed because you have summon protection on.\n\r" "Type NOSUMMON to allow other players to summon you.\n\r", GET_NAME(ch), world[ch->in_room].name, (ch->player.sex == SEX_MALE) ? "He" : "She"); send_to_char(buf, victim); act("You failed because $N has summon protection on.",TRUE,ch,0,victim,TO_CHAR); sprintf(buf, "%s failed summoning %s to %s.", GET_NAME(ch), GET_NAME(victim), world[ch->in_room].name); mudlog(buf, BRF, LEV_IMM, TRUE); return SPELL_NORMAL; } if (IS_NPC(victim) && saves_spell(victim, SPELL_SUMMON) ) { act("$N resists your attempt!",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (IS_PC(victim)) if (IN_ARENA(ch) != IN_ARENA(victim)) { send_to_char("Forces beyond your comprehension prevent you from summoning that player.\n\r",ch); return SPELL_NORMAL; } act("$n disappears suddenly.", TRUE, victim, 0, 0, TO_ROOM); target = ch->in_room; char_from_room(victim); char_to_room(victim, target); act("$n arrives suddenly.", TRUE, victim, 0, 0, TO_ROOM); act("$n has summoned you!", FALSE, ch, 0, victim, TO_VICT); do_look_at_room(victim, 15, 0); if (check_room_affects(victim, victim->in_room) == CHAR_DIED) return SPELL_NORMAL; if (check_death_trap(victim, NULL)) return SPELL_NORMAL; return SPELL_NORMAL; } ASPELL(spell_charm_person) { struct affected_type af; void add_follower(chdata *ch, chdata *leader); if(!ch || !victim) return SPELL_FAILED; if (victim == ch) { send_to_char("You like yourself even better!\n\r", ch); return SPELL_NORMAL; } if (IS_PC(ch) && IS_PC(victim)) /* a player charming another player */ return SPELL_FAILED; /* there's no legal reason to do this. */ if (GET_POS(victim) <= POS_SLEEPING) { send_to_char("Your victim is not paying attention to you.\n\r",ch); return SPELL_NORMAL; } if (CHARMED(victim)) { send_to_char("Your victim is already charmed...\n\r",ch); return SPELL_NORMAL; } if (CHARMED(ch)) { send_to_char("You cannot cast this spell while you are charmed...\n\r",ch); return SPELL_NORMAL; } if (GET_LEVEL(ch) >= GET_LEVEL(victim)) { if (circle_follow(victim, ch)) { send_to_char("Sorry, following in circles can not be allowed.\n\r", ch); return SPELL_NORMAL; } if (MOB_FLAGGED(victim, MOB_NO_CHARM) || IS_IMMORTAL(victim)) { act("$n resists all efforts to be charmed.", FALSE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } if (GET_LEVEL(ch) < LEV_CIMP) if (saves_spell(victim, SPELL_CHARM_PERSON)) { if (number(0,20) > 15) { act("$N is %1%Benraged%0 at your attempt!",FALSE,ch,0,victim,TO_CHAR); do_kill(victim, GET_NAME(ch), 0, 0); } else act("$N resists your attempt!",FALSE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (victim->master) stop_follower(victim); add_follower(victim, ch); af.type = SPELL_CHARM_PERSON; if (GET_INT(victim)) af.duration = 12 * 18 / GET_INT(victim); else af.duration = 36; af.modifier = 0; af.location = 0; af.bitvector = AFF_CHARM; af.bitvector2 = 0; affect_to_char(victim, &af); act("Isn't $n just such a nice fellow?", FALSE, ch, 0, victim, TO_VICT); if (IS_NPC(victim)) REMOVE_BIT(MOB_FLAGS(victim), MOB_SPEC); } return SPELL_NORMAL; } ASPELL(spell_sense_life) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_SENSE_LIFE)) { af.type = SPELL_SENSE_LIFE; af.duration = 5 * level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_SENSE_LIFE; af.bitvector2 = 0; affect_to_char(victim, &af); act("You feel your awareness improve.",FALSE,victim,0,0,TO_CHAR); act("$n seems more aware of $s surroundings.", FALSE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected by sense life.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by sense life.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } // support wvectors 5/29/98 -jtrhone // fixed skill_name reference bug, cleaned up a bit 6/29/98 -jtrhone ASPELL(spell_identify) { int i; BOOL found; if (obj) { act("$n concentrates on $p.", FALSE, ch, obj, 0, TO_ROOM); send_to_char("You feel informed:\n\r", ch); sprinttype(ITEM_TYPE(obj), item_types, buf2); sprintf(buf, "$p is of type: %%B%s%%0", buf2); act(buf, FALSE, ch, obj, 0, TO_CHAR); if (obj->eqaffbit || obj->eqaff2bit) { send_to_char("Item affections:\n\r", ch); if (obj->eqaff2bit) { sprintbit(obj->eqaffbit, affected_bits, buf); strcat(buf, "\n\r"); S2C(); } if (obj->eqaff2bit) { sprintbit(obj->eqaff2bit, affected2_bits, buf); strcat(buf, "\n\r"); S2C(); } } if (OBJ_EXTRAS(obj) || OBJ_EXTRAS2(obj)) { send_to_char("Item specials:\n\r", ch); if (OBJ_EXTRAS(obj)) { sprintbit(OBJ_EXTRAS(obj), extra_bits, buf); strcat(buf, "\n\r"); S2C(); } if (OBJ_EXTRAS2(obj)) { sprintbit(OBJ_EXTRAS2(obj), extra_bits2, buf); strcat(buf, "\n\r"); S2C(); } } if (WV_FLAGS(obj)) { send_to_char("Item occupies: ", ch); sprintbit(WV_FLAGS(obj), wv_bits, buf); strcat(buf, "\n\r"); S2C(); } if (obj->min_level) { sprintf(buf,"Minimum level on object: %d\n\r", obj->min_level); S2C(); } sprintf(buf, "Weight: %d, Value: %d\n\r", obj->weight, obj->cost); S2C(); switch (ITEM_TYPE(obj)) { case ITEM_SCROLL : case ITEM_POTION : sprintf(buf, "Level %d spells of:\n\r",obj->value[0]); S2C(); for (i = 1; i < 4; i++) if (obj->value[i] > 0) { sprintf(buf, "%s\n\r", skill_names[obj->value[i]]); S2C(); } break; case ITEM_WAND : case ITEM_STAFF : sprintf(buf, "Has %d charges, with %d charges left.\n\r", obj->value[1], obj->value[2]); S2C(); sprintf(buf, "Level %d spell of: ", obj->value[0]); S2C(); sprintf(buf, "%s\n\r", obj->value[3] > 0 ? skill_names[obj->value[3]] : ""); S2C(); break; case ITEM_WEAPON : sprintf(buf, "Damage dice: '%dD%d'\n\r", obj->value[1], obj->value[2]); S2C(); break; case ITEM_ARMOR : sprintf(buf, "AC-apply: %d\n\r", obj->value[0]); S2C(); break; } for (found = i = 0; i < MAX_OBJ_AFFECT; i++) if ((obj->affected[i].location != APPLY_NONE) && (obj->affected[i].modifier != 0)) { if (!found) { send_to_char("Can affect you as :\n\r", ch); found = TRUE; } sprinttype(obj->affected[i].location, apply_types, buf2); sprintf(buf, " Affects : %s By %d\n\r", buf2, obj->affected[i].modifier); S2C(); } } else { /* victim */ if (!victim) return SPELL_FAILED; if (IS_PC(victim)) { if (victim != ch) { act("$n concentrates on $N.", FALSE, ch, 0, victim, TO_ROOM); act("You concentrate on $N.", FALSE, ch, 0, victim, TO_CHAR); act("$n stares deep into your eyes.", FALSE, ch, 0, victim, TO_VICT); } else { act("You concentrate on yourself.", FALSE, ch, 0, 0, TO_CHAR); act("$n concentrates on $mself.", FALSE, ch, 0, 0, TO_ROOM); } sprintf(buf, "%d Years, %d Months, %d Days, %d Hours old.\n\r", age(victim).year, age(victim).month, age(victim).day, age(victim).hours); S2C(); sprintf(buf, "Height %dcm Weight %dpounds \n\r", GET_HEIGHT(victim), GET_WEIGHT(victim)); S2C(); sprintf(buf, "Str %d/%d, Int %d, Wis %d, Dex %d, Con %d\n\r", GET_STR(victim), GET_ADD(victim), GET_INT(victim), GET_WIS(victim), GET_DEX(victim), GET_CON(victim) ); S2C(); } else send_to_char("You learn nothing new.\n\r", ch); } return SPELL_NORMAL; } /********************************************************************** NEW SPELLS added by the crew at RoA, all spells written and added by James Rhone (James Rhone) unless otherwise noted ***********************************************************************/ /* spells that are primarily MAGE spells follow */ ASPELL(spell_implosion) /* */ { int dam; if (!victim) return SPELL_FAILED; dam = number(70, 120); SpellDamage(ch, victim, dam, SPELL_IMPLOSION, FALSE); return SPELL_NORMAL; } ASPELL(spell_ice_shaft) { int dam; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; dam = dice(level, 4); SpellDamage(ch, victim, dam, SPELL_ICE_SHAFT, FALSE); return SPELL_NORMAL; } /* written by Sergey (freebie) */ ASPELL(spell_haste) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_HASTE) && !affected_by_spell(victim, SKILL_HASTEN)) { af.type = SPELL_HASTE; af.duration = 4; af.modifier = 2; af.location = APPLY_DEX; af.bitvector = AFF_HASTE; af.bitvector2 = 0; affect_to_char(victim, &af); act("You feel your body start to %1sizzle%0 with energy.",FALSE,victim,0,0,TO_CHAR); act("$n's body starts to %1sizzle%0 with energy.",FALSE,victim,0,0,TO_ROOM); } else if (ch != victim) act("$N is already affected by haste.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by haste.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } /* written by Sergey (freebie) */ ASPELL(spell_mirror_image) { int mirrors; mirrors = ch->specials.num_of_images = MAX(GET_INT(ch) + number(1, 5) - 13, 2); sprintf(buf, "%d reflected images of you form suddenly.", mirrors); act(buf, TRUE, ch, 0, 0, TO_CHAR); sprintf(buf, "%d reflected images of $n form suddenly.", mirrors); act(buf, TRUE, ch, 0, 0, TO_ROOM); return SPELL_NORMAL; } ASPELL(spell_gateway) { /* object vnum 105 is GATE object */ obdata *gate1, *gate2; if (!victim) return SPELL_FAILED; if (INVALID_ROOM(ch->in_room) || INVALID_ROOM(victim->in_room)) return SPELL_FAILED; if (GET_LEVEL(victim) < maxnewbielevel) return SPELL_FAILED; if (IN_ARENA(ch) && !arena_info.locked) { send_to_char("You must wait until the arena begins.\n\r",ch); return SPELL_NORMAL; } if (!IS_IMMORTAL(ch) && IS_PC(ch) && IS_NPC(victim)) { send_to_char("You may only create a gate between players.\n\r",ch); return SPELL_NORMAL; } if (!IS_IMMORTAL(ch)) if (ROOM_FLAGGED(ch->in_room, NO_TELEPORT) || ROOM_FLAGGED(victim->in_room, NO_TELEPORT)) { act("Forces beyond comprehension prevent you from gating.",FALSE,ch,0,0,TO_CHAR); act("$n tries to gate, but is unsuccessful!",TRUE,ch,0,0,TO_ROOM); return SPELL_NORMAL; } if (!IS_NPC(ch) && !PRF_FLAGGED(victim, PRF_SUMMONABLE)) { sprintf(buf, "%s just tried to gate to you!\n\r" "%s failed because you have gate protection on.\n\r" "Type NOSUMMON to allow others to gate to you.\n\r", GET_NAME(ch), (ch->player.sex == SEX_MALE) ? "He" : "She"); send_to_char(buf, victim); act("You failed because $N has summon/gate protection on.",FALSE,ch,0,victim,TO_CHAR); sprintf(buf, "%s failed gating to %s.",GET_NAME(ch), GET_NAME(victim)); mudlog(buf, BRF, LEV_IMM, TRUE); return SPELL_NORMAL; } if (!(gate1 = read_object(105, VIRTUAL))) { send_to_char("Something went wrong! Notify an Immortal.\n\r",ch); return SPELL_NORMAL; } if (ROOM_FLAGGED(victim->in_room, NO_MAGIC) || ZONE_FLAGGED(world[victim->in_room].zone, Z_IMMORT) || ZONE_FLAGGED(world[victim->in_room].zone, Z_LOCKED) || ZONE_FLAGGED(world[victim->in_room].zone, Z_CLOSED) || (ZONE_FLAGGED(world[victim->in_room].zone, Z_ARENA) != IN_ARENA(ch))) { act("$n tries to gate, but is unsuccessful!", TRUE, victim, 0, 0, TO_ROOM); send_to_char("Some unknown force prevents a gateway from being formed there.\n\r",ch); return SPELL_NORMAL; } gate2 = read_object(105, VIRTUAL); gate1->value[0] = victim->in_room; gate2->value[0] = ch->in_room; gate1->timer = gate2->timer = number(1,3); // flag gates anchored so they dont float away 4/19/98 -jtrhone SET_BIT(OBJ_EXTRAS(gate1), ITEM_ANCHORED); SET_BIT(OBJ_EXTRAS(gate2), ITEM_ANCHORED); act("$p appears and shimmers slightly!", TRUE, victim, gate1, 0, TO_ROOM); act("$p appears and shimmers slightly!", TRUE, victim, gate1, 0, TO_CHAR); act("$n has created $p to $N!", TRUE, ch, gate1, victim, TO_ROOM); act("You have created $p to $N!", TRUE, ch, gate2, victim, TO_CHAR); obj_to_room(gate1, ch->in_room); obj_to_room(gate2, victim->in_room); return SPELL_NORMAL; } // RoA spells that are primarly CLERICAL in nature follow // Reworked slightly so only non-animal mobs are held, and added support for // NewAffect()... 07/09/98 - callahan ASPELL(spell_hold_person) { AffType af; if (!victim) return SPELL_FAILED; if (Level(ch) < LEV_CIMP) if (saves_spell(victim, SPELL_HOLD_PERSON) || MOB_FLAGGED(victim, MOB_NO_HOLD) || Level(victim) - Level(ch) > 5) { act("$N is enraged at your attempt to hold $M!", TRUE, ch, 0, victim,TO_CHAR); if (!number(0, 2)) do_kill(victim, Name(ch), 0, 0); return SPELL_NORMAL; } if (MOB_CLASS_FLAGGED(victim, MOB_MAMMAL | MOB_AVIAN | MOB_INSECT | MOB_ARACHNID | MOB_ORC | MOB_OGRE | MOB_REPTILE | MOB_GOBLINOID | MOB_AQUATIC | MOB_CRUSTACEAN)) { send_to_char(tprintf("%s cannot be affected by this spell.\r\n", Name(victim)), ch); return SPELL_FAILED; } if (!affected_by_spell(victim, SPELL_HOLD_PERSON) && !affected_by_spell(victim, SPELL_ENSNARE)) { NewAffect(&af); af.type = SPELL_HOLD_PERSON; af.duration = (GET_INT(ch) / 9) + 1; af.bitvector = AFF_HOLD; affect_to_char(victim, &af); act("You have been held!", FALSE, victim, 0, 0, TO_CHAR); act("$n is %4frozen%0 in place!", FALSE, victim, 0, 0, TO_ROOM); // for later EXP assigning... 12/17/97 -jtrhone HOLDER(victim) = ch; } else act("$N is already held in place!", FALSE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_calm) { struct affected_type af; chdata *person; if (IN_NOWHERE(ch)) return SPELL_FAILED; if (FIGHTING(ch)) stop_fighting(ch); af.type = SPELL_CALM; af.duration = GET_LEVEL(ch) / 15; af.modifier = APPLY_NONE; af.location = 0; af.bitvector = 0; af.bitvector2 = AFF2_CALM; /* put the affect on the chars which get affected*/ for(person = world[ch->in_room].people;person;person = person->next_in_room) if(IS_NPC(person) && !affected_by_spell(person, SPELL_CALM) && !MOB_FLAGGED(person, MOB_NO_CALM) && !saves_spell(person, SPELL_CALM)) { if (FIGHTING(person)) stop_fighting(person); affect_to_char(person, &af); act("$N suddenly looks much calmer!", FALSE, ch, 0, person, TO_CHAR); act("$N suddenly looks much calmer!", FALSE, ch, 0, person, TO_ROOM); act("$n has forced you to be calm!", FALSE, ch, 0, person, TO_VICT); } /* NO calm meanies */ for(person = world[ch->in_room].people;person;person = person->next_in_room){ if(MOB_FLAGGED(person, MOB_NO_CALM) && FIGHTING(person)) { act("$N is extremely annoyed at your attempt to calm $M!", FALSE, ch, 0, person, TO_CHAR); act("$N is extremely annoyed at $n's attempt to calm $M!", FALSE, ch, 0, person, TO_ROOM); act("You are extremely annoyed at $n's attempt to calm you!", FALSE, ch, 0, person, TO_VICT); if(FIGHTING(person) != ch) { stop_fighting(person); hit(person, ch, TYPE_UNDEFINED, FALSE); } } } return SPELL_NORMAL; } ASPELL(spell_illuminate) { struct affected_type af; if (!victim) return SPELL_FAILED; if (saves_spell(victim, SPELL_ILLUMINATE)) { act("$N resists your attempt!",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_ILLUMINATE)) { af.type = SPELL_ILLUMINATE; af.duration = GET_LEVEL(ch)/2; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; af.bitvector2 = AFF2_ILLUMINATE; affect_to_char(victim, &af); act("You feel vulnerable.",FALSE,victim,0,0,TO_CHAR); act("$n glows with a %B%3golden%0 aura!", FALSE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected by illuminate.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by illuminate.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_protection_from_good) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_PROTECT_FROM_GOOD)) { af.type = SPELL_PROTECT_FROM_GOOD; af.duration = 24; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_PROTECT_GOOD; af.bitvector2 = 0; affect_to_char(victim, &af); send_to_char("Success!\n\r",ch); send_to_char("You are protected from goodness!\n\r", victim); } else if (ch != victim) act("$N is already protected from goodness.",FALSE,victim,0,0,TO_CHAR); else act("You are already protected from goodness.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_protect_undead) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_PROTECT_UNDEAD)) { af.type = SPELL_PROTECT_UNDEAD; af.duration = 24; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(victim, &af); send_to_char("You are protected from the undead!\n\r", victim); act("$n shimmers slightly and looks holy!", FALSE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already protected from the undead.",FALSE,victim,0,0,TO_CHAR); else act("You are already protected from the undead.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_create_food) { obdata *tmp_obj; int num; /* object vnum 120 - 135 is a magic food in RoA */ num = number(120, 135); if (!(tmp_obj = read_object(num, VIRTUAL))) { send_to_char("Something went wrong! Notify an Immortal.\n\r",ch); return SPELL_FAILED; } tmp_obj->value[0] = 5 + GET_LEVEL(ch)/2; act("$n has created $p!", TRUE, ch, tmp_obj, 0, TO_ROOM); act("$p suddenly appears in your inventory!", TRUE, ch, tmp_obj, 0, TO_CHAR); obj_to_char(tmp_obj, ch); return SPELL_NORMAL; } ASPELL(spell_stone_skin) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!ch) log("SYSERR: ch sanity check failed, spell_stone_skin, magic.c"); if (!affected_by_spell(victim, SPELL_STONE_SKIN) && !affected_by_spell(victim, SPELL_ARMOR) && !affected_by_spell(victim, SPELL_TREESKIN) && // 06/07/98 -callahan !affected_by_spell(victim, SPELL_BARKSKIN)) { af.type = SPELL_STONE_SKIN; af.duration = 24; af.modifier = -GET_LEVEL(ch)-23; af.location = APPLY_AC; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(victim, &af); send_to_char("You feel protected by skin of stone!\n\r", victim); act("$n's skin suddenly hardens and turns %8grey%0!", FALSE, victim,0, 0, TO_ROOM); } else if (ch != victim) act("$N is already protected.",FALSE,ch,0,victim,TO_CHAR); else act("You are already protected.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_power_heal) { if (!victim) return SPELL_FAILED; if (affected_by_spell(victim, SPELL_BLINDNESS) || affected_by_spell(victim, SPELL_SPIRITLEAVES)) spell_cure_blind(ch, arg, victim, obj); GET_HIT(victim) += (250 - dice(1,4)); /* changed this spell JRHone*/ GET_HIT(victim) = MIN(GET_MAX_HIT(victim), GET_HIT(victim)); update_pos(victim); send_to_char("A %6blinding%0 light surrounds you....\n\r",victim); send_to_char("A %1warm%0 feeling fills your body....\n\r", victim); act("A %Bblinding light%0 surrounds $n.", FALSE, victim, 0, 0, TO_ROOM); return SPELL_NORMAL; } ASPELL(spell_wings) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_WINGS)) { af.type = SPELL_WINGS; af.duration = GET_LEVEL(ch); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_WINGS; af.bitvector2 = 0; affect_to_char(victim, &af); act("You slowly float into the air!",FALSE,victim,0,0,TO_CHAR); act("$n slowly floats into the air.", FALSE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected by wings.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by wings.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_gills) { struct affected_type af; if (!victim) return SPELL_FAILED; if (!affected_by_spell(victim, SPELL_GILLS)) { af.type = SPELL_GILLS; af.duration = GET_LEVEL(ch); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_GILLS; af.bitvector2 = 0; affect_to_char(victim, &af); act("You slowly form gills.",FALSE,victim,0,0,TO_CHAR); act("$n slowly forms gills.", FALSE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected by gills.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by gills.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_locate_being) { int rm = ch->in_room; if (!victim) { send_to_char("Your mind spins with confusion.\n\r",ch); return SPELL_FAILED; } if (!check_mortal_combat(ch, victim)) /* then its worth a saving throw*/ return SPELL_FAILED; if (saves_spell(victim, SPELL_LOCATE_BEING)) { send_to_char("Your target resists.\n\r",ch); return SPELL_FAILED; } act("You concentrate yourself....", FALSE, ch, 0, 0, TO_CHAR); act("$n sinks into deep concentration.", FALSE, ch, 0, 0, TO_ROOM); // check if victim has mindtrap set... 11/29/97 -jtrhone if (affected_by_spell(victim, SPELL_MINDTRAP)) { act("%B%5AAAAAHHH!!!%0", FALSE, ch, 0, victim, TO_CHAR); act("An image of $n %Bflashes%0 in your head.",TRUE,ch,0,victim,TO_VICT); act("Your %B%5MINDTRAP%0 lashes out at $n!",TRUE,ch,0,victim,TO_VICT); act("$n drops to $s knees in pain!", FALSE, ch, 0, 0, TO_ROOM); // hmm.. what type of damage GET_HIT(ch) /= 2; return SPELL_FAILED; } if (!INVALID_ROOM(victim->in_room)) { ch->in_room = victim->in_room; do_look_at_room(ch, 0, 0); ch->in_room = rm; act("An image of $n %Bflashes%0 in your head.",TRUE,ch,0,victim,TO_VICT); } else send_to_char("Your mind spins with confusion.\n\r",ch); return SPELL_NORMAL; } ASPELL(spell_view_hidden) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; af.type = SPELL_VIEW_HIDDEN; af.duration = level * 2; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; af.bitvector2 = 0; affect_join(victim, &af, TRUE, FALSE); act("Your awareness suddenly improves.",FALSE,victim,0,0,TO_CHAR); act("$n's awareness suddenly improves.",TRUE,victim,0,0,TO_ROOM); return SPELL_NORMAL; } ASPELL(spell_forest_sight) { struct affected_type af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; af.type = SPELL_FOREST_SIGHT; af.duration = level * 2; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; af.bitvector2 = 0; affect_join(victim, &af, TRUE, FALSE); act("Your awareness suddenly improves.",FALSE,victim,0,0,TO_CHAR); act("$n's awareness suddenly improves.",TRUE,victim,0,0,TO_ROOM); return SPELL_NORMAL; } // RoA first of the room affectual spells 10/28/96 ASPELL(spell_silence) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_SILENCE)) { act("There is an aura of %Bsilence%0 already here.",FALSE, ch, 0, 0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_SILENCE; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth an aura of %Bholy silence%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_retrieve_corpse) { char *argu = arg; long id; obdata *ob; long get_id_by_name(char *name); if (!*argu) { send_to_char("Usage: cast 'retrieve corpse' < PC name >\n\r",ch); return SPELL_NORMAL; } skip_spaces(&argu); if ((id = get_id_by_name(argu)) <= 0) { sprintf(buf, "The name %s is unknown in these realms...\n\r", argu); S2C(); return SPELL_NORMAL; } for (ob=object_list; ob; ob=ob->next) if (!INVALID_ROOM(ob->in_room) && IS_CORPSE(ob) && ob->plr_num == id) break; // we didnt find it... if (!ob) { act("You fail to locate anything...", FALSE, ch, 0, 0, TO_CHAR); return SPELL_NORMAL; } // waste protection... if (ob->in_room == ch->in_room) { act("Those remains are already here...", FALSE, ch, 0, 0, TO_CHAR); return SPELL_NORMAL; } // we found it :) act("You retrieve $p!", FALSE, ch, ob, 0, TO_CHAR); act("$n's eyes darken momentarily...",TRUE,ch,0,0,TO_ROOM); obj_from_room(ob); obj_to_room(ob, ch->in_room); act("$n has retrieved $p!",TRUE,ch,ob,0,TO_ROOM); sprintf(buf, "PLRUPD: %s retrieved %s.", GET_NAME(ch), ob->shdesc); mudlog(buf, BRF, LEV_IMM, TRUE); return SPELL_NORMAL; } ASPELL(spell_mindtrap) { struct affected_type af; if (!affected_by_spell(ch, SPELL_MINDTRAP)) { af.type = SPELL_MINDTRAP; af.duration = 24 + GET_LEVEL(ch); af.modifier = 0; af.location = 0; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(ch, &af); act("Your mindtrap has been successfully set...", FALSE, ch, 0, 0, TO_CHAR); act("A shadow falls across $n's face...", FALSE, ch, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected by mindtrap.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected by mindtrap.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } ASPELL(spell_firewall) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_FIREWALL)) { act("There is a %1%Bwall of fire%0 already here.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_FIREWALL; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth a %B%1wall of fire%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_icewall) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_ICEWALL)) { act("There is an %6%Bice storm%0 already here.",FALSE, ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_ICEWALL; af.caster = ch; af.duration = number(2, 4); af.bitvector = 0; act("You call forth an %B%6ice storm%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_typhoon) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_TYPHOON)) { act("A %1typhoon%0 rages here already!",FALSE, ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_TYPHOON; af.caster = ch; af.duration = number(2, 4); af.bitvector = 0; act("You call forth a deadly %1typhoon%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_void) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_VOID)) { act("A %4temporal void%0 shimmers here already!",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_VOID; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth a %4temporal void%0!", FALSE, ch, 0, 0,TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_gascloud) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_GASCLOUD)) { act("A %2cloud of gas%0 is already here!",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_GASCLOUD; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth a %2cloud of gas%0!", FALSE, ch, 0, 0,TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_blindwall) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_BLINDWALL)) { act("A %4cloak of blindness%0 is already here!",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_BLINDWALL; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth a %4cloak of blindness%0!", FALSE, ch, 0, 0,TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_confusion) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_CONFUSION)) { act("This area is already confusing enough!",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_CONFUSION; af.caster = ch; af.duration = number(2, 5); af.bitvector = 0; act("You call forth a an area of confusion!", FALSE, ch, 0, 0,TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_swarm) { int dam; int level = GET_LEVEL(ch); chdata *next_vict; BOOL found = FALSE; for (victim = character_list; victim; victim = next_vict) { next_vict = victim->next; if (FIGHTING(victim) == ch && SAME_ROOM(victim, ch) && check_mortal_combat(ch, victim)) { found = TRUE; dam = dice(level, 4); if (saves_spell(victim, SPELL_SWARM)) damage(ch, victim, (dam >> 1), SPELL_SWARM, FALSE); else damage(ch, victim, dam, SPELL_SWARM, FALSE); } } if (!found) send_to_char("You're unable to find an enemy to focus the swarm on.\n\r",ch); return SPELL_NORMAL; } ASPELL(spell_shower_of_life) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_SHOWEROFLIFE)) { act("There is a %6%Bshower of life%0 already here.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_SHOWEROFLIFE; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You call forth a %B%6shower of life%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_cursed_grounds) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_CURSED_GROUNDS)) { act("This area is already cursed.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_CURSED_GROUNDS; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You curse this area!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_absolute_ward) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_ABSOLUTE_WARD)) { act("This area is already warded.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_ABSOLUTE_WARD; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You ward this area!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_circle_of_warding) { struct room_affect_type af; char *argu = arg; skip_spaces(&argu); if (!*argu) { send_to_char("Usage: cast 'circle of warding' < evil | neutral | good >\n\r",ch); return SPELL_NORMAL; } if (spell_affects_room(ch->in_room, SPELL_CIRCLE_OF_WARDING)) { act("This area is already warded.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } if (is_abbrev(argu, "evil")) { af.bitvector = RMAFF_VS_EVIL; strcpy(buf2, "evil"); } else if (is_abbrev(argu, "neutral")) { af.bitvector = RMAFF_VS_NEUTRAL; strcpy(buf2, "neutrality"); } else if (is_abbrev(argu, "good")) { af.bitvector = RMAFF_VS_GOOD; strcpy(buf2, "goodness"); } else { send_to_char("Usage: cast 'circle of warding' < evil | neutral | good >\n\r",ch); return SPELL_NORMAL; } af.spell = SPELL_CIRCLE_OF_WARDING; af.caster = ch; af.duration = number(1, 3); sprintf(buf, "You ward this area against %s!", buf2); act(buf, FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_walloffog) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_WALLOFFOG) || spell_affects_room(ch->in_room, SPELL_OCCLUSION)) { act("This area is already covered by a wall of fog.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_WALLOFFOG; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You enshroud this area in a thick fog!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_area_of_return) { struct room_affect_type af, *raf; int room; // first, remove any existing areas of return for (room = 0; room < top_of_world; room++) if ((raf = char_spell_affects_room(ch, SPELL_AREA_OF_RETURN, room))) { char_spell_affect_from_room(ch, SPELL_AREA_OF_RETURN, room); if (world[room].name) { sprintf(buf, "You aura has been removed from %s.\n\r", world[room].name); S2C(); } } af.spell = SPELL_AREA_OF_RETURN; af.caster = ch; af.duration = number(3, 5); af.bitvector = 0; act("You mark this area with your %Baura%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } ASPELL(spell_return) { struct room_affect_type *raf; int room; // first, see if any areas exist... for (room = 0; room < top_of_world; room++) if ((raf = char_spell_affects_room(ch, SPELL_AREA_OF_RETURN, room))) break; if (room >= top_of_world) { act("You fail to find your %Baura%0!", FALSE, ch, 0, 0, TO_CHAR); return SPELL_NORMAL; } act("You slowly fade out of existence.", FALSE, ch, 0, 0, TO_CHAR); act("$n slowly fades out of existence.", FALSE, ch, 0, 0, TO_ROOM); char_from_room(ch); char_to_room(ch, room); act("You slowly fade into existence.", FALSE, ch, 0, 0, TO_CHAR); act("$n slowly fades into existence.", FALSE, ch, 0, 0, TO_ROOM); do_look_at_room(ch, 15, 0); if (check_room_affects(ch, ch->in_room) == CHAR_DIED) return SPELL_NORMAL; if (check_death_trap(ch, NULL)) return SPELL_NORMAL; return SPELL_NORMAL; } ASPELL(spell_project) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_PROJECT)) { act("This area already contains a projection.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_PROJECT; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You project yourself onto this area!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } // rangers spell similar to implosion 3/27/98 -jtrhone ASPELL(spell_earthdarts) { int dam; if (!victim) return SPELL_FAILED; dam = number(50, 100); SpellDamage(ch, victim, dam, SPELL_EARTHDARTS, FALSE); return SPELL_NORMAL; } // rangers spell similar to blindness 3/27/98 -jtrhone ASPELL(spell_spiritleaves) { AffType af; if (!victim) return SPELL_FAILED; if (!check_mortal_combat(ch, victim)) return SPELL_FAILED; if (saves_spell(victim, SPELL_SPIRITLEAVES) || MOB_FLAGGED(victim, MOB_NO_BLIND)) { if (ch != victim) act("$N repels your spell.",TRUE,ch,0,victim,TO_CHAR); else act("You repel your spell...?",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_SPIRITLEAVES) && !affected_by_spell(victim, SPELL_BLINDNESS)) { NewAffect(&af); af.type = SPELL_SPIRITLEAVES; af.location = APPLY_HITROLL; af.modifier = -(GET_LEVEL(ch)/3); /* Make hitroll WAY worse */ af.duration = 1; af.bitvector = AFF_BLIND; affect_to_char(victim, &af); af.location = APPLY_AC; af.modifier = 20; /* Make AC Worse! */ affect_to_char(victim, &af); act("$n seems to be blinded by spirit leaves!", TRUE, victim, 0, 0, TO_ROOM); act("You have been blinded by spirit leaves!",FALSE,victim,0,0,TO_CHAR); } else send_to_char("Luckily, you are already blind!\n\r",victim); return SPELL_NORMAL; } // rangers spell similar to bard's BOG 3/27/98 -jtrhone ASPELL(spell_entangle) { AffType af; if (!victim) return SPELL_FAILED; if (!check_mortal_combat(ch, victim)) return SPELL_FAILED; if (saves_spell(victim, SPELL_ENTANGLE) || MOB_FLAGGED(victim, MOB_NO_HOLD)) { if (ch != victim) act("$N repels your spell.",TRUE,ch,0,victim,TO_CHAR); else act("You repel your spell...?",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_ENTANGLE) && !affected_by_spell(victim, SPELL_SONG_BOG)) { NewAffect(&af); af.type = SPELL_ENTANGLE; af.location = APPLY_DEX; af.modifier = -3; // level/10 ROUNDS (1 tick == 30 rounds, roughly) // will decrement per round in fight.c af.duration = GET_LEVEL(ch) / 10; affect_to_char(victim, &af); act("You have been entangled!",FALSE,victim,0,0,TO_CHAR); act("$n seems to be entangled!", TRUE, victim, 0, 0, TO_ROOM); } else act("$N is already affected by such.",TRUE,ch,0,victim,TO_CHAR); return SPELL_NORMAL; } // ranger spell similar to stone_skin 3/27/98 -jtrhone ASPELL(spell_barkskin) { AffType af; if (!victim) return SPELL_FAILED; if (!ch) log("SYSERR: ch sanity check failed, barkskin, magic.c"); if (!affected_by_spell(victim, SPELL_STONE_SKIN) && !affected_by_spell(victim, SPELL_ARMOR) && !affected_by_spell(victim, SPELL_BARKSKIN)) { NewAffect(&af); af.type = SPELL_BARKSKIN; af.duration = 24; af.modifier = -GET_LEVEL(ch)-23; af.location = APPLY_AC; affect_to_char(victim, &af); send_to_char("You feel protected by barkskin!\n\r", victim); act("$n's skin suddenly hardens in the form of bark!", FALSE, victim,0, 0, TO_ROOM); } else if (ch != victim) act("$N is already protected.",FALSE,victim,0,0,TO_CHAR); else act("You are already protected.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } // ranger spell similar to heal 3/27/98 -jtrhone ASPELL(spell_spiritbalm) { if (!victim) return SPELL_FAILED; if (affected_by_spell(victim, SPELL_BLINDNESS) || affected_by_spell(victim, SPELL_SPIRITLEAVES)) spell_cure_blind(ch, arg, victim, obj); GET_HIT(victim) += (100 - dice(1,4)); GET_HIT(victim) = MIN(GET_MAX_HIT(victim), GET_HIT(victim)); update_pos(victim); act("A %1warm%0 feeling fills your spirit...",FALSE,victim,0,0,TO_CHAR); act("You suddenly feel much better!",FALSE,victim,0,0,TO_CHAR); act("$n suddenly looks much healthier.", FALSE, victim, 0, 0, TO_ROOM); return SPELL_NORMAL; } // ranger spell similar to harm 3/27/98 -jtrhone ASPELL(spell_spiritshock) { int dam; if (!victim) return SPELL_FAILED; dam = GET_HIT(victim) - dice(1, 4); if (dam < 0) dam = 0; else if (saves_spell(victim, SPELL_SPIRITSHOCK)) dam = MIN(30, dam / 3); damage(ch, victim, dam, SPELL_SPIRITSHOCK, FALSE); return SPELL_NORMAL; } // ranger spell similar to detect invis 3/27/98 -jtrhone ASPELL(spell_foresteyes) { AffType af; int level = GET_LEVEL(ch); if (!victim) return SPELL_FAILED; if (!affected_by_spell(ch, SPELL_FORESTEYES) && !affected_by_spell(ch, SPELL_DETECT_INVISIBLE)) { NewAffect(&af); af.type = SPELL_FORESTEYES; af.duration = level * 5; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_INVISIBLE; affect_to_char(victim, &af); send_to_char("You gain the eyes of the forest.\n\r", victim); } else if (ch != victim) act("$N is already affected.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } // ranger spell similar to hold 3/27/98 -jtrhone ASPELL(spell_ensnare) { AffType af; if (!victim) return SPELL_FAILED; if (GET_LEVEL(ch) < LEV_CIMP) if (saves_spell(victim, SPELL_ENSNARE) || MOB_FLAGGED(victim, MOB_NO_HOLD) || GET_LEVEL(victim) - GET_LEVEL(ch) > 5) { act("$N is enraged at your attempt to ensnare $M!", TRUE, ch, 0, victim,TO_CHAR); if (!number(0, 2)) do_kill(victim, GET_NAME(ch), 0, 0); return SPELL_NORMAL; } if (!affected_by_spell(victim, SPELL_HOLD_PERSON) && !affected_by_spell(victim, SPELL_ENSNARE)) { NewAffect(&af); af.type = SPELL_ENSNARE; af.duration = (GET_INT(ch) / 9) + 1; af.bitvector = AFF_HOLD; affect_to_char(victim, &af); act("You have been ensnared!",FALSE,victim,0,0,TO_CHAR); act("$n has been %6ensnared%0!", FALSE, victim, 0, 0, TO_ROOM); // for later EXP assigning... 12/17/97 -jtrhone HOLDER(victim) = ch; } else act("$N is already held in place!", FALSE, ch, 0, victim, TO_CHAR); return SPELL_NORMAL; } // ranger spell similar to wall of fog 3/27/98 -jtrhone ASPELL(spell_occlusion) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_WALLOFFOG) || spell_affects_room(ch->in_room, SPELL_OCCLUSION)) { act("This area is already covered by an area of fog.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_OCCLUSION; af.caster = ch; af.duration = 1; af.bitvector = 0; act("You enshroud this area in a thick fog!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); // now, stop ch from fighting... if ((victim = FIGHTING(ch))) { if (saves_spell(victim, SPELL_OCCLUSION)) { act("You fail to disengage from $N!", FALSE, ch, 0, victim, TO_CHAR); act("$n has disengaged from fighting you!", FALSE, ch, 0, victim, TO_VICT); return SPELL_NORMAL; } act("You disengage from $N!", FALSE, ch, 0, victim, TO_CHAR); // make mob remember... if (FIGHTING(victim) == ch) HUNTING(victim) = ch; stop_fighting(ch); stop_fighting(victim); } return SPELL_NORMAL; } // ranger spell similar to shower of life 3/27/98 -jtrhone ASPELL(spell_campfire) { struct room_affect_type af; if (spell_affects_room(ch->in_room, SPELL_CAMPFIRE)) { act("There is a %1%Bcampfire%0 already here.",FALSE, ch, 0,0,TO_CHAR); return SPELL_NORMAL; } af.spell = SPELL_CAMPFIRE; af.caster = ch; af.duration = number(1, 3); af.bitvector = 0; act("You build a soothing %B%1campfire%0!", FALSE, ch, 0, 0, TO_CHAR); affect_to_room(ch->in_room, &af); return SPELL_NORMAL; } // ranger spell similar to sanct 3/27/98 -jtrhone ASPELL(spell_spiritshield) { AffType af; if (!victim) return SPELL_FAILED; if (!IS_AFFECTED(victim, AFF_SANCTUARY) && !IS_AFFECTED2(victim, AFF2_CROW)) { NewAffect(&af); af.type = SPELL_SPIRITSHIELD; af.duration = IS_IMMORTAL(ch) ? GET_LEVEL(ch) : 3; af.location = APPLY_NONE; af.bitvector = AFF_SANCTUARY; affect_to_char(victim, &af); act("Your spirit is surrounded by a %Bglowing%0 aura.", TRUE, victim, 0, 0, TO_CHAR); act("$n's spirit is surrounded by a %Bglowing%0 aura.", TRUE, victim, 0, 0, TO_ROOM); } else if (ch != victim) act("$N is already affected.",FALSE,victim,0,0,TO_CHAR); else act("You are already affected.",FALSE,ch,0,0,TO_CHAR); return SPELL_NORMAL; } /* *************************************************************************** * NPC spells.. * * ************************************************************************* */ ASPELL(spell_fire_breath) { int dam; int hpch; obdata *burn; if (!victim) return SPELL_FAILED; hpch = GET_HIT(ch); if (hpch < 10) hpch = 10; dam = number(0, hpch >> 2); if (SpellDamage(ch, victim, dam, SPELL_FIRE_BREATH, FALSE) == CHAR_DIED) return SPELL_NORMAL; /* And now for the damage on inventory */ if (number(0, 70) < GET_LEVEL(ch)) { if (!saves_spell(victim, SPELL_FIRE_BREATH) ) { for (burn = victim->carrying; burn && (burn->type_flag != ITEM_WAND) && (burn->type_flag != ITEM_STAFF) && (burn->type_flag != ITEM_CONTAINER) && (!number(0, 2)); burn = burn->next_content) ; if (burn) { act("$p suddenly %B%1burns into ashes%0!", 0, victim, burn, 0, TO_CHAR); extract_obj(burn); } } } return SPELL_NORMAL; } ASPELL(spell_frost_breath) { int dam; int hpch; obdata *frozen; if (!victim) return SPELL_FAILED; hpch = GET_HIT(ch); if (hpch < 10) hpch = 10; dam = number(0, hpch >> 2); if (SpellDamage(ch, victim, dam, SPELL_FROST_BREATH, FALSE) == CHAR_DIED) return SPELL_NORMAL; /* And now for the damage on inventory */ if (number(0, 70) < GET_LEVEL(ch)) { if (!saves_spell(victim, SPELL_FROST_BREATH) ) { for (frozen = victim->carrying; frozen && (frozen->type_flag != ITEM_DRINKCON) && (frozen->type_flag != ITEM_FOOD) && (frozen->type_flag != ITEM_POTION) && (frozen->type_flag != ITEM_CONTAINER) && (!number(0, 2)); frozen = frozen->next_content) ; if (frozen) { act("$p suddenly %B%4freezes and breaks%0!", 0, victim, frozen, 0, TO_CHAR); extract_obj(frozen); } } } return SPELL_NORMAL; } ASPELL(spell_acid_breath) { int dam; int hpch; int damaged; int apply_ac(chdata *ch, int eq_pos); if (!victim) return SPELL_FAILED; hpch = GET_HIT(ch); if (hpch < 10) hpch = 10; dam = number(0, hpch >> 2); if (SpellDamage(ch, victim, dam, SPELL_ACID_BREATH, FALSE) == CHAR_DIED) return SPELL_NORMAL; /* And now for the damage on equipment */ if (number(0, 70) < GET_LEVEL(ch)) { if (!saves_spell(victim, SPELL_ACID_BREATH) ) { if (number(0,1) && EQ(victim, (damaged = number(0,MAX_WEAR-1)))) { act("$p gets %B%1seered by the acid%0!", 0, victim, EQ(victim, damaged), 0, TO_CHAR); damage_object(EQ(victim, damaged), victim); } } } return SPELL_NORMAL; } ASPELL(spell_gas_breath) { int dam; int hpch; if (!victim) return SPELL_FAILED; hpch = GET_HIT(ch); if (hpch < 10) hpch = 10; dam = number(0, hpch >> 2); SpellDamage(ch, victim, dam, SPELL_GAS_BREATH, FALSE); return SPELL_NORMAL; } ASPELL(spell_lightning_breath) { int dam; int hpch; chdata *nxt; if (!victim) return SPELL_FAILED; hpch = GET_HIT(ch); if (hpch < 10) hpch = 10; dam = number(0, hpch >> 2); if (SpellDamage(ch, victim, dam, SPELL_LIGHTNING_BREATH, FALSE) == CHAR_DIED) return SPELL_NORMAL; if (world[victim->in_room].terrain_type == TERRAIN_WATER_SWIM || world[victim->in_room].terrain_type == TERRAIN_WATER_NOSWIM || world[victim->in_room].terrain_type == TERRAIN_UWATER) { act("%BElectricity flows through the area!!%0", FALSE, ch, 0, 0,TO_ROOM); for (victim = world[victim->in_room].people; victim; victim = nxt) { nxt = victim->next_in_room; if (!IS_FLYING(victim)) damage(ch, victim, (dam*4), SPELL_LIGHTNING_BREATH, FALSE); } } return SPELL_NORMAL; }