/* * Elkandu Magic System * * Written by Keolah for Rogue Winds * * This is an experiment at creating a non spell based magic system, involving * different combinations of keywords to create a desired magical effect. * Assumption: All players are mages, and can make at least minimal use of their magic. * */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> #ifdef sun #include <strings.h> #endif #include <time.h> #include "mud.h" /* from act_move.c */ extern void drop_dream_items(CHAR_DATA *ch, OBJ_DATA *obj); /* from birth.c */ extern void set_race(CHAR_DATA *ch, bool died); /* from bodyparts.c */ extern void add_part(CHAR_DATA *ch, int part, int to_part); /* from combat.c */ extern void ranged_attack(CHAR_DATA *ch, OBJ_DATA *obj, char *argument); extern bool can_gain_exp(CHAR_DATA *ch, CHAR_DATA *victim); /* from handler.c */ extern MATERIAL_DATA *material_lookup( int number ); extern SPECIES_DATA *find_species(char *name); extern char *munch_colors(char *word); /* from talent.c */ extern bool can_travel(int i, CHAR_DATA *ch, CHAR_DATA *victim); typedef enum { ACT_TRICKS, ACT_HARM, ACT_HELP, ACT_CHANGE, ACT_MOVE, ACT_FIND, ACT_CREATE, ACT_ENHANCE, ACT_HINDER, ACT_FOCUS, ACT_RUNE, ACT_SING, ACT_CONTROL } action_types; void obj_trick(CHAR_DATA *ch, OBJ_DATA *obj, int type) { char buf[MAX_STRING_LENGTH]; switch (type) { default: sprintf(buf, "&PRaw mana %s $p and %s.", number_range(1,2) == 1 ? "surrounds" : "circles", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_FIRE: sprintf(buf, "&R%s flames %s %s $p and %s.", number_range(1,2) == 1 ? "Flickering" : "Lambent", number_range(1,2) == 1 ? "streak" : "dance", number_range(1,2) == 1 ? "over" : "along", number_range(1,2) == 1 ? "vanish" : "disappear" ); break; case MAG_EARTH: sprintf(buf, "&GLeaves %s %s $p and %s.", number_range(1,2) == 1 ? "sprout" : "grow", number_range(1,2) == 1 ? "from" : "all over", number_range(1,2) == 1 ? "wither" : "fall off" ); break; case MAG_BLUNT: sprintf(buf, "&O%s %s %s $p %s.", number_range(1,2) == 1 ? "Tiny" : "Little", number_range(1,2) == 1 ? "pebbles" : "bits of rock", number_range(1,2) == 1 ? "pelt" : "strike", number_range(1,2) == 1 ? "lightly" : "softly" ); break; case MAG_ELECTRICITY: sprintf(buf, "&Y%s %s %s %s $p and %s.", number_range(1,2) == 1 ? "Crackling" : "White", number_range(1,2) == 1 ? "lightning" : "electricity", number_range(1,2) == 1 ? "shoots" : "races", number_range(1,2) == 1 ? "over" : "along", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_WIND: sprintf(buf, "&c%s %s %s $p and %s %s.", number_range(1,2) == 1 ? "Howling" : "Whipping", number_range(1,2) == 1 ? "winds" : "storms", number_range(1,2) == 1 ? "twist around" : "surround", number_range(1,2) == 1 ? "abruptly" : "suddenly", number_range(1,2) == 1 ? "cease" : "stop" ); break; case MAG_COLD: sprintf(buf, "&CA %s layer of %s %s $p and %s.", number_range(1,2) == 1 ? "light" : "thin", number_range(1,2) == 1 ? "frost" : "ice", number_range(1,2) == 1 ? "covers" : "spreads over", number_range(1,2) == 1 ? "melts" : "vanishes" ); break; case MAG_WATER: sprintf(buf, "&B%s %s of water %s $p and %s.", number_range(1,2) == 1 ? "Small" : "Tiny", number_range(1,2) == 1 ? "drops" : "droplets", number_range(1,2) == 1 ? "cover" : "flow over", number_range(1,2) == 1 ? "drip away" : "evaporate" ); break; case MAG_ACID: sprintf(buf, "&g%s of acid %s from $p.", number_range(1,2) == 1 ? "Flecks" : "Tiny droplets", number_range(1,2) == 1 ? "drip" : "drizzle" ); break; case MAG_DREAM: sprintf(buf, "&P$p %s %s as if %s from a %s.", number_range(1,2) == 1 ? "flashes" : "flickers", number_range(1,2) == 1 ? "for an instant" : "for a moment", number_range(1,2) == 1 ? "an image" : "something", number_range(1,2) == 1 ? "dream" : "nightmare" ); break; case MAG_SOUND: sprintf(buf, "&Y$p %s %s for a %s.", number_range(1,2) == 1 ? "hums" : "sings", number_range(1,2) == 1 ? "eerily" : "faintly", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_HOLY: sprintf(buf, "&z&W%s %s light %s $p %s.", number_range(1,2) == 1 ? "Shimmering" : "Holy", number_range(1,2) == 1 ? "white" : "silver", number_range(1,2) == 1 ? "surrounds" : "encompasses", number_range(1,2) == 1 ? "briefly" : "for a moment" ); break; case MAG_UNHOLY: sprintf(buf, "&z$p %s a %s %s for a %s.", number_range(1,2) == 1 ? "emits" : "casts", number_range(1,2) == 1 ? "deep" : "dark", number_range(1,2) == 1 ? "shadow" : "darkness", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_POISON: sprintf(buf, "&g%s of %s %s %s $p.", number_range(1,2) == 1 ? "Wisps" : "Puffs", number_range(1,2) == 1 ? "smoke" : "poisonous gas", number_range(1,2) == 1 ? "drift" : "waft", number_range(1,2) == 1 ? "over" : "around" ); break; case MAG_CHANGE: case MAG_TIME: sprintf(buf, "&B$p %s %s %s.", number_range(1,2) == 1 ? "twists" : "warps", number_range(1,2) == 1 ? "strangely" : "eerily", number_range(1,2) == 1 ? "briefly" : "for a moment" ); break; case MAG_TELEKINETIC: sprintf(buf, "&Y$p %s and %s %s.", number_range(1,2) == 1 ? "twitches" : "dances", number_range(1,2) == 1 ? "tingles" : "hums", number_range(1,2) == 1 ? "briefly" : "for a moment" ); break; case MAG_LIGHT: case MAG_SEEK: sprintf(buf, "&Y$p %s %s for a %s.", number_range(1,2) == 1 ? "glows" : "shines", number_range(1,2) == 1 ? "brightly" : "faintly", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_PSIONIC: sprintf(buf, "&p$p %s %s with %s %s.", number_range(1,2) == 1 ? "shimmers" : "shines", number_range(1,2) == 1 ? "violet" : "faintly", number_range(1,2) == 1 ? "mental" : "psionic", number_range(1,2) == 1 ? "energy" : "power" ); break; case MAG_ANTIMATTER: case MAG_ANTIMAGIC: sprintf(buf, "&z%s black %s %s %s $p and %s.", number_range(1,2) == 1 ? "Crackling" : "Humming", number_range(1,2) == 1 ? "lightning" : "antimatter", number_range(1,2) == 1 ? "shoots" : "streaks", number_range(1,2) == 1 ? "around" : "along", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_ETHER: sprintf(buf, "&w%s %s of %s %s %s $p.", number_range(1,2) == 1 ? "Insubstantial" : "Pale", number_range(1,2) == 1 ? "wisps" : "tendrils", number_range(1,2) == 1 ? "ether" : "mist", number_range(1,2) == 1 ? "float" : "drift", number_range(1,2) == 1 ? "over" : "along" ); break; } act(AT_ACTION, buf, ch, obj, NULL, TO_ROOM); act(AT_ACTION, buf, ch, obj, NULL, TO_CHAR); } void ch_trick(CHAR_DATA *ch, int type) { char buf[MAX_STRING_LENGTH]; switch (type) { default: sprintf(buf, "&PRaw mana %s $n and %s.", number_range(1,2) == 1 ? "surrounds" : "circles", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_FIRE: sprintf(buf, "&R%s flames %s %s $n and %s.", number_range(1,2) == 1 ? "Flickering" : "Lambent", number_range(1,2) == 1 ? "streak" : "dance", number_range(1,2) == 1 ? "around" : "in front of", number_range(1,2) == 1 ? "vanish" : "disappear"); break; case MAG_EARTH: sprintf(buf, "%s leaves %s %s $n and %s.", number_range(1,2) == 1 ? "&GGreen" : "&OAutumn", number_range(1,2) == 1 ? "swirl" : "blow", number_range(1,2) == 1 ? "around" : "in front of", number_range(1,2) == 1 ? "blow away" : "disappear" ); break; case MAG_BLUNT: sprintf(buf, "&O%s %s %s $n %s.", number_range(1,2) == 1 ? "Tiny" : "Little", number_range(1,2) == 1 ? "pebbles" : "bits of rock", number_range(1,2) == 1 ? "spin around" : "encircle", number_range(1,2) == 1 ? "briefly" : "momentarily" ); break; case MAG_ELECTRICITY: sprintf(buf, "&Y%s %s %s $n and %s.", number_range(1,2) == 1 ? "Crackling" : "White", number_range(1,2) == 1 ? "lightning" : "electricity", number_range(1,2) == 1 ? "surrounds" : "splits around", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_WIND: sprintf(buf, "&C%s %s %s $n and %s %s.", number_range(1,2) == 1 ? "Howling" : "Whipping", number_range(1,2) == 1 ? "winds" : "storms", number_range(1,2) == 1 ? "swirl around" : "surround", number_range(1,2) == 1 ? "abruptly" : "suddenly", number_range(1,2) == 1 ? "cease" : "stop" ); break; case MAG_COLD: sprintf(buf, "&C%s %s %s $n and %s %s.", number_range(1,2) == 1 ? "Swirling cold" : "Frigid", number_range(1,2) == 1 ? "winds" : "snowflakes", number_range(1,2) == 1 ? "swirl around" : "surround", number_range(1,2) == 1 ? "abruptly" : "suddenly", number_range(1,2) == 1 ? "cease" : "stop" ); break; case MAG_WATER: sprintf(buf, "&C%s bubbles %s around $n and %s with a %s.", number_range(1,2) == 1 ? "Small" : "Shimmering", number_range(1,2) == 1 ? "spin" : "swirl", number_range(1,2) == 1 ? "vanish" : "disappear", number_range(1,2) == 1 ? "pop" : "splash" ); break; case MAG_ACID: sprintf(buf, "&gA %s of %s acid %s around $n.", number_range(1,2) == 1 ? "shower" : "drizzle", number_range(1,2) == 1 ? "glistening" : "tiny flecks of", number_range(1,2) == 1 ? "swirls" : "spins" ); break; case MAG_DREAM: sprintf(buf, "&P$n %s %s as if %s from a %s.", number_range(1,2) == 1 ? "flashes" : "flickers", number_range(1,2) == 1 ? "for an instant" : "for a moment", number_range(1,2) == 1 ? "an image" : "something", number_range(1,2) == 1 ? "dream" : "nightmare" ); break; case MAG_SOUND: sprintf(buf, "&YA %s sound %s $n for a %s.", number_range(1,2) == 1 ? "humming" : "singing", number_range(1,2) == 1 ? "surrounds" : "eminates", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_HOLY: sprintf(buf, "&z&W%s %s light %s $n for a %s.", number_range(1,2) == 1 ? "Shimmering" : "Holy", number_range(1,2) == 1 ? "white" : "silver", number_range(1,2) == 1 ? "eminates from" : "surrounds", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_UNHOLY: case MAG_DRAIN: sprintf(buf, "&z%s %s %s $n for a %s.", number_range(1,2) == 1 ? "Tendrils of" : "Eerie", number_range(1,2) == 1 ? "shadows" : "darkness", number_range(1,2) == 1 ? "surround" : "twist around", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_POISON: sprintf(buf, "&g%s of %s %s %s $n.", number_range(1,2) == 1 ? "Wisps" : "Puffs", number_range(1,2) == 1 ? "smoke" : "poisonous gas", number_range(1,2) == 1 ? "swirl" : "circle", number_range(1,2) == 1 ? "in front of" : "around" ); break; case MAG_CHANGE: case MAG_TIME: sprintf(buf, "&B$n %s %s %s.", number_range(1,2) == 1 ? "twists" : "warps", number_range(1,2) == 1 ? "strangely" : "eerily", number_range(1,2) == 1 ? "briefly" : "for a moment" ); break; case MAG_TELEKINETIC: sprintf(buf, "&Y$n %s and %s for a %s.", number_range(1,2) == 1 ? "shivers" : "itches", number_range(1,2) == 1 ? "tickles" : "tingles", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_LIGHT: case MAG_SEEK: sprintf(buf, "&Y$n %s %s for a %s.", number_range(1,2) == 1 ? "glows" : "shines", number_range(1,2) == 1 ? "brightly" : "faintly", number_range(1,2) == 1 ? "moment" : "while" ); break; case MAG_PSIONIC: sprintf(buf, "&p$n %s %s with %s %s.", number_range(1,2) == 1 ? "shimmers" : "shines", number_range(1,2) == 1 ? "violet" : "faintly", number_range(1,2) == 1 ? "mental" : "psionic", number_range(1,2) == 1 ? "energy" : "power" ); break; case MAG_ANTIMATTER: case MAG_ANTIMAGIC: sprintf(buf, "&z%s black %s %s $n and %s.", number_range(1,2) == 1 ? "Crackling" : "Humming", number_range(1,2) == 1 ? "lightning" : "antimatter", number_range(1,2) == 1 ? "surrounds" : "encircles", number_range(1,2) == 1 ? "vanishes" : "disappears" ); break; case MAG_ETHER: sprintf(buf, "&w%s %s of %s %s %s $n.", number_range(1,2) == 1 ? "Insubstantial" : "Pale", number_range(1,2) == 1 ? "wisps" : "tendrils", number_range(1,2) == 1 ? "ether" : "mist", number_range(1,2) == 1 ? "float" : "swirl", number_range(1,2) == 1 ? "around" : "in front of" ); break; } act(AT_ACTION, buf, ch, NULL, NULL, TO_ROOM); act(AT_ACTION, buf, ch, NULL, NULL, TO_CHAR); } void obj_harm(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) { AREA_DATA *area; int vnum; char buf[MAX_STRING_LENGTH]; if (ch->in_room->pShop) { obj_trick(ch, obj, type); return; } switch (type) { default: obj_trick(ch, obj, type); break; case MAG_FIRE: if (IS_OBJ_STAT(obj, ITEM_ARTIFACT) || obj->item_type == ITEM_FIRE) { obj_trick(ch, obj, type); break; } if (obj->weight * 30 > power) { if (IS_OBJ_STAT(obj, ITEM_FLAMMABLE)) { act(AT_FIRE, "You set $p on fire.", ch, obj, NULL, TO_CHAR); act(AT_FIRE, "$n set $p on fire.", ch, obj, NULL, TO_ROOM); obj->item_type = ITEM_FIRE; obj->timer = obj->weight - (power / 30); sprintf(buf, "burning %s", myobj(obj)); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(buf); break; } else { obj_trick(ch, obj, type); break; } } if (IS_OBJ_STAT(obj, ITEM_FLAMMABLE)) { act(AT_FIRE, "You burn $p into ashes.", ch, obj, NULL, TO_CHAR); act(AT_FIRE, "$n burns $p into ashes.", ch, obj, NULL, TO_ROOM); dump_container(obj); extract_obj(obj); return; } if (!obj->material || obj->material->number == 116 /* ether */) { obj_trick(ch, obj, type); break; } if (!IS_OBJ_STAT(obj, ITEM_METAL)) { obj_trick(ch, obj, type); break; } vnum = 0; if (!stockobj) for (area=first_area; area; area=area->next) { if (!str_cmp( area->filename, "stockobj.are" )) { stockobj = area; vnum = area->hi_o_vnum; break; } } else { area = stockobj; vnum=area->hi_o_vnum; } if (vnum == 0) { bug("Cannot find stockobj.are!",0); return; } act(AT_FIRE, "You melt $p into a misshapen lump of metal.", ch, obj, NULL, TO_CHAR); act(AT_FIRE, "$n melts $p into a misshapen lump of metal.", ch, obj, NULL, TO_ROOM); obj->cost -= obj->pIndexData->cost; obj->pIndexData = get_obj_index(vnum); STRFREE(obj->name); obj->name = STRALLOC(obj->material->name); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(obj->material->short_descr); obj->item_type = ITEM_TREASURE; xCLEAR_BITS(obj->parts); break; case MAG_ANTIMATTER: if (ch->curr_talent[TAL_VOID] < 100) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (obj->weight * 10 > power) { obj_trick(ch, obj, type); break; } act(AT_DGREY, "You burn $p out of existance!", ch, obj, NULL, TO_CHAR); act(AT_DGREY, "$n burns $p out of existance!", ch, obj, NULL, TO_ROOM); dump_container(obj); extract_obj(obj); break; case MAG_COLD: if (ch->curr_talent[TAL_FROST] < 100) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (obj->weight * 30 > power) { obj_trick(ch, obj, type); break; } act(AT_FROST, "You freeze $p solid and shatter it!", ch, obj, NULL, TO_CHAR); act(AT_FROST, "$n freezes $p solid and shatters it!", ch, obj, NULL, TO_ROOM); dump_container(obj); extract_obj(obj); break; case MAG_DRAIN: if (ch->curr_talent[TAL_DEATH] < 20) { obj_trick(ch, obj, type); break; } if (obj->timer <= 0) { act( AT_BLOOD, "$p starts to decay slowly.", ch, obj, NULL, TO_CHAR); obj->timer = 100; return; } act( AT_BLOOD, "$p decays further.", ch, obj, NULL, TO_CHAR); obj->timer -= TALENT(ch, TAL_DEATH)/10; if (obj->timer < 1) obj->timer = 1; break; case MAG_ELECTRICITY: if (ch->curr_talent[TAL_LIGHTNING] < 75) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (!IS_OBJ_STAT(obj, ITEM_EXPLOSIVE)) { if (obj->weight*20 < power) { obj->timer = 1; xSET_BIT(obj->extra_flags, ITEM_EXPLOSIVE); act(AT_FIRE, "You add an explosive charge to $p.", ch, obj, NULL, TO_CHAR); } else { obj_trick(ch, obj, type); break; } } else { obj->timer = 0; xREMOVE_BIT(obj->extra_flags, ITEM_EXPLOSIVE); act(AT_FIRE, "You remove the explosive charge from $p.", ch, obj, NULL, TO_CHAR); } break; } } void ch_harm(CHAR_DATA *victim, CHAR_DATA *ch, int dam, int type, bool dont_wait) { if (!victim || victim == NULL) { ch_trick(ch, type); return; } if (char_died(victim)) return; if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) { ch_trick(victim, type); return; } if (!IS_SAME_PLANE(ch, victim)) { if (CAN_SEE_PLANE(ch, victim)) send_to_char("That appears to have no affect.\n\r", ch); return; } if (!dont_wait) { STRFREE(ch->last_taken); ch->last_taken = STRALLOC("channeling"); WAIT_STATE(ch, PULSE_VIOLENCE); } if (victim->shield == type) { act(AT_MAGIC, "Your $t bounces off $N's shield!", ch, magic_table[type], victim, TO_CHAR); act(AT_MAGIC, "$n's $t bounces off $N's shield!", ch, magic_table[type], victim, TO_NOTVICT); act(AT_MAGIC, "$n's $t bounces off your shield!", ch, magic_table[type], victim, TO_VICT); /* don't keep them bouncing back and forth */ if (ch->shield == type) { act(AT_MAGIC, "Your $t fizzles out harmlessly.", ch, magic_table[type], NULL, TO_CHAR); act(AT_MAGIC, "$n's $t fizzles out harmlessly", ch, magic_table[type], NULL, TO_ROOM); return; } /* send it back at them */ ch_harm(ch, victim, dam, type, TRUE); return; } if (check_displacement(ch, victim)) return; if (check_antimagic(ch, victim)) return; if (type == MAG_UNHOLY) { if (IS_AFFECTED(victim, AFF_ANGEL)) { dam *= 2; } else { dam /= 2; } } else if (type == MAG_HOLY) { if (IS_AFFECTED(victim, AFF_DEMON)) { dam *= 2; } else { dam /= 2; } } else if (type == MAG_DREAM) { if (IS_AFFECTED(victim, AFF_DREAMWORLD)) { dam *= 3; } else { dam = 0; } } else if (IS_UNDERWATER(victim) && type == MAG_FIRE) dam /= 2; else if (type == MAG_EARTH) dam = (dam * 200) / (victim->in_room->curr_vegetation +10); else if (type == MAG_WATER) dam = (dam * 200) / (victim->in_room->curr_water +10); dam = number_range(dam, dam*5); dam = URANGE(1, dam, 5000); /* dam = (100 - TALENT(victim, talent)) * dam / 100; */ if (type == MAG_DRAIN) { dam /= 2; ch->hit += dam; if (ch->hit > ch->max_hit) ch->hit = ch->max_hit; } if (dam <= 0) { act(AT_MAGIC, "The magic has no effect.", victim, NULL, NULL, TO_ROOM); act(AT_MAGIC, "The magic has no effect.", victim, NULL, NULL, TO_CHAR); if (IS_NPC(ch) && number_range(20,50) < get_curr_int(ch)) xSET_BIT(ch->act, ACT_MAG_FAIL); return; } act(AT_MAGIC, "Your $t hits $N!", ch, magic_table[type], victim, TO_CHAR); act(AT_MAGIC, "$n's $t hits $N!", ch, magic_table[type], victim, TO_NOTVICT); act(AT_MAGIC, "$n's $t hits you!", ch, magic_table[type], victim, TO_VICT); victim->last_hit = ch; ch->last_hit = victim; if (can_gain_exp(ch, victim)) gain_exp(ch, get_exp_worth(victim) * dam / 100); direct_damage(victim, dam); if (char_died(victim)) return; pain(victim, dam); climate_affect(victim, type); } void obj_help(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) { int amt; bool found; AFFECT_DATA *paf; if ( IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); return; } separate_obj(obj); amt = 50; found = FALSE; if (obj->mana < amt && type != MAG_TIME && type != MAG_ALL && type != MAG_LIGHT && type != MAG_UNHOLY) { obj_trick(ch, obj, type); return; } switch (type) { default: obj_trick(ch, obj, type); break; case MAG_ALL: if (obj->mana < amt || IS_OBJ_STAT(obj, ITEM_MAGIC) || ch->curr_talent[TAL_CATALYSM] < 40) { act(AT_MAGIC, "You funnel raw energy into $p.", ch, obj, NULL, TO_CHAR); if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { send_to_char("The magic is absorbed with no effect.\n\r",ch); return; } power /= obj->weight == 0 ? 1 : obj->weight; obj->raw_mana += power; if (obj->gem) obj->gem->raw_mana += power; if (obj->raw_mana > 2000 + TALENT(ch, TAL_CATALYSM)*5 + ch->pcdata->noncombat[SK_CHANNEL]*20) { act(AT_DANGER, "The overcharged item explodes in your hands!", ch, NULL, NULL, TO_CHAR); act(AT_ACTION, "$p explodes in $n's hands.", ch, obj, NULL, TO_ROOM); lose_hp(ch, obj->mana*3 + (obj->raw_mana / 20)); extract_obj(obj); } else if (obj->raw_mana > 2000) act(AT_PURPLE, "$p vibrates violently!", ch, obj, NULL, TO_CHAR); return; } act(AT_PINK, "The raw mana settles into $n's $p, emitting a mystic glow.", ch, obj, NULL, TO_ROOM); act(AT_PINK, "The raw mana settles into $p, emitting a mystic glow.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_MAGIC); break; case MAG_HOLY: amt = 500; if (IS_OBJ_STAT(obj, ITEM_SHIELD)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_SECURITY] + ch->curr_talent[TAL_CATALYSM] < 195) { obj_trick(ch, obj, type); return; } if (obj->mana < amt) { obj_trick(ch, obj, type); return; } act(AT_WHITE, "A holy light eminates from $n's $p, coalescing into a protective barrier.", ch, obj, NULL, TO_ROOM); act(AT_WHITE, "A holy light eminates from $p, coalescing into a protective barrier.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_SHIELD); obj->cost += 450000; break; case MAG_LIGHT: if (IS_OBJ_STAT(obj, ITEM_GLOW)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_ILLUSION] < 30) { obj_trick(ch, obj, type); return; } if (IS_OBJ_STAT(obj, ITEM_DARK)) { if (obj->value[4] == BRAND_ANTI_MATTER) { send_to_char("The weapon absorbs all the light and remains dark.\n\r", ch); return; } act( AT_YELLOW, "The $t takes in some of the light around it.", ch, myobj(obj), NULL, TO_CHAR); act( AT_YELLOW, "$n's $t takes in some of the light around it.", ch, myobj(obj), NULL, TO_ROOM); xREMOVE_BIT(obj->extra_flags, ITEM_DARK); return; } act( AT_YELLOW, "The $t shines brightly!", ch, myobj(obj), NULL, TO_CHAR); act( AT_YELLOW, "$n's $t shines brightly!", ch, myobj(obj), NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_GLOW); return; case MAG_UNHOLY: if (IS_OBJ_STAT(obj, ITEM_DARK)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_DEATH] < 30) { obj_trick(ch, obj, type); return; } if (IS_OBJ_STAT(obj, ITEM_GLOW)) { if (obj->value[4] == BRAND_RADIANT) { send_to_char("You are unable to quench this radiant light.\n\r", ch); return; } act( AT_MAGIC, "The $t grows dim and ceases to shine.", ch, myobj(obj), NULL, TO_CHAR); act( AT_MAGIC, "$n's $t grows dim and ceases to shine.", ch, myobj(obj), NULL, TO_ROOM); xREMOVE_BIT(obj->extra_flags, ITEM_GLOW); return; } act( AT_MAGIC, "Swirling shadows shroud the $t.", ch, myobj(obj), NULL, TO_CHAR); act( AT_MAGIC, "Swirling shadows shroud $n's $t.", ch, myobj(obj), NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_DARK); return; case MAG_TELEKINETIC: amt = 100; if (IS_OBJ_STAT(obj, ITEM_RETURNING)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_MOTION] < 50 && TALENT(ch, TAL_MOTION) < 50) { obj_trick(ch, obj, type); return; } if (obj->mana < amt) { obj_trick(ch, obj, type); return; } act(AT_YELLOW, "$n's $p twitches for a moment, as a telekinetic enchantment settles in.", ch, obj, NULL, TO_ROOM); act(AT_YELLOW, "$p twitches for a moment, as a telekinetic enchantment settles in.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_RETURNING); break; case MAG_WATER: if (ch->curr_talent[TAL_WATER] < 40) { obj_trick(ch, obj, type); return; } CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_AFFECT; SET_BIT(paf->modifier, 1 << AFF_AQUA_BREATH); xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_BLUE, "Bubbles erupt from $n's $p as it glows with a watery film.", ch, obj, NULL, TO_ROOM); act(AT_BLUE, "Bubbles erupt from $p as it glows with a watery film.", ch, obj, NULL, TO_CHAR); break; case MAG_WIND: if (ch->curr_talent[TAL_WIND] < 60) { obj_trick(ch, obj, type); return; } CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_AFFECT; SET_BIT(paf->modifier, 1 << AFF_FLYING); xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_LBLUE, "$n's $p sprouts a pair of tiny wings.", ch, obj, NULL, TO_ROOM); act(AT_LBLUE, "$p sprouts a pair of tiny wings.", ch, obj, NULL, TO_CHAR); break; case MAG_SEEK: if (ch->curr_talent[TAL_SEEKING] < 80) { obj_trick(ch, obj, type); return; } CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_AFFECT; SET_BIT(paf->modifier, 1 << AFF_TRUESIGHT); xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_YELLOW, "$n's $p glows for a long while with a pure and true light.", ch, obj, NULL, TO_ROOM); act(AT_YELLOW, "$p glows for a long while with a pure and true light.", ch, obj, NULL, TO_CHAR); break; case MAG_DRAIN: if (obj->item_type != ITEM_WEAPON && obj->item_type != ITEM_MISSILE_WEAPON) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_DEATH] < 10) { obj_trick(ch, obj, type); return; } amt = URANGE(10, 250 - TALENT(ch, TAL_DEATH), 200); amt += obj->value[2]; if (obj->mana < amt) { obj_trick(ch, obj, type); return; } obj->value[2] += 5; act(AT_DGREY, "$n's $p glints with a deadly power.", ch, obj, NULL, TO_ROOM); act(AT_DGREY, "$p glints with a deadly power.", ch, obj, NULL, TO_CHAR); break; case MAG_ANTIMATTER: if (obj->item_type != ITEM_CONTAINER) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_VOID] >= 10) { obj_trick(ch, obj, type); return; } amt = URANGE(10, 250 - TALENT(ch, TAL_VOID), 200); amt += obj->value[0] / 10; if (obj->mana < amt) { obj_trick(ch, obj, type); return; } obj->value[0] += TALENT(ch, TAL_VOID) / 10; act(AT_DGREY, "$n's $p ripples strangely, the space within stretching to infinity.", ch, obj, NULL, TO_ROOM); act(AT_DGREY, "$p ripples strangely, the space within stretching to infinity.", ch, obj, NULL, TO_CHAR); break; case MAG_BLUNT: amt = 200; if (IS_OBJ_STAT(obj, ITEM_DURABLE)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_SECURITY] + ch->curr_talent[TAL_EARTH] < 100) { obj_trick(ch, obj, type); return; } if (obj->mana < amt) { obj_trick(ch, obj, type); return; } act(AT_ORANGE, "$n's $p radiates strentch and durability.", ch, obj, NULL, TO_ROOM); act(AT_ORANGE, "$p radiates strentch and durability.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_DURABLE); break; case MAG_TIME: if (ch->curr_talent[TAL_TIME] < 10) { obj_trick(ch, obj, type); return; } if (obj->timer <= 0 || IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); return; } obj->timer += TALENT(ch, TAL_TIME); if (obj->timer > 100) obj->timer = 0; act(AT_MAGIC, "$p flickers for a moment.", ch, obj, NULL, TO_CHAR); return; } WAIT_STATE(ch, PULSE_VIOLENCE*2); obj->mana -= amt; obj->cost += 50000; } void ch_help(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) { PART_DATA *part; AFFECT_DATA af; int sn; switch (type) { default: ch_trick(victim, type); break; case MAG_HOLY: if (victim == ch) { act(AT_MAGIC, "You close your eyes and relax, focusing on healing.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n closes $s eyes and breathes deeply, $s wounds closing.", ch, NULL, NULL, TO_ROOM); } else { act(AT_MAGIC, "$n concentrates on you, and pain eases out of your body", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "$n concentrates on $N, whose wounds begin to close.", ch, NULL, victim, TO_NOTVICT); act(AT_MAGIC, "You concentrate on $N, easing $S pain and healing $S wounds.", ch, NULL, victim, TO_CHAR); } if (IS_AFFECTED(ch, AFF_UNHOLY) && power != 0) power /= 2; if (IS_AFFECTED(ch, AFF_HOLY)) power *= 2; if (victim == ch) power *= 2; if (!IS_FIGHTING(ch)) power *= 2; victim->hit += power; for (part = victim->first_part;part;part = part->next) { if (part->flags == PART_SEVERED && part->cond == PART_WELL && (part->connect_to ? part->connect_to->flags != PART_SEVERED : TRUE) && power > 300) { act(AT_MAGIC, "Your $t grows back!", victim, part_locs[part->loc], NULL, TO_CHAR); act(AT_MAGIC, "$n's $t grows back!", victim, part_locs[part->loc], NULL, TO_ROOM); part->flags = PART_WELL; return; /* No more healing after a part is regened */ } else { part->cond = UMIN(PART_WELL, part->cond+power/10); } } if (victim->hit > victim->max_hit) victim->hit = victim->max_hit; break; case MAG_LIGHT: if (power > TALENT(ch, TAL_ILLUSION)) { ch->pcdata->wizinvis = TALENT(ch, TAL_ILLUSION); } else { ch->pcdata->wizinvis = power; } if (xIS_SET(ch->act, PLR_WIZINVIS)) { xREMOVE_BIT(ch->act, PLR_WIZINVIS); act( AT_IMMORT, "$n slowly fades into existence.", ch, NULL, NULL, TO_ROOM ); send_to_char( "You slowly fade back into existence.\n\r", ch ); } else { if (ch->pcdata->wizinvis < 1 || ch->pcdata->wizinvis > TALENT(ch, TAL_ILLUSION)) ch->pcdata->wizinvis = TALENT(ch, TAL_ILLUSION); act(AT_IMMORT, "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM); send_to_char("You slowly vanish into thin air.\n\r", ch); xSET_BIT(ch->act, PLR_WIZINVIS); } break; case MAG_POISON: if (ch->curr_talent[TAL_HEALING] < 15) { ch_trick(victim, type); return; } if ( !is_affected( victim, gsn_poison ) ) { ch_trick(victim, type); return; } affect_strip( victim, gsn_poison ); set_char_color( AT_MAGIC, victim); send_to_char( "A warm feeling runs through your body.\n\r", victim); victim->mental_state = URANGE( -100, victim->mental_state, -10 ); act( AT_MAGIC, "A flush of health washes over $N.", ch, NULL, victim, TO_NOTVICT); if ( ch != victim ) { act( AT_MAGIC, "You lift the poison from $N's body.", ch, NULL, victim, TO_CHAR); } break; case MAG_DRAIN: if (ch->curr_talent[TAL_HEALING] < 60) { ch_trick(victim, type); return; } if ( !is_affected( victim, gsn_mummy_rot ) ) { ch_trick(victim, type); return; } affect_strip( victim, gsn_mummy_rot ); set_char_color( AT_MAGIC, victim); send_to_char( "Your flesh feels more resilient.\n\r", victim); victim->mental_state = URANGE( -100, victim->mental_state, -10 ); act( AT_MAGIC, "$N's flesh stops rotting.", ch, NULL, victim, TO_NOTVICT); if ( ch != victim ) { act( AT_MAGIC, "You cure the rotting disease from $N's body.", ch, NULL, victim, TO_CHAR); } break; case MAG_SEEK: if (ch->curr_talent[TAL_HEALING] < 25 && ch->curr_talent[TAL_SEEKING] < 25) { ch_trick(victim, type); return; } if ( !is_affected( victim, gsn_blindness ) ) { ch_trick(victim, type); return; } affect_strip( victim, gsn_blindness ); set_char_color( AT_MAGIC, victim); send_to_char( "Your vision returns!\n\r", victim ); if ( ch != victim ) send_to_char( "You work your cure, restoring vision.\n\r", ch ); break; case MAG_CHANGE: if (ch->curr_talent[TAL_HEALING] < 25 && ch->curr_talent[TAL_CHANGE] < 25) { ch_trick(victim, type); return; } if (!is_affected( victim, gsn_corruption)) { ch_trick(victim, type); return; } affect_strip( victim, gsn_corruption ); set_char_color( AT_MAGIC, victim ); send_to_char( "Waves of magic cleanse your body.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You cleanse $N's body of corruption.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N's body returns to normal again.", ch, NULL, victim, TO_NOTVICT); break; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 50) { ch_trick(victim, type); return; } sn = gsn_fire; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_RESISTANT; af.modifier = RIS_FIRE; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); send_to_char( "You are protected from heat.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You protect $N from heat.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N is protected from heat.", ch, NULL, victim, TO_NOTVICT); break; case MAG_COLD: if (ch->curr_talent[TAL_FROST] < 50) { ch_trick(victim, type); return; } sn = gsn_frost; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_RESISTANT; af.modifier = RIS_COLD; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); update_pos(victim); send_to_char( "You are protected from cold.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You protect $N from cold.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N is protected from cold.", ch, NULL, victim, TO_NOTVICT); break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] < 50) { ch_trick(victim, type); return; } victim->mental_state = 0; act( AT_MAGIC, "You balance $N's mind.", ch, NULL, victim, TO_CHAR); act( AT_MAGIC, "Your mind is balanced.", ch, NULL, victim, TO_VICT); break; case MAG_ACID: if (ch->curr_talent[TAL_HEALING] < 20 && ch->curr_talent[TAL_WATER] < 20) { ch_trick(victim, type); return; } if ( victim->pcdata && victim->pcdata->condition[COND_DRUNK] <= 0 ) { ch_trick(victim, type); return; } if ( victim->pcdata ) victim->pcdata->condition[COND_DRUNK] = 0; act(AT_MAGIC, "You purge the alcohol from $N's system.", ch, NULL, victim, TO_CHAR ); act(AT_MAGIC, "$n purges the alcohol from your system.", ch, NULL, victim, TO_VICT ); break; case MAG_TELEKINETIC: if (ch->curr_talent[TAL_HEALING] < 10) { ch_trick(victim, type); return; } if (victim->move >= victim->max_move) { ch_trick(victim, type); return; } victim->move = UMAX(victim->move + power, victim->max_move); update_pos(victim); send_to_char( "Vitality and stamina return to you.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You let vitality flow into $N's body.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N's body seems to grow less exhausted.", ch, NULL, victim, TO_NOTVICT); break; case MAG_BLUNT: if (ch->curr_talent[TAL_EARTH] < 30) { ch_trick(victim, type); return; } if (IS_NPC(victim) || victim->pcdata->condition[COND_FULL] < 0) { ch_trick(victim, type); return; } victim->pcdata->condition[COND_FULL] += 20; send_to_char("You are satiated.", victim); if (ch != victim) { act(AT_MAGIC, "You fill $N's stomach.", ch, NULL, victim, TO_CHAR); } break; case MAG_UNHOLY: if (ch->curr_talent[TAL_HEALING] < 30) { ch_trick(victim, type); return; } if (!is_affected(victim, gsn_curse)) { ch_trick(victim, type); return; } affect_strip(victim, gsn_curse); send_to_char("The weight of your curse is lifted.\n\r", victim); if (ch != victim) { act(AT_MAGIC, "You dispel the curse afflicting $N.", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "$n's dispels the curse afflicting $N.", ch, NULL, victim, TO_NOTVICT); } break; case MAG_WATER: if (ch->curr_talent[TAL_WATER] < 50) { ch_trick(victim, type); return; } if (IS_NPC(victim) || victim->pcdata->condition[COND_THIRST] < 0) { ch_trick(victim, type); return; } victim->pcdata->condition[COND_THIRST] += 10; act( AT_MAGIC, "You feel bloated.", ch, NULL, victim, TO_VICT); act( AT_MAGIC, "You fill $N up with water.", ch, NULL, victim, TO_CHAR); break; } } void obj_hinder(CHAR_DATA *ch, OBJ_DATA *obj, int type) { bool found; AFFECT_DATA *paf; found = FALSE; switch (type) { default: obj_trick(ch, obj, type); return; case MAG_HOLY: if (obj->item_type != ITEM_ARMOR) { obj_trick(ch, obj, type); break; } if (TALENT(ch, TAL_SECURITY) / 10 > (obj->pIndexData->value[0] - obj->value[0])) { act(AT_WHITE, "You reduce the protective ability of $p.", ch, obj, NULL, TO_CHAR); obj->value[0]--; } else { obj_trick(ch, obj, type); return; } break; case MAG_EARTH: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CON && !found) { if (TALENT(ch, TAL_EARTH) / 10 > -1 * paf->modifier) { act(AT_GREEN, "You hinder $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_CON; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_GREEN, "You hinder $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); } break; case MAG_COLD: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_LCK && !found) { if (TALENT(ch, TAL_FROST) / 10 > -1 * paf->modifier) { act(AT_FROST, "You hinder $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_LCK; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_FROST, "You hinder $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); } break; case MAG_FIRE: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_STR && !found) { if (TALENT(ch, TAL_FIRE) / 10 > -1 * paf->modifier) { act(AT_FIRE, "You hinder $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_STR; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_FIRE, "You hinder $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); } break; case MAG_SEEK: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CHA && !found) { if (TALENT(ch, TAL_SEEKING) / 10 > -1 * paf->modifier) { act(AT_GREEN, "You hinder $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_CHA; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_GREEN, "You hinder $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); } break; case MAG_WIND: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DEX && !found) { if (TALENT(ch, TAL_WIND) / 10 > -1 * paf->modifier) { act(AT_CYAN, "You hinder $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_DEX; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_CYAN, "You hinder $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); } break; case MAG_WATER: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_WIS && !found) { if (TALENT(ch, TAL_WATER) / 10 > -1 * paf->modifier) { act(AT_BLUE, "You hinder $p with the power of Water.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_WIS; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_BLUE, "You hinder $p with the power of Water.", ch, obj, NULL, TO_CHAR); } break; case MAG_PSIONIC: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_INT && !found) { if (TALENT(ch, TAL_MIND) / 10 > -1 * paf->modifier) { act(AT_PURPLE, "You hinder $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_INT; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_PURPLE, "You hinder $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); } break; case MAG_ELECTRICITY: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DAMROLL && !found) { if (TALENT(ch, TAL_LIGHTNING) / 10 > -1 * paf->modifier) { act(AT_YELLOW, "You hinder $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_DAMROLL; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_YELLOW, "You hinder $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); } break; case MAG_TELEKINETIC: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_HITROLL && !found) { if (TALENT(ch, TAL_MOTION) / 10 > -1 * paf->modifier) { act(AT_YELLOW, "You hinder $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); paf->modifier--; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_HITROLL; paf->modifier = -1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_YELLOW, "You hinder $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); } break; } WAIT_STATE(ch, PULSE_VIOLENCE*2); obj->mana += 50; obj->cost -= 50000; } void ch_hinder(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) { AFFECT_DATA af; int sn; switch (type) { default: ch_trick(victim, type); break; case MAG_EARTH: if (ch->in_room->curr_vegetation < 100 - ch->curr_talent[TAL_EARTH]) { ch_trick(victim, type); return; } if (ch->curr_talent[TAL_EARTH] > number_range(10,50)) { act(AT_GREEN, "You are entangled in vines!", ch, NULL, victim, TO_VICT); act(AT_GREEN, "$N is entangled in vines!", ch, NULL, victim, TO_NOTVICT); act(AT_GREEN, "You entangle $N in vines!", ch, NULL, victim, TO_CHAR); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_HOLD); else xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD); } else { act(AT_GREEN, "Vines grab for you but fail to hold you!", ch, NULL, victim, TO_VICT); act(AT_GREEN, "Your vines fail to hold $N!", ch, NULL, victim, TO_CHAR); } break; case MAG_COLD: if (ch->in_room->area->weather->temp > ch->curr_talent[TAL_FROST]*10 - 400) { ch_trick(victim, type); return; } if (ch->curr_talent[TAL_FROST] > number_range(10,50)) { act(AT_FROST, "Ice forms around you, holding you in place!", ch, NULL, victim, TO_VICT); act(AT_FROST, "Ice forms around $N!", ch, NULL, victim, TO_NOTVICT); act(AT_FROST, "You hold $N in ice!", ch, NULL, victim, TO_CHAR); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_HOLD); else xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD); } else { act(AT_FROST, "Ice forms around you but fails to hold you!", ch, NULL, victim, TO_VICT); act(AT_FROST, "Your ice fails to hold $N!", ch, NULL, victim, TO_CHAR); } break; case MAG_WATER: if (!IS_UNDERWATER(victim)) { if (ch->curr_talent[TAL_WATER] < 60) { ch_trick(victim, type); return; } if (IS_NPC(victim) || victim->pcdata->condition[COND_THIRST] < 0) { ch_trick(victim, type); return; } victim->pcdata->condition[COND_THIRST] = 0; act( AT_MAGIC, "You are DYING of THIRST!", ch, NULL, victim, TO_VICT); act( AT_MAGIC, "You drain all the water from $N's body.", ch, NULL, victim, TO_CHAR); break; } if (ch->curr_talent[TAL_WATER] > number_range(10,50)) { act(AT_MAGIC, "A whirlpool spins around you, holding you in place!", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "$N is held in a whirlpool!", ch, NULL, victim, TO_NOTVICT); act(AT_MAGIC, "You hold $N in a whirlpool!", ch, NULL, victim, TO_CHAR); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_HOLD); else xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD); } else { act(AT_MAGIC, "A whirlpool spins near you, but you swim away!", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "Your whirlpool fails to hold $N!", ch, NULL, victim, TO_CHAR); } break; case MAG_TIME: if (ch->curr_talent[TAL_TIME] > number_range(10,50)) { act(AT_MAGIC, "You are held in place!", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "$N's feet are held to the floor!", ch, NULL, victim, TO_NOTVICT); act(AT_MAGIC, "You hold $N in place!", ch, NULL, victim, TO_CHAR); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_HOLD); else xSET_BIT(victim->pcdata->perm_aff, AFF_HOLD); } else { act(AT_MAGIC, "Something grabs at you, but fails to hold you!", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "Your magic fails to hold $N!", ch, NULL, victim, TO_CHAR); } break; case MAG_ANTIMAGIC: if (victim != ch && ch->curr_talent[TAL_VOID] < 30) { ch_trick(victim, type); return; } if (TALENT(victim, TAL_SECURITY) > TALENT(ch, TAL_VOID) && ch != victim && !IS_CONSENTING(victim, ch)) { act(AT_MAGIC, "$N's magic wavers but holds.", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "Your magic wavers but holds.", ch, NULL, victim, TO_VICT); learn_talent(victim, TAL_SECURITY); return; } if ( victim->first_affect ) { send_to_char ( "Your enchantments are stripped away by powerful magic.\n\r", victim); if (ch != victim) { act(AT_MAGIC, "You strip away $N's enchantments.", ch, NULL, victim, TO_CHAR); } while ( victim->first_affect ) affect_remove ( victim, victim->first_affect ); WAIT_STATE(ch, PULSE_VIOLENCE); } else { ch_trick(victim, type); return; } break; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 30) { ch_trick(victim, type); return; } sn = gsn_sticky_flame; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } if (IS_SET(victim->immune, RIS_FIRE)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power/10; af.location = APPLY_DAMROLL; af.modifier = TALENT(ch, TAL_FIRE)/40; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_FLAMING); affect_join( victim, &af ); send_to_char ("Sticky flames cover your body!\n\r", victim); if (ch != victim) act(AT_FIRE, "You cover $N in sticky fire!", ch, NULL, victim, TO_CHAR); break; case MAG_SEEK: if (ch->curr_talent[TAL_ILLUSION] < 30) { ch_trick(victim, type); return; } sn = gsn_blindness; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } if (IS_AFFECTED(victim, AFF_TRUESIGHT)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power/10; af.location = APPLY_HITROLL; af.modifier = -1 * TALENT(ch, TAL_ILLUSION)/20; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_BLIND); affect_join( victim, &af ); send_to_char ("You are blinded by a flash of light!\n\r", victim); if (ch != victim) act(AT_YELLOW, "You blind $N with a flash of light!", ch, NULL, victim, TO_CHAR); break; case MAG_POISON: if (ch->curr_talent[TAL_DEATH] < 30) { ch_trick(victim, type); return; } sn = gsn_poison; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } if (IS_SET(victim->immune, RIS_POISON) || IS_AFFECTED(victim, AFF_NONLIVING)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power/10; af.location = APPLY_STR; af.modifier = -1 * TALENT(ch, TAL_DEATH)/40; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_POISON); affect_join( victim, &af ); victim->mental_state = URANGE( 10, victim->mental_state + 10, 100 ); send_to_char ("You feel very sick.\n\r", victim); if (ch != victim) act(AT_DGREEN, "You spread poison into $N's body.", ch, NULL, victim, TO_CHAR); act(AT_DGREEN, "$N begins to look very sick.", ch, NULL, victim, TO_ROOM); break; case MAG_DRAIN: if (ch->curr_talent[TAL_DEATH] < 60) { ch_trick(victim, type); return; } sn = gsn_mummy_rot; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } if (IS_SET(victim->immune, RIS_DRAIN) || IS_AFFECTED(victim, AFF_NONLIVING)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_CON; af.modifier = -1 * TALENT(ch, TAL_DEATH)/50; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_ROTTING); affect_join( victim, &af ); send_to_char ("Your flesh begins to rot away.\n\r", victim); if (ch != victim) act(AT_DGREY, "You make $N's flesh begin to rot away.", ch, NULL, victim, TO_CHAR); act(AT_DGREY, "$N's flesh begins to rot away.", ch, NULL, victim, TO_ROOM); break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 40) { ch_trick(victim, type); return; } sn = gsn_curse; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_HITROLL; af.modifier = -1 * TALENT(ch, TAL_DEATH)/50; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_CURSE); affect_join( victim, &af ); send_to_char ("You feel unlucky.\n\r", victim); if (ch != victim) act(AT_DGREY, "You inflict a curse upon $N.", ch, NULL, victim, TO_CHAR); act(AT_DGREY, "A malignant aura surrounds $N for a moment.", ch, NULL, victim, TO_ROOM); break; case MAG_DREAM: sn = gsn_sleep; if (ch->curr_talent[TAL_DREAM] < 30) { ch_trick(victim, type); return; } if (!IS_NPC(victim) && IS_FIGHTING(victim)) { ch_trick(victim, type); return; } if (IS_SET( victim->immune, RIS_SLEEP)) { ch_trick(victim, type); return; } if (is_affected(victim, sn)) { ch_trick(victim, type); break; } if (number_range(1, get_curr_wil(ch)) < number_range(1, get_curr_wil(victim) + TALENT(victim, TAL_SECURITY))) { ch_trick(victim, type); return; } if (!IS_FIGHTING(victim)) { victim->last_hit = ch; ch->last_hit = victim; } else { ch_trick(victim, type); return; } af.type = sn; af.duration = power/20; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = meb(AFF_SLEEP); affect_join(victim, &af); if (!IS_NPC(victim)) { sprintf(log_buf, "%s has cast sleep on %s.", ch->name, victim->name); to_channel(log_buf, "Spell", PERMIT_SECURITY); } if (IS_AWAKE(victim)) { act(AT_MAGIC, "You feel very sleepy ..... zzzzzz.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n goes to sleep.", victim, NULL, NULL, TO_ROOM); victim->position = POS_SLEEPING; } if (IS_NPC(victim)) start_hating(victim, ch); break; case MAG_BLUNT: if (ch->curr_talent[TAL_EARTH] < 60) { ch_trick(victim, type); return; } if (IS_NPC(victim) || victim->pcdata->condition[COND_FULL] < 0) { ch_trick(victim, type); return; } victim->pcdata->condition[COND_FULL] = 0; act( AT_HUNGRY, "You are STARVING!", ch, NULL, victim, TO_VICT); act( AT_MAGIC, "You reach out your hand, and $N's body shrivels.", ch, NULL, victim, TO_CHAR); act( AT_MAGIC, "$n reaches out $s hand, and $N's body shrivels.", ch, NULL, victim, TO_NOTVICT); break; case MAG_SOUND: if (ch->curr_talent[TAL_SPEECH] < 60) { ch_trick(victim, type); return; } stop_fighting(ch, TRUE); act(AT_SAY, "You hum a tranquil melody to $N.", ch, NULL, victim, TO_CHAR); act(AT_SAY, "$n hums a tranquil melody to $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SAY, "$n hums a tranquil melody, and you feel at peace.", ch, NULL, victim, TO_VICT); break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] < 50) { ch_trick(victim, type); return; } sn = gsn_mind; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_MENTALSTATE; af.modifier = ch->curr_talent[TAL_MIND]; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); send_to_char ("Suddenly the world seems strange to you as you begin to hallucinate...\n\r", victim); if (ch != victim) act(AT_DGREY, "You fill $N's mind with rampant hallucinations.", ch, NULL, victim, TO_CHAR); act(AT_DGREY, "$N's eyes grow wide and $E starts hallucinating.", ch, NULL, victim, TO_ROOM); break; case MAG_HOLY: if (ch->curr_talent[TAL_SECURITY] < 50) { ch_trick(victim, type); return; } sn = gsn_security; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_AC; af.modifier = -1 * TALENT(ch, TAL_SECURITY) / 10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); send_to_char ("You feel vulnerable.\n\r", victim); if (ch != victim) act(AT_DGREY, "You make $N vulnerable.", ch, NULL, victim, TO_CHAR); act(AT_DGREY, "$N seems naked for a moment as $E becomes vulnerable.", ch, NULL, victim, TO_ROOM); break; } } void room_hinder(CHAR_DATA *ch, ROOM_INDEX_DATA *room, int type, int power, char *argument) { EXIT_DATA *pexit; switch (type) { default: ch_trick(ch, type); break; case MAG_EARTH: if (ch->curr_talent[TAL_DEATH] < 20) { ch_trick(ch, type); return; } if (ch->in_room->curr_vegetation <= 0) { ch_trick(ch, type); return; } ch->in_room->curr_vegetation -= 10; act( AT_HUNGRY, "You touch the plants in the room, and they begin to wither.", ch, NULL, NULL, TO_CHAR); act( AT_HUNGRY, "The vegetation in the room withers.", ch, NULL, NULL, TO_ROOM); break; case MAG_WATER: if (ch->curr_talent[TAL_FIRE] < 20) { ch_trick(ch, type); return; } if(ch->in_room->curr_water <= 0) { ch_trick(ch, type); return; } ch->in_room->curr_water -= 10; act( AT_THIRSTY, "Water drains out of the room.", ch, NULL, NULL, TO_CHAR); act( AT_THIRSTY, "Water begins to drain out of the room.", ch, NULL, NULL, TO_ROOM); break; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 60) { ch_trick(ch, type); return; } if (ch->in_room->curr_vegetation < 10) { ch_trick(ch, type); return; } if (ch->in_room->curr_water > 30) { ch_trick(ch, type); return; } act(AT_FIRE, "You set fire to the room!", ch, NULL, NULL, TO_CHAR); act(AT_FIRE, "$n sets fire to the room!", ch, NULL, NULL, TO_ROOM); SET_BIT(ch->in_room->room_flags, ROOM_BURNING); break; case MAG_HOLY: if (!(pexit=find_door(ch, argument, FALSE)) || !IS_SET(pexit->exit_info, EX_CLOSED) || !IS_SET(pexit->exit_info, EX_LOCKED) || IS_SET(pexit->exit_info, EX_PICKPROOF)) { ch_trick(ch, type); return; } REMOVE_BIT(pexit->exit_info, EX_LOCKED); send_to_char( "*Click*\n\r", ch ); if ( pexit->rexit && pexit->rexit->to_room == ch->in_room ) REMOVE_BIT( pexit->rexit->exit_info, EX_LOCKED ); check_room_for_traps( ch, TRAP_UNLOCK | trap_door[pexit->vdir] ); break; } } void void_create(CHAR_DATA *ch, int power, char *argument) { MATERIAL_DATA *material_lookup( int number ); char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH]; OBJ_INDEX_DATA *pObjIndex; AREA_DATA *area; int lo_vnum=2; int hi_vnum=2; MATERIAL_DATA *material; int hash; char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; AFFECT_DATA *paf; extern int top_affect; if (ch->curr_talent[TAL_VOID] < 100) { huh(ch); return; } if (argument == NULL) { ch_trick(ch, MAG_ETHER); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); material=material_lookup(116); /* Ether material */ if (!(material)) { send_to_char("You can't seem to reach the Ether for some reason.\n\r", ch); bug("Cannot find Ether material for Void Create!", 0); return; } if (!stockobj) for (area=first_area; area; area=area->next) { if (!str_cmp( area->filename, "stockobj.are" )) { stockobj = area; lo_vnum=area->low_o_vnum; hi_vnum=area->hi_o_vnum; break; } else { lo_vnum=2; hi_vnum=2; } } else { area = stockobj; lo_vnum=area->low_o_vnum; hi_vnum=area->hi_o_vnum; } if (lo_vnum==hi_vnum) { send_to_char("You cannot figure out how to create anything right now.\n\r", ch); return; } for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) { for ( pObjIndex = obj_index_hash[hash]; pObjIndex; pObjIndex = pObjIndex->next) { if (pObjIndex == NULL) { bug("NULL pObjIndex on void_create!"); send_to_char("Your mind is a blank.\n\r", ch); return; } if ( nifty_is_name( arg1, pObjIndex->name ) && pObjIndex->vnum >= lo_vnum && pObjIndex->vnum <= hi_vnum) { if (pObjIndex->tech > ch->pcdata->noncombat[SK_SMITH] + ch->curr_talent[TAL_VOID] - 100) { ch_trick(ch, MAG_ETHER); return; } if (pObjIndex->weight * 10 > power && !IS_AFFECTED(ch, AFF_VOID)) { ch_trick(ch, MAG_ETHER); return; } obj = create_object( pObjIndex, 0 ); if (!obj) { ch_trick(ch, MAG_ETHER); return; } break; } } if (obj) break; } if (obj == NULL) { ch_trick(ch, MAG_ETHER); return; } strcpy(buf, material->name); sprintf(arg, obj->short_descr, buf); one_argument(arg, buf); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(arg); strcpy(buf, material->name); sprintf(arg, obj->description, buf); STRFREE(obj->description); obj->description = STRALLOC(capitalize(arg)); strcpy(buf, obj->name); strcat(buf, " "); strcat(buf, material->name); STRFREE(obj->name); obj->name=STRALLOC(buf); if (obj->item_type == ITEM_WEAPON || obj->item_type == ITEM_MISSILE_WEAPON) obj->value[2] = TALENT(ch, TAL_VOID); /* This is important so that Void mages cannot create * infinite free items and sell them. * Enchanting them will still add value, however, * but that requires actual work, so lets let them... -keo */ obj->cost = 0; for (paf = material->first_affect; paf; paf = paf->next) { AFFECT_DATA *naf; CREATE(naf, AFFECT_DATA, 1); naf->type = paf->type; naf->duration = paf->duration; naf->location = paf->location; naf->modifier = paf->modifier; naf->bitvector = paf->bitvector; top_affect++; LINK(naf, obj->first_affect, obj->last_affect, next, prev); } obj->size = ch->height; obj->material=material; obj->obj_by = STRALLOC(ch->name); obj = obj_to_char(obj, ch); act( AT_MAGIC, "You weave $p from ether.", ch, obj, NULL, TO_CHAR); act( AT_MAGIC, "$n weaves $p from ether.", ch, obj, NULL, TO_ROOM); } void dream_create(CHAR_DATA *ch, int power, char *arg1, char *arg2) { MATERIAL_DATA *material_lookup( int number ); OBJ_DATA *obj = NULL; extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH]; OBJ_INDEX_DATA *pObjIndex; AREA_DATA *area; int lo_vnum=2; int hi_vnum=2; MATERIAL_DATA *material; int hash; char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; AFFECT_DATA *paf; extern int top_affect; if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) { ch_trick(ch, MAG_DREAM); return; } if (arg1 == NULL || arg2 == NULL) { ch_trick(ch, MAG_DREAM); return; } material=first_material; while (material) { if (!str_prefix(material->name, arg2)) break; material=material->next; } if (!(material)) { ch_trick(ch, MAG_DREAM); return; } if (!stockobj) for (area=first_area; area; area=area->next) { if (!str_cmp( area->filename, "stockobj.are" )) { stockobj = area; lo_vnum=area->low_o_vnum; hi_vnum=area->hi_o_vnum; break; } else { lo_vnum=2; hi_vnum=2; } } else { area = stockobj; lo_vnum=area->low_o_vnum; hi_vnum=area->hi_o_vnum; } if (lo_vnum==hi_vnum) { ch_trick(ch, MAG_DREAM); return; } for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) { for ( pObjIndex = obj_index_hash[hash]; pObjIndex; pObjIndex = pObjIndex->next) { if (pObjIndex == NULL) { bug("NULL pObjIndex on spell_imagine!"); send_to_char("Your mind is a blank.\n\r", ch); return; } if ( nifty_is_name( arg1, pObjIndex->name ) && pObjIndex->vnum >= lo_vnum && pObjIndex->vnum <= hi_vnum) { obj = create_object( pObjIndex, 0 ); if (!obj) { ch_trick(ch, MAG_DREAM); return; } break; } } if (obj) break; } if (obj == NULL) { ch_trick(ch, MAG_DREAM); return; } strcpy(buf, material->name); sprintf(arg, obj->short_descr, buf); one_argument(arg, buf); if (strcmp(buf, "some")) strcpy(arg, aoran(arg)); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(arg); strcpy(buf, material->name); sprintf(arg, obj->description, buf); if (strcmp(buf, "some")) strcpy(arg, aoran(arg)); STRFREE(obj->description); obj->description = STRALLOC(capitalize(arg)); strcpy(buf, obj->name); strcat(buf, " "); strcat(buf, material->name); STRFREE(obj->name); obj->name=STRALLOC(buf); obj->cost += number_fuzzy(obj->cost); for (paf = material->first_affect; paf; paf = paf->next) { AFFECT_DATA *naf; CREATE(naf, AFFECT_DATA, 1); naf->type = paf->type; naf->duration = paf->duration; naf->location = paf->location; naf->modifier = paf->modifier; naf->bitvector = paf->bitvector; top_affect++; LINK(naf, obj->first_affect, obj->last_affect, next, prev); } obj->material=material; obj->size = ch->height; obj->obj_by = STRALLOC(ch->name); obj = obj_to_char(obj, ch); act( AT_MAGIC, "You imagine $p.", ch, obj, NULL, TO_CHAR); act( AT_MAGIC, "$n concentrates, and $p appears in $s hands.", ch, obj, NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_DREAMWORLD); } void obj_create(CHAR_DATA *ch, int type, int power, char *argument) { int create, x, y; OBJ_DATA *obj; MATERIAL_DATA *material; char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; material=material_lookup(116); /* Ether material */ if (!(material)) { send_to_char("You can't seem to reach the Ether for some reason.\n\r", ch); bug("Cannot find Ether material for Void Create!", 0); return; } switch (type) { default: ch_trick(ch, type); return; case MAG_FIRE: if (IS_UNDERWATER(ch) || ch->curr_talent[TAL_FIRE] < 10) { ch_trick(ch, MAG_WATER); return; } act(AT_FIRE, "You make a burst of mystic flame burn before you.", ch, NULL, NULL, TO_CHAR); act(AT_FIRE, "$n makes a burst of mystic flame burn before $m.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_FIRE; break; case MAG_WATER: if (IS_UNDERWATER(ch) || ch->curr_talent[TAL_WATER] < 10) { ch_trick(ch, type); return; } act(AT_BLUE, "A spring of clear water gushes forth in midair.", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "A spring of clear water gushes forth in midair.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_SPRING; break; case MAG_ACID: if (ch->curr_talent[TAL_WATER] < 20) { ch_trick(ch, type); return; } act(AT_BLUE, "You conjure a hot cup of tea.", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "$n conjures a hot cup of tea.", ch, NULL, NULL, TO_ROOM); create = 54; break; case MAG_BLUNT: if (ch->curr_talent[TAL_EARTH] < 10) { ch_trick(ch, type); return; } act(AT_HUNGRY, "You conjure a loaf of bread.", ch, NULL, NULL, TO_CHAR); act(AT_HUNGRY, "$n conjures a loaf of bread.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_MUSHROOM; break; case MAG_EARTH: if (ch->curr_talent[TAL_EARTH] < 10 ) { ch_trick(ch, type); return; } act(AT_RED, "You open your hand and a beautiful red rose grows and opens.", ch, NULL, NULL, TO_CHAR); act(AT_RED, "$n opens $s hand and a beautiful red rose grows and opens.", ch, NULL, NULL, TO_ROOM); create = 53; break; case MAG_DRAIN: if (ch->curr_talent[TAL_MOTION] < 10 ) { ch_trick(ch, type); return; } act(AT_PURPLE, "You conjure a mystic shovel.", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "$n conjures a mystic shovel.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_MYSTIC_SHOVEL; break; case MAG_ANTIMATTER: if (ch->curr_talent[TAL_VOID] < 30) { ch_trick(ch, type); return; } act(AT_MAGIC, "You weave a bag of holding from the Void.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n weaves a bag of holding from the Void.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_BAG_OF_HOLDING; break; case MAG_LIGHT: if (ch->curr_talent[TAL_ILLUSION] < 10) { ch_trick(ch, type); return; } act(AT_YELLOW, "You conjure a globe of light.", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n conjures a globe of light.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_LIGHT_BALL; break; case MAG_POISON: case MAG_CHANGE: if (ch->curr_talent[TAL_DEATH] < 10) { ch_trick(ch, type); return; } act(AT_CHAOS, "You conjure a piece of chaos cheese.", ch, NULL, NULL, TO_CHAR); act(AT_CHAOS, "$n conjures a piece of chaos cheese.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_CHAOS_CHEESE; break; case MAG_SOUND: if (ch->curr_talent[TAL_SPEECH] < 10) { ch_trick(ch, type); return; } act(AT_MAGIC, "You conjure a magic marker.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n conjures a magic marker.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_MAGIC_MARKER; break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 10) { ch_trick(ch, type); return; } act(AT_DGREY, "You conjure a globe of darkness.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "$n conjures a globe of darkness.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_BALL_DARK; break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] < 20) { ch_trick(ch, type); return; } act(AT_BLUE, "You conjure a bottle of wine.", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "$n conjures a bottle of wine.", ch, NULL, NULL, TO_ROOM); create = OBJ_VNUM_WINE; break; case MAG_SEEK: if (ch->curr_talent[TAL_SEEKING] < 100) { ch_trick(ch, type); return; } act(AT_BLUE, "You conjure a reflecting pool.", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "$n conjures a reflecting pool.", ch, NULL, NULL, TO_ROOM); create = 9006; break; case MAG_SLASH: if (ch->curr_talent[TAL_CATALYSM] < 30) { ch_trick(ch, type); return; } act(AT_YELLOW, "You draw pure energy together to form a gleaming mageblade.", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n draws $s hands together and forges a mageblade of raw energy.", ch, NULL, NULL, TO_ROOM); create = 98; break; case MAG_TELEKINETIC: if (ch->curr_talent[TAL_MOTION] < 40) { ch_trick(ch, type); return; } if (IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS)) { ch_trick(ch, type); return; } victim = generate_mob_nation(argument); if (!victim) { send_to_char("You cannot find anything like that.\n\r",ch); return; } act(AT_MAGIC, "You open a swirling rift and pull $N through.", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "$n opens a swirling rift and pulls $N through.", ch, NULL, victim, TO_ROOM); char_to_room( victim, ch->in_room ); do_look( victim, "auto" ); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (!get_obj_index(create)) { bug("obj_create: vnum %d not found!", create); send_to_char("At the last minute, you lose your train of thought!\n\r", ch); return; } obj = create_object(get_obj_index(create), 0); if (!IS_OBJ_STAT(obj, ITEM_NO_TAKE)) { obj = obj_to_char(obj, ch); } else { obj = obj_to_room(obj, ch->in_room); } obj->cost = 0; obj->obj_by = STRALLOC(ch->name); obj->timer = power / 10; obj->material = material; /* Random mageblade appearances */ if (type == MAG_ALL) { x = number_range(1,11); y = number_range(1,12); sprintf(buf, "%s %s %s", x == 1 ? "gleaming" : x == 2 ? "shining" : x == 3 ? "blazing" : x == 4 ? "crackling" : x == 5 ? "sparkling" : x == 6 ? "fiery" : x == 7 ? "glimmering" : x == 8 ? "glistening" : x == 9 ? "glinting" : x == 10 ? "mystic" : "shimmering", y == 1 ? "&Rred" : y == 2 ? "&Wwhite" : y == 3 ? "&wsilver" : y == 4 ? "&Bblue" : y == 5 ? "&Ggreen" : y == 6 ? "&Pviolet" : y == 7 ? "&ppurple" : y == 8 ? "&Ppink" : y == 9 ? "&Ccyan" : y == 10 ? "&Rmu&Ylti-&Gco&Clo&Pred" : "&Ygolden", obj->short_descr); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(buf); STRFREE(obj->name); obj->name = STRALLOC(buf); } WAIT_STATE(ch, PULSE_VIOLENCE); } void obj_find(CHAR_DATA *ch, OBJ_DATA *obj, int type) { AFFECT_DATA *paf; SKILLTYPE *sktmp; MATERIAL_DATA *mat; int gp; switch (type) { default: obj_trick(ch, obj, type); break; case MAG_ALL: case MAG_ENERGY: if (ch->curr_talent[TAL_SEEKING] < 15) { obj_trick(ch, obj, type); return; } if (obj->first_affect || obj->pIndexData->first_affect) ch_printf(ch, "The %s has the following affects:\n\r", myobj(obj)); else ch_printf(ch, "The %s has no inherent affects.\n\r", myobj(obj)); for ( paf = obj->pIndexData->first_affect; paf; paf = paf->next ) showaffect( ch, paf ); for ( paf = obj->first_affect; paf; paf = paf->next ) showaffect( ch, paf ); if (obj->gem) { ch_printf(ch, "%s has been affixed to this item.\n\r", aoran(myobj(obj->gem))); for ( paf = obj->gem->first_affect; paf; paf = paf->next ) showaffect( ch, paf ); } break; case MAG_SEEK: ch_printf(ch, "\n\rThe %s is %s", myobj(obj), aoran(item_type_name(obj))); if (!xIS_EMPTY(obj->parts) ) ch_printf(ch, ", worn on: %s\n\r", ext_flag_string(&obj->parts, bp_flags)); else send_to_char( ".\n\r", ch ); if (ch->curr_talent[TAL_SEEKING] >= 10) ch_printf( ch, "Special properties: %s\n\rIts weight is %d.\r\n", extra_bit_name(&obj->extra_flags), obj->weight); if (obj->cost > 0) { gp = obj->cost; ch_printf( ch, "&wIt is worth &C%d mithril, ", (int)gp/1000000); gp = gp % 1000000; ch_printf( ch, "&Y%d gold, ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%d silver, ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "&Oand %d copper coins&C.\n\r", gp); } if (ch->curr_talent[TAL_SEEKING] >= 5) ch_printf(ch, "It appears to have been made for someone %d inches tall.\n\r", obj->size ); if (ch->curr_talent[TAL_SEEKING] >= 10 && obj->material) ch_printf(ch, "It appears to be made of %s.\r\n", obj->material->name); if (ch->curr_talent[TAL_SEEKING] >= 25) { if (obj->timer == 0) ch_printf(ch, "It will not decay.\n\r"); else ch_printf(ch, "It will last another %d hours.\n\r", obj->timer); } if (obj->obj_by && ch->curr_talent[TAL_SEEKING] >= 50) ch_printf( ch, "It was created by %s.\n\r", obj->obj_by); if (obj->raw_mana && ch->curr_talent[TAL_SEEKING] >= 5) ch_printf(ch, "This item %s with raw mana.\n\r", obj->raw_mana > 2000 ? "vibrates violently" : obj->raw_mana > 1500 ? "radiates brightly" : obj->raw_mana > 1000 ? "shines" : obj->raw_mana > 500 ? "vibrates" : "tingles"); if (obj->mana && ch->curr_talent[TAL_SEEKING] >= 40) ch_printf(ch, "%d points of energy have been absorbed into this item.\n\r", obj->mana); switch (obj->item_type) { case ITEM_CONTAINER: ch_printf( ch, "%s appears to be %s.\n\r", capitalize(obj->short_descr), obj->value[0] < 76 ? "of a small capacity" : obj->value[0] < 150 ? "of a small to medium capacity" : obj->value[0] < 300 ? "of a medium capacity" : obj->value[0] < 550 ? "of a medium to large capacity" : obj->value[0] < 751 ? "of a large capacity" : "of a giant capacity" ); break; case ITEM_PILL: case ITEM_SCROLL: case ITEM_POTION: if (ch->curr_talent[TAL_SEEKING] >= 20) { ch_printf( ch, "Casts:" ); if (obj->value[1] >= 0 && (sktmp=get_skilltype(obj->value[1])) != NULL) { send_to_char( " '", ch ); send_to_char( sktmp->name, ch ); send_to_char( "'", ch ); } if (obj->value[2] >= 0 && (sktmp=get_skilltype(obj->value[2])) != NULL) { send_to_char( " '", ch ); send_to_char( sktmp->name, ch ); send_to_char( "'", ch ); } if (obj->value[3] >= 0 && (sktmp=get_skilltype(obj->value[3])) != NULL) { send_to_char( " '", ch ); send_to_char( sktmp->name, ch ); send_to_char( "'", ch ); } send_to_char( ".\n\r", ch ); } break; case ITEM_SALVE: ch_printf( ch, "Has %d out of %d applications left", obj->value[1], obj->value[2]); if (ch->curr_talent[TAL_SEEKING] >= 20) { ch_printf(ch, " of "); if (obj->value[4] >= 0 && (sktmp=get_skilltype(obj->value[4])) != NULL) { send_to_char( " '", ch ); send_to_char( sktmp->name, ch ); send_to_char( "'", ch ); } if (obj->value[5] >= 0 && (sktmp=get_skilltype(obj->value[5])) != NULL) { send_to_char( " '", ch ); send_to_char( sktmp->name, ch ); send_to_char( "'", ch ); } } send_to_char( ".\n\r", ch ); break; case ITEM_WEAPON: if (obj->value[4] && obj->value[4] < 14) ch_printf(ch, "This is a magically %s&z&Bweapon.\n\r", weapon_brand[obj->value[4]] ); ch_printf(ch, "This weapon falls into the '%s' category.\n\r", weapon_skill[obj->value[5]]); if (ch->curr_talent[TAL_SEEKING] >= 40 && obj->value[0]) { if (ch->curr_talent[TAL_SEEKING] >= 70) { if (obj->value[0] <= 17) ch_printf( ch, "This weapon will inflict %d extra damage against all %s.\n\r", obj->value[6] / 10, weapon_bane[obj->value[0]]); } else { ch_printf( ch, "This weapon is the bane of all %s.\n\r", weapon_bane[obj->value[0]]); } } ch_printf(ch, "Damage bonus is %d.\n\r", (obj->value[2]) / 2); break; case ITEM_ARMOR: ch_printf( ch, "Armor class is %d.\n\r", obj->value[0] ); break; case ITEM_MISSILE_WEAPON: if (obj->value[4] && obj->value[4] < 13) ch_printf( ch, "This is a magically %s&z&Bweapon.\n\r", weapon_brand[obj->value[4]] ); ch_printf(ch, "This weapon falls into the '%s' category.\n\r", weapon_skill[obj->value[5]]); ch_printf(ch, "Damage bonus is %d.\n\r", obj->value[2]); if (obj->value[5] != SK_WAND) { if (obj->value[0] == 0) { ch_printf(ch, "It is empty.\n\r"); } else { ch_printf(ch, "%d shots have been loaded into this weapon.\n\r", obj->value[0]); } break; case ITEM_SCANNER: case ITEM_RADIO: ch_printf( ch, "The volume is set at %d.\n\r", obj->value[0]); ch_printf( ch, "The frequency is set at %d.\n\r", obj->value[1]); break; } } break; case MAG_EARTH: case MAG_BLUNT: if (!obj->material) { obj_trick(ch, obj, type); return; } mat = obj->material; ch_printf(ch, "The %s is made of %s.\n\r", myobj(obj), mat->name); ch_printf(ch, "%s has a cost of %d.\n\r", capitalize(mat->name), mat->cost); if (!xIS_EMPTY(obj->extra_flags) && ch->curr_talent[TAL_EARTH] >= 20) ch_printf(ch, "It has the properties of %s.\n\r", extra_bit_name(&mat->extra_flags)); if (ch->curr_talent[TAL_CATALYSM] >= 40) ch_printf( ch, "%s is a%s magical ore.\n\r", capitalize(mat->name), mat->magic <= 10 ? "n incredibly" : mat->magic <= 25 ? "n extremely" : mat->magic <= 50 ? " highly" : mat->magic <= 70 ? " very" : mat->magic <= 80 ? " rather" : mat->magic <= 90 ? " fairly" : mat->magic <= 100 ? " somewhat" : mat->magic <= 120 ? " poorly" : " non" ); if (ch->curr_talent[TAL_SEEKING] >= 15) for (paf = mat->first_affect; paf; paf = paf->next) showaffect(ch, paf); break; case MAG_WATER: if (obj->item_type != ITEM_DRINK_CON && obj->item_type != ITEM_FOUNTAIN) { obj_trick(ch, obj, type); return; } if (obj->value[2] >= LIQ_MAX) { bug( "Do_drink: bad liquid number %d.", obj->value[2] ); obj->value[2] = 0; } if (obj->value[1] <= 0) { ch_printf(ch, "The %s is empty.\n\r", myobj(obj)); break; } if (ch->curr_talent[TAL_WATER] >= 10) ch_printf(ch, "The %s is %s full of %s.\n\r", myobj(obj), obj->value[1] < obj->value[0] / 4 ? "less than" : obj->value[1] < 3 * obj->value[0] / 4 ? "about" : "more than", liq_table[obj->value[2]].liq_name); else ch_printf(ch, "The %s is %s full of a %s liquid.\n\r", myobj(obj), obj->value[1] < obj->value[0] / 4 ? "less than" : obj->value[1] < 3 * obj->value[0] / 4 ? "about" : "more than", liq_table[obj->value[2]].liq_color); if (ch->curr_talent[TAL_WATER] >= 40) ch_printf(ch, "It will make you %s, %s, %s.\n\r", liq_table[obj->value[2]].liq_affect[COND_THIRST] > 0 ? "less thirsty" : liq_table[obj->value[2]].liq_affect[COND_THIRST] < 0 ? "more thirsty" : "no less thirsty", liq_table[obj->value[2]].liq_affect[COND_FULL] > 0 ? "less hungry" : liq_table[obj->value[2]].liq_affect[COND_FULL] < 0 ? "more hungry" : "no less hungry", liq_table[obj->value[2]].liq_affect[COND_DRUNK] > 0 ? "and drunk" : "but not drunk"); if (obj->value[3] && ch->curr_talent[TAL_WATER] > 20) ch_printf(ch, "The %s is poisoned.\n\r", myobj(obj)); break; case MAG_POISON: if ( obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD || obj->item_type == ITEM_COOK) { if ( obj->item_type == ITEM_COOK && obj->value[2] == 0 ) send_to_char( "It looks undercooked.\n\r", ch ); else if ( obj->value[3] != 0 ) send_to_char( "You smell poisonous fumes.\n\r", ch ); else send_to_char( "It looks very delicious.\n\r", ch ); } else { send_to_char( "It doesn't look poisoned.\n\r", ch ); } break; } } void ch_find(CHAR_DATA *victim, CHAR_DATA *ch, int type) { char *name; DEITY_DATA *talent; AFFECT_DATA *paf; SKILLTYPE *sktmp; switch (type) { default: ch_trick(victim, type); break; case MAG_ALL: if ( IS_NPC(victim) ) name = capitalize(victim->short_descr); else name = victim->name; ch_printf(ch,"%s looks like %s.\n\r", name, victim->nation ? aoran(victim->nation->name) : get_race(victim)); if (ch->curr_talent[TAL_SEEKING] >= 30) { if (TALENT(ch, TAL_SEEKING) > TALENT(victim, TAL_SECURITY) ) { ch_printf(ch, "%s's current stats: %-2d str, %-2d wil, %-2d int, %-2d dex, %2d con, %-2d per, %-2d end.\r\n", victim->name, get_curr_str(victim), get_curr_wil(victim), get_curr_int(victim), get_curr_dex(victim), get_curr_con(victim), get_curr_per(victim), get_curr_lck(victim) ); } } if (ch->curr_talent[TAL_SEEKING] >= 40) { if ( (chance(ch, 50) && get_curr_wil(ch) >= get_curr_wil(victim) + 10 )) { ch_printf(ch, "%s appears to be affected by: ", name); if (!victim->first_affect) { send_to_char( "nothing.\n\r", ch ); } else { for ( paf = victim->first_affect; paf; paf = paf->next ) { if (victim->first_affect != victim->last_affect) { if( paf != victim->last_affect && (sktmp=get_skilltype(paf->type)) != NULL) ch_printf( ch, "%s, ", sktmp->name ); if( paf == victim->last_affect && (sktmp=get_skilltype(paf->type)) != NULL) { ch_printf( ch, "and %s.\n\r", sktmp->name ); } } else { if ( (sktmp=get_skilltype(paf->type)) != NULL ) ch_printf( ch, "%s.\n\r", sktmp->name ); else send_to_char( "\n\r", ch ); } } } } } if (IS_NPC(victim)) return; ch_printf(ch, "%s's aura:\n\r", PERS(victim, ch)); if (IS_SET(victim->pcdata->flags, PCFLAG_MASK) && TALENT(ch, TAL_SEEKING) > TALENT(victim, TAL_SEEKING)) { send_to_char("You sense only a distorted fog.\n\r", ch); return; } for (talent = first_deity; talent; talent = talent->next) { if (victim->pcdata->inborn == talent->index) { if (victim->talent[talent->index] >= 150) ch_printf(ch, "predominately radiant %s\n\r", talent->color); else if (victim->talent[talent->index] >= 100) ch_printf(ch, "primarily brilliant %s\n\r", talent->color); else if (victim->talent[talent->index] >= 50) ch_printf(ch, "mainly bright %s\n\r", talent->color); else ch_printf(ch, "mostly pale %s\n\r", talent->color); } else if (victim->talent[talent->index] >= 200) ch_printf(ch, "blindingly brilliant %s\n\r", talent->color); else if (victim->talent[talent->index] >= 160 && ch->curr_talent[TAL_SEEKING] >= 10) ch_printf(ch, "awash with a cascade of %s\n\r", talent->color); else if (victim->talent[talent->index] >= 130 && ch->curr_talent[TAL_SEEKING] >= 20) ch_printf(ch, "raging torrents of brilliant %s\n\r", talent->color); else if (victim->talent[talent->index] >= 100 && ch->curr_talent[TAL_SEEKING] >= 30) ch_printf(ch, "radiating %s brightly\n\r", talent->color); else if (victim->talent[talent->index] >= 85 && ch->curr_talent[TAL_SEEKING] >= 40) ch_printf(ch, "shimmering rays of %s\n\r", talent->color); else if (victim->talent[talent->index] >= 70 && ch->curr_talent[TAL_SEEKING] >= 50) ch_printf(ch, "bright streaks of %s\n\r", talent->color); else if (victim->talent[talent->index] >= 50 && ch->curr_talent[TAL_SEEKING] >= 80) ch_printf(ch, "shining %s sparkles\n\r", talent->color); else if (victim->talent[talent->index] >= 30 && ch->curr_talent[TAL_SEEKING] >= 120) ch_printf(ch, "traces of glittering %s\n\r", talent->color); else if (victim->talent[talent->index] >= 10 && ch->curr_talent[TAL_SEEKING] >= 150) ch_printf(ch, "pale flecks of %s\n\r", talent->color); else if (victim->talent[talent->index] >= 1 && ch->curr_talent[TAL_SEEKING] >= 200) ch_printf(ch, "faint tinge of %s barely visible\n\r", talent->color); } break; } } /* ch_find */ void seek_find(CHAR_DATA *ch, int type, char *argument) { OBJ_DATA *obj; OBJ_DATA *in_obj; CHAR_DATA *victim; DESCRIPTOR_DATA *d; char *str; char buf[MAX_STRING_LENGTH]; char name[MAX_INPUT_LENGTH]; int found, temp; struct stat fst; switch (type) { default: ch_trick(ch, type); break; case MAG_TELEKINETIC: if (ch->curr_talent[TAL_SEEKING] < 20) { ch_trick(ch, type); break; } found = FALSE; if (TALENT(ch, TAL_SEEKING) < 50) for (victim = first_char; victim; victim = victim->next) { if (victim->in_room && can_see(ch, victim) && nifty_is_name( argument, victim->name)) { found++; pager_printf( ch, "%s is in %s\n\r", PERS(victim, ch), victim->in_room->name ); } } else for (victim = first_char; victim; victim = victim->next) { if (victim->in_room && can_see(ch, victim) && nifty_is_name( argument, victim->name)) { found++; pager_printf( ch, "%s is in %s, in %s\n\r", PERS(victim, ch), victim->in_room->name, victim->in_room->area->name ); } } for (obj = first_object; obj; obj = obj->next) { if (!can_see_obj(ch, obj) || !nifty_is_name(argument, obj->name)) continue; if (IS_OBJ_STAT(obj, ITEM_PROTOTYPE) || IS_OBJ_STAT(obj, ITEM_NOLOCATE) || IS_OBJ_STAT(obj, ITEM_ARTIFACT) || IS_OBJ_STAT(obj, ITEM_GEM) || number_percent() > TALENT(ch, TAL_SEEKING)) continue; found++; for (temp = 0, in_obj = obj; in_obj->in_obj && temp < 100; in_obj = in_obj->in_obj, ++temp); if (temp >= MAX_NEST) { sprintf(buf, "seek_object: object [%d] %s is nested more than %d times!", obj->pIndexData->vnum, obj->short_descr, MAX_NEST); bug(buf, 0); continue; } if ( in_obj->carried_by ) { if (TALENT(ch, TAL_SEEKING) < 30) sprintf( buf, "%s is carried by %s.\n\r", obj_short(obj), PERS(in_obj->carried_by, ch) ); else if (TALENT(ch, TAL_SEEKING) < 60) sprintf( buf, "%s is carried by %s, in %s.\n\r", obj_short(obj), PERS(in_obj->carried_by, ch), in_obj->carried_by->in_room->name); else sprintf( buf, "%s is carried by %s, in %s in %s.\n\r", obj_short(obj), PERS(in_obj->carried_by, ch), in_obj->carried_by->in_room->name, in_obj->carried_by->in_room->area->name); } else { if (in_obj->in_room == NULL) sprintf( buf, "%s is somewhere\n\r", obj_short(obj)); else if (TALENT(ch, TAL_SEEKING) < 50) sprintf( buf, "%s is in %s.\n\r", obj_short(obj), in_obj->in_room->name ); else sprintf( buf, "%s is in %s, in %s.\n\r", obj_short(obj), in_obj->in_room->name, in_obj->in_room->area->name ); } buf[0] = UPPER(buf[0]); send_to_char(buf, ch); } if (!found) { send_to_char("You were unable to locate anything like that.\n\r", ch); } break; case MAG_EARTH: case MAG_BLUNT: if (ch->curr_talent[TAL_SEEKING] + ch->curr_talent[TAL_EARTH] < 20) { ch_trick(ch, type); return; } ch_printf(ch, "You are in %s in %s, on the world of %s.\n\r", ch->in_room->name, ch->in_room->area->name, ch->in_room->area->resetmsg); switch( ch->in_room->sector_type ) { default: str = "somewhere strange"; break; case SECT_INSIDE: str = "inside"; break; case SECT_CITY: str = "a city street"; break; case SECT_FIELD: str = "a field"; break; case SECT_FOREST: str = "a forest"; break; case SECT_HILLS: str = "in the hills"; break; case SECT_MOUNTAIN: str = "in the mountains"; break; case SECT_WATER_SWIM: str = "swallow water"; break; case SECT_WATER_NOSWIM: str = "deep water"; break; case SECT_UNDERWATER: str = "underwater"; break; case SECT_AIR: str = "in the air"; break; case SECT_DESERT: str = "in the desert"; break; case SECT_OCEANFLOOR: str = "on the oceanfloor"; break; case SECT_UNDERGROUND: str = "underground"; break; case SECT_LAVA: str = "molten lava"; break; case SECT_SWAMP: str = "in the swamps"; break; case SECT_BEACH: str = "on a beach"; break; case SECT_ICE: str = "on ice"; break; } ch_printf(ch, "It appears to be %s.\n\r", str); if (ch->in_room->room_flags) ch_printf(ch, "It seems to be %s.\n\r", flag_string(ch->in_room->room_flags, r_flags) ); temp = ch->in_room->curr_water; ch_printf(ch, "%s, and ", temp >= 100 ? "The room is completely underwater" : temp > 50 ? "The water is deep" : temp > 0 ? "The water is muddy and shallow" : "The room is dry"); temp = ch->in_room->curr_vegetation; ch_printf(ch, "%s vegetation grows.\n\r", temp >= 66 ? "thick" : temp > 33 ? "some" : "no"); temp = ch->in_room->curr_resources; ch_printf(ch, "There is a %s concentration of resources here.\n\r", temp >= 66 ? "high" : temp > 33 ? "moderate" : "low"); if (ch->in_room->runes) ch_printf( ch, "Runes of %s line the walls.\n\r", ch->curr_talent[TAL_CATALYSM] < 20 ? "some sort" : flag_string(ch->in_room->runes, rune_flags) ); break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_SEEKING] < 200) { ch_trick(ch, type); break; } if ((victim = get_char_world( ch, argument)) == NULL) { ch_trick(ch, type); break; } if (!victim->desc) { ch_trick(ch, type); break; } if (victim == ch) { for ( d = first_descriptor; d; d = d->next ) if ( d->snoop_by == ch->desc ) d->snoop_by = NULL; send_to_char("You break your mental connections watching over people.\n\r", ch); return; } if (victim->desc->snoop_by) { for ( d = first_descriptor; d; d = d->next ) if ( d->snoop_by == ch->desc ) d->snoop_by = NULL; send_to_char("Your mental links become tangled and sever themselves.\n\r", ch); return; } for (d = ch->desc->snoop_by; d; d = d->snoop_by) if (d->character == victim || d->original == victim) { send_to_char("Your target's mind gets in the way.\n\r", ch); return; } if (IS_SET(ch->pcdata->flags, PCFLAG_SHIELD) || (IS_SET(victim->pcdata->flags, PCFLAG_SHIELD) && TALENT(ch, TAL_MIND) < TALENT(victim, TAL_MIND))) { send_to_char("A shield blocks you from connecting.\n\r", ch); return; } if (victim->curr_talent[TAL_SEEKING] + victim->curr_talent[TAL_MIND] >= 110) send_to_char("You feel like someone is watching your every move...\n\r", victim); victim->desc->snoop_by = ch->desc; send_to_char("You establish a connection to watch over them.\n\r", ch); break; case MAG_TIME: send_to_char("You direct your thoughts backward along the paths of Time...\n\r", ch); strcpy(name, capitalize(argument)); sprintf(buf, "%s%c/%s", PLAYER_DIR, tolower(argument[0]), name); if ( stat( buf, &fst ) != -1 ) sprintf(buf, "%s last entered the Planes on %s\r", name, ctime(&fst.st_mtime)); else sprintf(buf, "You could not find %s's thread within the Planes.\n\r", name); send_to_char(buf, ch); break; } } /* seek_find */ void ch_focus(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) { switch (type) { default: ch_trick(victim, type); break; case MAG_ANTIMAGIC: if (!victim->shield) { ch_trick(victim, type); return; } if (victim == ch) { act(AT_MAGIC, "You lower your magical shield.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n lowers $s magical shield.",ch, NULL, NULL, TO_ROOM); } else { if (ch->curr_talent[TAL_VOID] < 50) { ch_trick(victim, type); return; } act(AT_MAGIC, "You disrupt $N's magical shield!", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "$n disrupts $N's magical shield!", ch, NULL, victim, TO_ROOM); act(AT_MAGIC, "$n disrupts your magical shield!", ch, NULL, victim, TO_VICT); } victim->shield = MAG_NONE; return; case MAG_ACID: if (ch->curr_talent[TAL_WATER] < 30 || ch->curr_talent[TAL_EARTH] < 10) { ch_trick(victim, type); return; } act(AT_GREEN, "A glistening bubble of acid encompasses you.", ch, NULL, NULL, TO_CHAR); act(AT_GREEN, "A glistening bubble of acid encompasses $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_DREAM: if (ch->curr_talent[TAL_DREAM] < 40) { ch_trick(victim, type); return; } act(AT_PINK, "Wispy dreams and whispered thoughts surround you.", ch, NULL, NULL, TO_CHAR); act(AT_PINK, "Wispy dreams and whispered thoughts surround $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_ENERGY: if (ch->curr_talent[TAL_CATALYSM] < 40) { ch_trick(victim, type); return; } act(AT_PURPLE, "A rippling shield of energy surrounds you.", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "A rippling shield of energy surrounds $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 40) { ch_trick(victim, type); return; } act(AT_FIRE, "Mystical flames rise to enshroud you.", ch, NULL, NULL, TO_CHAR); act(AT_FIRE, "Mystical flames rise to enshroud $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_COLD: if (ch->curr_talent[TAL_FROST] < 40) { ch_trick(victim, type); return; } act(AT_FROST, "A glistening hail of ice encompasses you.", ch, NULL, NULL, TO_CHAR); act(AT_FROST, "A glistening hail of ice encompasses $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_LIGHT: if (ch->curr_talent[TAL_ILLUSION] < 40) { ch_trick(victim, type); return; } act(AT_WHITE, "Searing light radiates from you.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "Searing light radiates from $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_ALL: if (victim == ch) { if (ch->curr_talent[TAL_CATALYSM] < 60) { ch_trick(victim, type); return; } act(AT_PURPLE, "A field of prismatic mana surrounds you.", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "A field of prismatic mana surrounds $n.", ch, NULL, NULL, TO_ROOM); } else { if (ch->curr_talent[TAL_CATALYSM] < 30) { ch_trick(victim, type); return; } WAIT_STATE(ch, PULSE_VIOLENCE); if (victim->shield == MAG_ALL || IS_SET(ch->pcdata->flags, PCFLAG_CHEAT)) { act(AT_PURPLE, "Your mana bounces off $N's shield!", ch, NULL, victim, TO_CHAR); act(AT_PURPLE, "$n's mana bounces off your shield!", ch, NULL, victim, TO_VICT); act(AT_PURPLE, "$n's mana bounces off $N's shield!", ch, NULL, victim, TO_NOTVICT); ch->mana = ch->max_mana + power; return; } act(AT_PURPLE, "You funnel your magic into $N's body!", ch, NULL, victim, TO_CHAR); act(AT_PURPLE, "$n glows brightly, funneling $s magic into you!", ch, NULL, victim, TO_VICT); act(AT_PURPLE, "$n glows brightly, funneling $s magic into $N!", ch, NULL, victim, TO_NOTVICT); ch->mana -= power; victim->mana += power; } break; case MAG_POISON: if (ch->curr_talent[TAL_DEATH] < 40) { ch_trick(victim, type); return; } act(AT_DGREEN, "Deadly venom oozes from your skin.", ch, NULL, NULL, TO_CHAR); act(AT_DGREEN, "Deadly venom oozes from $n's skin.", ch, NULL, NULL, TO_ROOM); break; case MAG_ELECTRICITY: if (ch->curr_talent[TAL_LIGHTNING] < 40) { ch_trick(victim, type); return; } act(AT_YELLOW, "Torrents of cascading energy form around you.", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "Torrents of cascading energy form around $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_SOUND: if (ch->curr_talent[TAL_LIGHTNING] < 40) { ch_trick(victim, type); return; } act(AT_PINK, "A discordant wail of deafening sound surrounds you.", ch, NULL, NULL, TO_CHAR); act(AT_PINK, "A discordant wail of deafening sound surrounds $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_BLUNT: if (ch->curr_talent[TAL_EARTH] < 40) { ch_trick(victim, type); return; } act(AT_DGREY, "A hail of stones rotates around you.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "A hail of stones rotates around $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] < 40) { ch_trick(victim, type); return; } act(AT_PURPLE, "You concentrate, forming a mental barrier.", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "$n concentrates, forming a mental barrier.", ch, NULL, NULL, TO_ROOM); break; case MAG_EARTH: if (ch->curr_talent[TAL_EARTH] < 40) { ch_trick(victim, type); return; } act(AT_GREEN, "An array of thorny vines surrounds you.", ch, NULL, NULL, TO_CHAR); act(AT_GREEN, "An array of thorny vines surrounds $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_CHANGE: if (ch->curr_talent[TAL_CHANGE] < 40) { ch_trick(victim, type); return; } act(AT_DBLUE, "The air warps and distorts around you.", ch, NULL, NULL, TO_CHAR); act(AT_DBLUE, "The air warps and distorts around $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_WATER: if (ch->curr_talent[TAL_WATER] < 40) { ch_trick(victim, type); return; } act(AT_BLUE, "Foaming waves rise to encompass you.", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "Foaming waves rise to encompass $n.", ch, NULL, NULL, TO_ROOM); break; case MAG_WIND: if (ch->curr_talent[TAL_WIND] < 40) { ch_trick(victim, type); return; } act(AT_CYAN, "Swirling gusts of wind blow around you.", ch, NULL, NULL, TO_CHAR); act(AT_CYAN, "Swirling gusts of wind blow around $n.", ch, NULL, NULL, TO_ROOM); break; } ch->shield = type; } /* ch_focus */ void obj_focus(CHAR_DATA *ch, OBJ_DATA *obj, int type) { char buf[MAX_STRING_LENGTH]; if (obj->item_type != ITEM_WEAPON && obj->item_type != ITEM_MISSILE_WEAPON) { obj_trick(ch, obj, type); return; } if (obj->value[4] && type != MAG_HOLY && type != MAG_ANTIMAGIC) { obj_trick(ch, obj, type); return; } if (obj->mana < 500 && type != MAG_ANTIMAGIC) { obj_trick(ch, obj, type); return; } WAIT_STATE(ch, PULSE_VIOLENCE); switch (type) { default: obj_trick(ch, obj, type); return; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 50) { obj_trick(ch, obj, type); return; } act( AT_FIRE, "$p bursts into flame!", ch, obj, NULL, TO_CHAR ); act( AT_FIRE, "$n's $p bursts into flame!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_FLAMING; break; case MAG_COLD: if (ch->curr_talent[TAL_FROST] < 50) { obj_trick(ch, obj, type); return; } act( AT_FROST, "$p shimmers with cold!", ch, obj, NULL, TO_CHAR ); act( AT_FROST, "$n's $p shimmers with cold!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_FROZEN; break; case MAG_ELECTRICITY: if (ch->curr_talent[TAL_LIGHTNING] < 50) { obj_trick(ch, obj, type); return; } act( AT_YELLOW, "$p crackles with electricity!", ch, obj, NULL, TO_CHAR); act( AT_YELLOW, "$n's $p crackles with electricity!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_ELEC; break; case MAG_ACID: if (ch->curr_talent[TAL_WATER] < 50) { obj_trick(ch, obj, type); return; } act( AT_YELLOW, "$p hisses with acid!", ch, obj, NULL, TO_CHAR); act( AT_YELLOW, "$n's $p hisses with acid!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_ACID; break; case MAG_ANTIMATTER: if (ch->curr_talent[TAL_VOID] < 50) { obj_trick(ch, obj, type); return; } act( AT_DGREY, "Black lightning erupts from $p!", ch, obj, NULL, TO_CHAR); act( AT_DGREY, "Black lightning erupts from $n's $p!", ch, obj, NULL, TO_ROOM); xREMOVE_BIT(obj->extra_flags, ITEM_GLOW); xSET_BIT(obj->extra_flags, ITEM_DARK); obj->value[4] = BRAND_ANTI_MATTER; break; case MAG_SOUND: if (ch->curr_talent[TAL_SPEECH] < 50) { obj_trick(ch, obj, type); return; } act( AT_GREEN, "$p emits a sonic hum!", ch, obj, NULL, TO_CHAR ); act( AT_GREEN, "$n's $p emits a sonic hum!", ch, obj, NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_HUM); obj->value[4] = BRAND_SONIC; break; case MAG_CHANGE: if (ch->curr_talent[TAL_CHANGE] < 50) { obj_trick(ch, obj, type); return; } act( AT_DBLUE, "The air warps and twists into $p!", ch, obj, NULL, TO_CHAR ); act( AT_DBLUE, "The air warps and twists into $n's $p!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_DISTORT; break; case MAG_POISON: if (ch->curr_talent[TAL_DEATH] < 50) { obj_trick(ch, obj, type); return; } act( AT_GREEN, "$p drips with venom!", ch, obj, NULL, TO_CHAR ); act( AT_GREEN, "$n's $p drips with venom!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_POISON; break; case MAG_SLASH: if (ch->curr_talent[TAL_CATALYSM] < 50) { obj_trick(ch, obj, type); return; } if (obj->value[5] != SK_SWORD && obj->value[5] != SK_DAGGER && obj->value[5] != SK_AXE && obj->value[5] != SK_HALBERD && obj->value[5] != SK_SPEAR && obj->value[5] != SK_POLEARM && obj->value[5] != SK_CLAW) { obj_trick(ch, obj, type); return; } act( AT_WHITE, "$p glints razor-sharp!", ch, obj, NULL, TO_CHAR ); act( AT_WHITE, "$n's $p glints razor-sharp!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_VORPAL; break; case MAG_WIND: if (ch->curr_talent[TAL_WIND] < 50) { obj_trick(ch, obj, type); return; } act( AT_CYAN, "Stormy winds swirl about $p!", ch, obj, NULL, TO_CHAR ); act( AT_CYAN, "Stormy winds swirl about $n's $p!", ch, obj, NULL, TO_ROOM ); obj->value[4] = BRAND_STORM; break; case MAG_LIGHT: if (ch->curr_talent[TAL_ILLUSION] < 50) { obj_trick(ch, obj, type); return; } act( AT_YELLOW, "$p glows with a blinding radiance!", ch, obj, NULL, TO_CHAR); act( AT_YELLOW, "$n's $p glows with a blinding radiance!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_RADIANT; xREMOVE_BIT(obj->extra_flags, ITEM_DARK); xSET_BIT(obj->extra_flags, ITEM_GLOW); break; case MAG_BLUNT: if (ch->curr_talent[TAL_EARTH] < 50) { obj_trick(ch, obj, type); return; } if (obj->value[5] != SK_MACE && obj->value[5] != SK_STAFF && obj->value[5] != SK_WHIP) { obj_trick(ch, obj, type); return; } act( AT_DGREY, "$p becomes harder than rock!", ch, obj, NULL, TO_CHAR ); act( AT_DGREY, "$n's $p becomes harder than rock!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_CRUSH; break; case MAG_DRAIN: if (ch->curr_talent[TAL_DEATH] < 60) { obj_trick(ch, obj, type); return; } act( AT_DGREY, "$p thirsts for blood!", ch, obj, NULL, TO_CHAR); act( AT_DGREY, "$n's $p thirsts for blood!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_DRAIN; break; case MAG_PSIONIC: if (ch->curr_talent[TAL_MIND] < 50) { obj_trick(ch, obj, type); return; } act( AT_PURPLE, "A strange humming sound emanates from $p!", ch, obj, NULL, TO_CHAR); act( AT_PURPLE, "A strange humming sound emanates from $n's $p!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_PSIONIC; xSET_BIT(obj->extra_flags, ITEM_HUM); break; case MAG_HOLY: if (ch->curr_talent[TAL_SECURITY] < 50) { obj_trick(ch, obj, type); return; } if (IS_OBJ_STAT(obj, ITEM_LOYAL) || IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); return; } if (obj->mana < 500) { obj_trick(ch, obj, type); return; } obj->mana -= 500; obj->cost += 500000; xSET_BIT(obj->extra_flags, ITEM_LOYAL); act(AT_WHITE, "You bind $p with a wash of white light.", ch, obj, NULL, TO_CHAR); act(AT_WHITE, "White light washes over $n's $p.", ch, obj, NULL, TO_ROOM); return; case MAG_ANTIMAGIC: if (!IS_OBJ_STAT(obj, ITEM_MAGIC)) { obj_trick(ch, obj, type); return; } if (ch->curr_talent[TAL_VOID] < 30) { obj_trick(ch, obj, type); return; } act(AT_DGREY, "You strip $p of its magical properties.", ch, obj, NULL, TO_CHAR); act(AT_DGREY, "Antimagic violently rips at $n's $p.", ch, NULL, NULL, TO_ROOM); xREMOVE_BIT(obj->extra_flags, ITEM_MAGIC); xREMOVE_BIT(obj->extra_flags, ITEM_HUM); xREMOVE_BIT(obj->extra_flags, ITEM_DARK); xREMOVE_BIT(obj->extra_flags, ITEM_GLOW); obj->cost -= 50000; if (obj->value[4]) { obj->value[4] = 0; obj->cost -= 500000; } obj->value[0] = 0; obj->value[7] = 0; obj->mana = 0; obj->raw_mana = 0; return; } obj->mana -= 500; obj->cost += 500000; sprintf(buf, "%s%s", weapon_brand[obj->value[4]],myobj(obj)); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(buf); } /* obj_focus */ void obj_move(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power, char *argument) { CHAR_DATA *victim; CHAR_DATA *target; ROOM_INDEX_DATA *location; switch (type) { default: obj_trick(ch, obj, type); break; case MAG_TELEKINETIC: if ((target = get_char_world(ch, argument)) == NULL || !can_travel(90, ch, target) || (TALENT(target, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) { act( AT_MAGIC, "You are unable to locate $t.", ch, argument, NULL, TO_CHAR); return; } if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD) /* Thanks Smokey */ || IS_OBJ_STAT(obj, ITEM_ARTIFACT) /* Thanks Waffle */ || victim->carry_weight + get_obj_weight(obj) > can_carry_w(target)) { obj_trick(ch, obj, type); break; } separate_obj(obj); act( AT_MAGIC, "$p slowly dematerializes from your hands.", ch, obj, NULL, TO_CHAR); act( AT_MAGIC, "$p slowly dematerializes from $n's hands.", ch, obj, NULL, TO_ROOM); obj_from_char( obj ); if (!IS_AFFECTED(target, AFF_ETHEREAL)) { obj_to_char( obj, target ); act( AT_MAGIC, "$p slowly materializes in your hands, sent by $N.", target, obj, ch, TO_CHAR); act( AT_MAGIC, "$p slowly materializes in $n's hands.", target, obj, NULL, TO_ROOM); } else { obj_to_room( obj, target->in_room ); act( AT_MAGIC, "$p slowly materializes beside you and drops to the ground.", target, obj, ch, TO_CHAR); act( AT_MAGIC, "$p slowly materializes beside $n and drops to the ground.", target, obj, NULL, TO_ROOM); } save_char_obj(ch); save_char_obj(target); WAIT_STATE(ch, PULSE_VIOLENCE); break; case MAG_CHANGE: for ( ; ; ) { location = get_room_index( number_range( 0, 32000 ) ); if ( location ) if ( !IS_SET(location->room_flags, ROOM_PRIVATE) && !IS_SET(location->room_flags, ROOM_SOLITARY) && !IS_SET(location->room_flags, ROOM_NO_ASTRAL) && !IS_SET(location->room_flags, ROOM_PROTOTYPE) ) break; } act( AT_MAGIC, "You throw $p high into the air where it vanishes.", ch, obj, NULL, TO_CHAR); act( AT_MAGIC, "$n throws $p high into the air where it vanishes.", ch, obj, NULL, TO_ROOM); obj_from_char(obj); obj_to_room(obj, location); break; case MAG_WIND: if (obj->weight*10 > power || !obj->in_room) { act(AT_MAGIC, "$p shakes a little.", ch, obj, NULL, TO_ROOM); act(AT_MAGIC, "$p shakes a little.", ch, obj, NULL, TO_CHAR); return; } act(AT_MAGIC, "$p suddenly lifts off the ground and flies through the air toward $n.", ch, obj, NULL, TO_ROOM); act(AT_MAGIC, "You lift $p with your magic and bring it toward you.", ch, obj, NULL, TO_CHAR); if (ch->curr_talent[TAL_MOTION] < number_range(1,30)) { act(AT_MAGIC, "$p flies past $n and falls to the ground.", ch, obj, NULL, TO_ROOM); act(AT_MAGIC, "$p flies past you and falls to the ground.", ch, obj, NULL, TO_CHAR); return; } if (ch->curr_talent[TAL_MOTION] < number_range(1,50)) { act(AT_MAGIC, "$p smacks into $n, but $e catches it.", ch, obj, NULL, TO_ROOM); act(AT_MAGIC, "$p smacks into you, but you catch it.", ch, obj, NULL, TO_CHAR); lose_hp(ch, obj->weight); } separate_obj(obj); obj_from_room(obj); obj_to_char(obj, ch); if ( obj->item_type == ITEM_MONEY ) { int gp; gp = obj->value[0]; ch_printf( ch, "There were &C%d mithril, ", (int)gp/1000000 ); gp = gp % 1000000; ch_printf( ch, "&Y%d gold, ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%d silver, ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "and &O%d copper coins.\n\r", gp); ch->gold += obj->value[0]; extract_obj( obj ); } break; } } /* obj_move */ void ch_move(CHAR_DATA *victim, CHAR_DATA *ch, int type, char *arg1, char *arg2) { int slot, mem; ROOM_INDEX_DATA *location; CHAR_DATA *target; char buf[MAX_STRING_LENGTH]; location = NULL; switch (type) { default: ch_trick(victim, type); break; case MAG_TELEKINETIC: if ( (target = get_char_world(ch, arg2)) == NULL || !can_travel(90, ch, target) || (TALENT(target, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) { act( AT_MAGIC, "You are unable to locate $t.", ch, arg1, NULL, TO_CHAR); return; } if (target == ch || victim == target) { ch_trick(victim, type); break; } if (victim != ch && ch->curr_talent[TAL_MOTION] < 90) { ch_trick(victim, type); break; } if (!IS_NPC(victim)) { sprintf( buf, "%s sent %s to %s (%d).", ch->name, victim->name, target->in_room->name, target->in_room->vnum ); to_channel( buf, "Spell", PERMIT_SECURITY); } act( AT_MAGIC, "You send $N across the astral planes.", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "$n sends you across the astral planes.", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "$n sends $N across the astral planes.", ch, NULL, victim, TO_ROOM); char_from_room( victim ); victim->in_obj = NULL; char_to_room( victim, target->in_room ); if (victim->mount) { char_from_room(victim->mount); char_to_room(victim->mount, target->in_room); } act( AT_MAGIC, "A rift in the sky opens, and $n falls out.", victim, NULL, NULL, TO_ROOM); do_look( victim, "auto" ); break; case MAG_CHANGE: if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) && ch->curr_talent[TAL_MOTION] < 80) { send_to_char("For some reason, nothing happens.\n\r", ch); return; } for ( ;; ) { location = get_room_index( number_range( 0, 32000 ) ); if ( location ) if ( !IS_SET(location->room_flags, ROOM_PRIVATE) && !IS_SET(location->room_flags, ROOM_SOLITARY) && !IS_SET(location->room_flags, ROOM_NO_ASTRAL) && !IS_SET(location->area->flags, AFLAG_NOTELEPORT) && !IS_SET(location->room_flags, ROOM_PROTOTYPE) && !IS_SET(location->room_flags, ROOM_NO_RECALL) ) break; } act( AT_MAGIC, "Reality seems to twist for a moment, and your surroundings warp and change.", victim, NULL, NULL, TO_CHAR); act( AT_MAGIC, "Reality seems to twist for a moment, and $n vanishes.", victim, NULL, NULL, TO_ROOM); char_from_room( victim ); victim->in_obj = NULL; char_to_room( victim, location ); if (victim->mount) { char_from_room(victim->mount); char_to_room(victim->mount, location); } act( AT_MAGIC, "Reality ripples for a moment, and $n suddenly appears.", ch, NULL, NULL, TO_ROOM); do_look( victim, "auto" ); break; case MAG_PSIONIC: if (!arg2 || arg2[0] == '\0') slot = 0; else slot = atoi(arg2); if (!str_cmp(arg2, "nexus")) { if (IS_SET(ch->in_room->area->flags, AFLAG_FREEKILL)) location = get_room_index(ROOM_VNUM_PKILL); else location = get_room_index(ROOM_VNUM_NEXUS); } else if (!str_cmp(arg2, "area")) { location = get_room_index(ch->in_room->area->hi_soft_range); } else { mem = (ch->curr_talent[TAL_MOTION] -20) / 10; if (mem > 7) mem = 7; if (mem < 0 && ch->curr_talent[TAL_MOTION] > 0) mem = 0; if (slot > mem) { send_to_char("You cannot recall the details of that location.\n\r", ch); return; } if (IS_NPC(ch)) { if (IS_AFFECTED(ch, AFF_CHARM) && ch->master && !IS_NPC(ch->master)) { location = get_room_index( ch->master->pcdata->memorize[slot] ); } else { return; } } else { location = get_room_index( ch->pcdata->memorize[slot] ); } } if ( !location ) location = get_room_index( ROOM_VNUM_NEXUS ); if ( !location ) { send_to_char( "You are completely lost.\n\r", ch ); return; } if ( ch->in_room == location ) { send_to_char("You are already here!\n\r", ch); return; } if ( IS_AFFECTED(ch, AFF_DREAMWORLD) && IS_SET(location->room_flags, ROOM_NO_DREAM)) { send_to_char("A mysterious shield prevents you from recalling.\n\r", ch); return; } if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) && ch->curr_talent[TAL_MOTION] < 80) { send_to_char( "For some strange reason... nothing happens.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CURSE) && ch->curr_talent[TAL_MOTION] < 70) { send_to_char("You are cursed and cannot recall!\n\r", ch); return; } if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) { send_to_char("You cannot recall from combat!\r\n", ch); return; } act( AT_ACTION, "$n disappears in a swirl of mist.", ch, NULL, NULL, TO_ROOM); char_from_room(ch); ch->in_obj = NULL; char_to_room(ch, location); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, location); do_look(ch->mount, "auto"); } act( AT_ACTION, "$n appears in the room, a ring of mist dissipating around $m.", ch, NULL, NULL, TO_ROOM ); do_look(ch, "auto"); break; case MAG_DREAM: if (victim == ch) { if ( IS_AFFECTED (ch, AFF_DREAMWORLD ) ) { if ( !IS_AFFECTED(ch, AFF_SLEEP) ) { act( AT_MAGIC, "You step out of the world of dreams.", ch, NULL, NULL, TO_CHAR); act( AT_MAGIC, "$n slowly fades out of the dream.", ch, NULL, NULL, TO_ROOM); drop_dream_items(ch, ch->last_carrying); if (IS_NPC(ch)) xREMOVE_BIT(ch->affected_by, AFF_DREAMWORLD); else xREMOVE_BIT(ch->pcdata->perm_aff, AFF_DREAMWORLD); act( AT_MAGIC, "$n slowly fades into the waking world.", ch, NULL, NULL, TO_ROOM); return; } else { send_to_char("You can't seem to wake up!\n\r", ch); return; } } if (IS_AFFECTED(ch, AFF_VOID)) { send_to_char("The dream twists your mind!\n\r", ch); ch->mental_state = 100; return; } if (IS_SET(ch->in_room->room_flags, ROOM_NO_DREAM) && (ch->curr_talent[TAL_DREAM] < 100 || (IS_SET(ch->in_room->runes, RUNE_WARD) && ch->curr_talent[TAL_DREAM] < 200))) { ch_trick(ch, type); break; } act( AT_MAGIC, "You step into the world of dreams.", ch, NULL, NULL, TO_CHAR); act( AT_MAGIC, "$n slowly fades out of the waking world.", ch, NULL, NULL, TO_ROOM); xSET_BIT(ch->pcdata->perm_aff, AFF_DREAMWORLD); ch->position = POS_STANDING; act( AT_MAGIC, "$n slowly fades into the dream.", ch, NULL, NULL, TO_ROOM); break; } else { if (ch->curr_talent[TAL_DREAM] < 50) { ch_trick(ch, type); break; } if (!IS_AFFECTED(victim, AFF_DREAMWORLD)) { if (IS_AFFECTED(victim, AFF_VOID)) { ch_trick(ch, type); break; } if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) { ch_trick(ch, type); break; } act( AT_MAGIC, "You pull $N into the dream!", ch, NULL, victim, TO_CHAR); victim->position = POS_STANDING; if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_DREAMWORLD); else xSET_BIT(victim->pcdata->perm_aff, AFF_DREAMWORLD); act( AT_MAGIC, "The waking world seems to fade away.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); break; } act( AT_PURPLE, "You extract $N from the dream!", ch, NULL, victim, TO_CHAR); victim->position = POS_STANDING; if (IS_NPC(victim)) xREMOVE_BIT(victim->affected_by, AFF_DREAMWORLD); else xREMOVE_BIT(victim->pcdata->perm_aff, AFF_DREAMWORLD); act( AT_PURPLE, "The dream vanishes and waking world fades into view.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); break; } case MAG_ANTIMATTER: if (number_range(1, ch->curr_talent[TAL_VOID]) < 20) { ch_trick(ch, type); break; } if (victim == ch) { if (!IS_AFFECTED(ch, AFF_VOID)) { if (IS_AFFECTED(ch, AFF_DREAMWORLD)) { ch_trick(ch, type); break; } act(AT_DGREY, "You enter the Void.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "$n steps out of reality.", ch, NULL, NULL, TO_ROOM); xSET_BIT(ch->pcdata->perm_aff, AFF_VOID); act(AT_DGREY, "$n steps into the Void.", ch, NULL, NULL, TO_ROOM); break; } act(AT_DGREY, "You step out of the Void.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "$n steps out of the Void.", ch, NULL, NULL, TO_ROOM); xREMOVE_BIT(ch->pcdata->perm_aff, AFF_VOID); act(AT_DGREY, "$n steps into reality.", ch, NULL, NULL, TO_ROOM); break; } else { if (ch->curr_talent[TAL_VOID] < 40) { ch_trick(ch, type); break; } if (!IS_AFFECTED(victim, AFF_VOID)) { if (IS_AFFECTED(victim, AFF_DREAMWORLD)) { ch_trick(ch, type); break; } if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) { ch_trick(ch, type); break; } act( AT_MAGIC, "You pull $N into the Void!", ch, NULL, victim, TO_CHAR); victim->position = POS_STANDING; if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_VOID); else xSET_BIT(victim->pcdata->perm_aff, AFF_VOID); act( AT_MAGIC, "Reality seems to fade away into nothingness.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); break; } act( AT_DGREY, "You extract $N from the Void!", ch, NULL, victim, TO_CHAR); victim->position = POS_STANDING; if (IS_NPC(victim)) xREMOVE_BIT(victim->affected_by, AFF_VOID); else xREMOVE_BIT(victim->pcdata->perm_aff, AFF_VOID); act( AT_DGREY, "The Void vanishes and reality fades into view.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); break; } break; case MAG_WIND: if (IS_AFFECTED(victim, AFF_FLYING)) { if (ch->curr_talent[TAL_WIND] < 20 && ch->curr_talent[TAL_MOTION] < 50) { act(AT_CYAN, "You go plummeting toward the ground.", victim, NULL, NULL, TO_CHAR); act(AT_CYAN, "$n goes plummeting toward the ground.", victim, NULL, NULL, TO_ROOM); lose_hp(victim, victim->weight/10); } else { act(AT_CYAN, "You settle gracefully to the ground.", victim, NULL, NULL, TO_CHAR); act(AT_CYAN, "$n settles gracefully to the ground.", victim, NULL, NULL, TO_ROOM); } if (IS_NPC(victim)) xREMOVE_BIT(victim->affected_by, AFF_FLYING); else xREMOVE_BIT(victim->pcdata->perm_aff, AFF_FLYING); break; } if (ch->curr_talent[TAL_WIND] < 30 && ch->curr_talent[TAL_MOTION] < 75) { ch_trick(victim, type); break; } act(AT_MAGIC, "Mystic winds carry you off the ground.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "Mystic winds carry $n off the ground.", victim, NULL, NULL, TO_ROOM); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_FLYING); else xSET_BIT(victim->pcdata->perm_aff, AFF_FLYING); break; } } /* ch_move */ void summon_move(CHAR_DATA *ch, int type, int power, char *argument) { int i, vnum; ROOM_INDEX_DATA *location; char buf[MAX_STRING_LENGTH]; AREA_DATA *pArea; EXPLORED_AREA *xarea; DEITY_DATA *talent; CHAR_DATA *victim; CHAR_DATA *next_vict; bool found; OBJ_DATA *obj; location = NULL; switch (type) { default: ch_trick(ch, type); break; case MAG_TELEKINETIC: if (ch->curr_talent[TAL_MOTION] < 20) { ch_trick(ch, type); break; } if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) { send_to_char("You can't travel in combat!\n\r", ch); return; } if (!can_travel(90, ch, ch)) { send_to_char("You feel trapped in this place.\n\r",ch); return; } /* Start travel to location */ for(pArea = first_area; pArea; pArea = pArea->next) { if (nifty_is_name_prefix(argument, pArea->name)) { /* Only allow you to target areas you've been to already */ xarea = ch->pcdata->first_explored; while (xarea) { if (xarea->index == pArea->low_soft_range) { ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r", pArea->name); break; } xarea = xarea->next; } if (!xarea) { send_to_char("&BYou don't know what that area looks like yet.\n\r", ch); return; } if (IS_SET(pArea->flags, AFLAG_NOTRAVEL)) { send_to_char("&BStrong wards surround the area, blocking your magic.\n\r", ch); return; } for (i = 0;i <= 20;i++) { if (i == 20) { send_to_char("&BYou fail to penetrate the wards surrounding that area.\n\r", ch); return; } vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum); if ((location = get_room_index(vnum)) == NULL) continue; if (IS_SET(location->room_flags, ROOM_NO_ASTRAL)) { if (IS_SET(location->runes, RUNE_WARD)) continue; if (IS_SET(pArea->flags, AFLAG_NOBYPASS)) continue; if (TALENT(ch, TAL_MOTION) < 100) continue; } break; } if (!location) { send_to_char("You can't find a place to land.\n\r", ch); return; } if (ch->pcdata->inborn == -1) talent = get_talent_by_index(TAL_MOTION); else talent = get_talent_by_index(ch->pcdata->inborn); act(AT_MAGIC, "$T the room, and $n is gone.", ch, NULL, talent->message, TO_ROOM); act(AT_MAGIC, "$T the room, and you travel.", ch, NULL, talent->message, TO_CHAR); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, location); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, location); do_look(ch->mount, "auto"); } act( AT_MAGIC, "$T the room, and $n appears.", ch, NULL, talent->message, TO_ROOM); do_look( ch, "auto" ); learn_talent(ch, TAL_MOTION); WAIT_STATE(ch, PULSE_VIOLENCE*2 - ch->curr_talent[TAL_MOTION]/5); return; } /* end travel to location */ } if (ch->curr_talent[TAL_MOTION] < 50) { act( AT_MAGIC, "You are unable to locate anyplace like that.", ch, NULL, NULL, TO_CHAR); return; } /* start travel to person */ if ( (victim = get_char_world(ch, argument)) == NULL || !can_travel(90, ch, victim) || (TALENT(victim, TAL_SECURITY) > TALENT(ch, TAL_SEEKING))) { send_to_char("&BYou are unable to locate anyplace or anyone like that.\n\r", ch); return; } if (victim == ch) { send_to_char("That was a short trip!\n\r", ch); return; } if (victim == ch->mount) { send_to_char("You are riding them already!\n\r", ch); return; } if (ch->pcdata->inborn == -1) talent = get_talent_by_index(TAL_MOTION); else talent = get_talent_by_index(ch->pcdata->inborn); act(AT_MAGIC, "$T the room, and $n is gone.", ch, NULL, talent->message, TO_ROOM); act(AT_MAGIC, "$T the room, and you travel.", ch, NULL, talent->message, TO_CHAR); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, victim->in_room ); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, victim->in_room); do_look(ch->mount, "auto"); } act( AT_MAGIC, "$T the room, and $n appears.", ch, NULL, talent->message, TO_ROOM); do_look( ch, "auto" ); break; case MAG_SEEK: if (ch->curr_talent[TAL_MOTION] < 40) { ch_trick(ch, type); break; } if (IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS)) { ch_trick(ch, type); break; } if (IS_AFFECTED(ch, AFF_VOID)) { ch_trick(ch, type); break; } victim = get_char_world(ch, argument); if (!victim) { send_to_char("You cannot find anything like that.\n\r",ch); return; } if (victim == ch) { ch_trick(ch, type); break; } if (victim->in_room && !can_travel(100, ch, victim)) { send_to_char("Something prevents you from opening a rift.\n\r", ch); return; } if (!IS_NPC(victim)) { sprintf( buf, "%s summoned %s to %s (%d).", ch->name, victim->name, ch->in_room->name, ch->in_room->vnum ); to_channel( buf, "Spell", PERMIT_SECURITY); } act( AT_MAGIC, "A swirling rift opens for a moment, sucking $n through.", victim, NULL, ch, TO_ROOM); act(AT_MAGIC, "A swirling rift opens suddenly, and $n pulls you through!", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "You open a swirling rift and pull $N through.", ch, NULL, victim, TO_CHAR); act(AT_MAGIC, "$n opens a swirling rift and pulls $N through.", ch, NULL, victim, TO_ROOM); char_from_room(victim); victim->in_obj = NULL; char_to_room( victim, ch->in_room ); do_look( victim, "auto" ); WAIT_STATE(ch, PULSE_VIOLENCE); break; case MAG_DREAM: if (ch->curr_talent[TAL_DREAM] < 30) { ch_trick(ch, type); break; } if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) { ch_trick(ch, type); break; } victim = get_char_world(ch, argument); if (!victim) { /* Start travel to location */ for (pArea = first_area; pArea; pArea = pArea->next) { if ((argument[0] == '\0' || nifty_is_name_prefix(argument, pArea->name)) && !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) { /* Only allow you to target areas you've been to already */ xarea = ch->pcdata->first_explored; while (xarea) { if (xarea->index == pArea->low_soft_range) { ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r", pArea->name); break; } xarea = xarea->next; } if (!xarea) { send_to_char("&BYou don't know what that area looks like yet.\n\r", ch); return; } for (i = 0;i < 20;i++) { vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum); if ((location = get_room_index(vnum)) == NULL) continue; if (IS_SET(location->room_flags, ROOM_NO_DREAM)) continue; break; } if (!location) { ch_trick(ch, type); break; } act( AT_MAGIC, "You shift into another dream.", ch, NULL, NULL, TO_CHAR); act( AT_MAGIC, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, location ); act( AT_MAGIC, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); return; } } send_to_char("You can't find anyplace like that.\n\r",ch); return; } if (victim == ch) { send_to_char("That was a short trip!\n\r", ch); return; } if (IS_SET(victim->in_room->room_flags, ROOM_NO_DREAM) && (ch->curr_talent[TAL_DREAM] < 100 || (IS_SET(victim->in_room->runes, RUNE_WARD) && ch->curr_talent[TAL_DREAM] < 200))) { act( AT_MAGIC, "You are unable to locate anyone like that.", ch, NULL, NULL, TO_CHAR); return; } act( AT_MAGIC, "You shift into another dream.", ch, NULL, NULL, TO_CHAR); act( AT_MAGIC, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, victim->in_room ); act( AT_MAGIC, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); break; case MAG_UNHOLY: if ( ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_MOTION] < 95 ) { ch_trick(ch, type); break; } victim = get_char_world(ch, argument); if (!victim) { ch_trick(ch, type); break; } if (victim != ch && !IS_CONSENTING(victim, ch)) { send_to_char("You can't retrieve their corpse without their consent.\n\r" ,ch); return; } found = FALSE; for ( obj = first_object; obj; obj = obj->next ) { if ( obj->in_room && nifty_is_name( victim->name, obj->name ) && (obj->pIndexData->vnum == 11 ) ) { found = TRUE; if (obj->timer > 38) { act( AT_MAGIC, "The image of your corpse appears, but wavers away.", victim, NULL, NULL, TO_CHAR ); act( AT_MAGIC, "The image of $n's corpse appears, but wavers away.", victim, NULL, NULL, TO_ROOM ); return; } if (IS_SET( obj->in_room->room_flags, ROOM_NOSUPPLICATE ) && ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_MOTION] < 200) { act( AT_MAGIC, "Only silence answers from that forsaken place.", ch, NULL, NULL, TO_CHAR); return; } act( AT_MAGIC, "Your corpse appears suddenly, surrounded by a misty aura...", victim, NULL, NULL, TO_CHAR ); act( AT_MAGIC, "$n's corpse appears suddenly, surrounded by a misty aura...", victim, NULL, NULL, TO_ROOM ); obj_from_room(obj); obj = obj_to_room(obj, ch->in_room); } } if ( !found ) { send_to_char( "No corpse of that sort litters the world...\n\r", ch ); return; } WAIT_STATE(ch, PULSE_VIOLENCE*2); break; case MAG_PSIONIC: if (!argument || argument[0] == '\0') vnum = 0; else vnum = atoi(argument); if (!str_cmp(argument, "nexus")) { if (IS_SET(ch->in_room->area->flags, AFLAG_FREEKILL)) location = get_room_index(ROOM_VNUM_PKILL); else location = get_room_index(ROOM_VNUM_NEXUS); } else if (!str_cmp(argument, "area")) { location = get_room_index(ch->in_room->area->hi_soft_range); } else { i = (ch->curr_talent[TAL_MOTION] -20) / 10; if (i > 7) i = 7; if (i < 0 && ch->curr_talent[TAL_MOTION] > 0) i = 0; if (vnum > i) { send_to_char("You cannot recall the details of that location.\n\r", ch); return; } if (IS_NPC(ch)) { if (IS_AFFECTED(ch, AFF_CHARM) && ch->master && !IS_NPC(ch->master)) { location = get_room_index( ch->master->pcdata->memorize[vnum] ); } else { return; } } else { location = get_room_index( ch->pcdata->memorize[vnum] ); } } if ( !location ) location = get_room_index( ROOM_VNUM_NEXUS ); if ( !location ) { send_to_char( "You are completely lost.\n\r", ch ); return; } if ( ch->in_room == location ) { send_to_char("You are already here!\n\r", ch); return; } if ( IS_AFFECTED(ch, AFF_DREAMWORLD) && IS_SET(location->room_flags, ROOM_NO_DREAM)) { ch_trick(ch, type); break; } if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) && ch->curr_talent[TAL_MOTION] < 80) { ch_trick(ch, type); break; } if (IS_AFFECTED(ch, AFF_CURSE) && ch->curr_talent[TAL_MOTION] < 70) { ch_trick(ch, type); break; } if (IS_FIGHTING(ch) && ch->curr_talent[TAL_MOTION] < 60) { ch_trick(ch, type); break; } act( AT_ACTION, "$n disappears in a swirl of mist.", ch, NULL, NULL, TO_ROOM); char_from_room(ch); ch->in_obj = NULL; char_to_room(ch, location); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, location); do_look(ch->mount, "auto"); } act( AT_ACTION, "$n appears in the room, a ring of mist dissipating around $m.", ch, NULL, NULL, TO_ROOM ); do_look(ch, "auto"); break; case MAG_ANTIMATTER: if ( !IS_AFFECTED(ch, AFF_VOID) ) { ch_trick(ch, type); break; } victim = get_char_world(ch, argument); if (!victim) { /* Start travel to location */ for(pArea = first_area; pArea; pArea = pArea->next) { if((argument[0] == '\0' || nifty_is_name_prefix(argument, pArea->name)) && !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) { /* Only allow you to target areas you've been to already */ xarea = ch->pcdata->first_explored; while (xarea) { if (xarea->index == pArea->low_soft_range) { ch_printf(ch, "&BYou bring to mind your memory of %s...\n\r", pArea->name); break; } xarea = xarea->next; } if (!xarea) { send_to_char("&BYou don't know what that area looks like yet.\n\r", ch); return; } for (i = 0;i < 20;i++) { vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum); if ((location = get_room_index(vnum)) == NULL) continue; break; } if (!location) { ch_trick(ch, type); break; } act( AT_DGREY, "You shift into another part of the Void.", ch, NULL, NULL, TO_CHAR); act( AT_DGREY, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, location ); act( AT_DGREY, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); } } ch_trick(ch, type); break; } if (victim == ch) { ch_trick(ch, type); break; } act( AT_DGREY, "You shift into another part of the Void.", ch, NULL, NULL, TO_CHAR); act( AT_DGREY, "$n fades out of existance.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, victim->in_room ); act( AT_DGREY, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); break; case MAG_ETHER: if (ch->curr_talent[TAL_VOID] < 80) { ch_trick(ch, type); break; } if (!IS_AFFECTED(ch, AFF_VOID)) { ch_trick(ch, type); break; } victim = get_char_world(ch, argument); if (!victim || (IS_NPC(victim) && !xIS_SET(victim->act, ACT_NAMED))) victim = generate_mob_nation(argument); if (!victim) { ch_trick(ch, type); break; } if (victim == ch) { ch_trick(ch, type); break; } if (victim->in_room) { act( AT_DGREY, "$n tears a rift in reality and pulls you through!", ch, NULL, victim, TO_VICT); act( AT_DGREY, "$n is ripped through a rift in reality!", victim, NULL, NULL, TO_ROOM); char_from_room( victim ); } victim->in_obj = NULL; char_to_room( victim, ch->in_room ); if (IS_NPC(victim)) xSET_BIT(victim->affected_by, AFF_VOID); else xSET_BIT(victim->pcdata->perm_aff, AFF_VOID); act( AT_DGREY, "$n is pulled into the Void!", victim, NULL, NULL, TO_ROOM); do_look( victim, "auto" ); break; case MAG_BLUNT: if ((ch->curr_talent[TAL_EARTH] < 20 && !IS_NPC(ch)) || IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR)) { ch_trick(ch, type); break; } act(AT_HUNGRY, "The earth trembles beneath you!", ch, NULL, NULL, TO_CHAR); act(AT_HUNGRY, "The ground begins to tremble and shake!", ch, NULL, NULL, TO_ROOM); for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; if (IS_AFFECTED(victim, AFF_FLYING) && !IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) continue; ch_harm(victim, ch, power, MAG_BLUNT, FALSE); if (char_died(ch)) return; } break; } } /* summon_move */ void obj_change(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power, char *argument) { CHAR_DATA *mob; OBJ_DATA *obj1; OBJ_DATA *obj_next; MOB_INDEX_DATA *pMobIndex; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; DESCRIPTOR_DATA *d; PART_DATA *part; int amt; bool found; switch (type) { default: obj_trick(ch, obj, type); break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 30) { obj_trick(ch, obj, type); break; } if (obj->item_type == ITEM_CORPSE_PC && ch->curr_talent[TAL_DEATH] >= 50) { for (d = first_descriptor; d; d = d->next) { if (d->connected == CON_PLAYING) { if (nifty_is_name(d->character->name, obj->name)) { victim = d->character; break; } } } if (!victim) { obj_trick(ch, obj, type); break; } if (!IS_CONSENTING(victim, ch)) { send_to_char("You cannot reanimate them without their consent.\n\r", ch); return; } if (power < victim->perm_con*10) { obj_trick(ch, obj, type); break; } if (!IS_AFFECTED(victim, AFF_ETHEREAL)) { send_to_char("You cannot reanimate them when they are not ethereal.\n\r", ch); return; } while ((obj = victim->first_carrying)) { obj_from_char(obj); obj_to_room(obj, victim->in_room); } while (victim->first_affect) affect_remove ( victim, victim->first_affect ); act(AT_DGREY, "$n screams in agony as $e is drawn back into $s body.", victim, NULL, NULL, TO_ROOM); act(AT_DGREY, "You scream in agony as you are drawn back into your body.", victim, NULL, NULL, TO_CHAR); if (victim->in_room != ch->in_room) { char_from_room(victim); victim->in_obj = NULL; char_to_room(victim, ch->in_room); } part = victim->first_part; while (part) { part->cond = PART_WELL; part->flags = PART_WELL; part = part->next; } victim->exp += obj->cost; if ( get_timer( victim, TIMER_PKILLED ) > 0 ) remove_timer( victim, TIMER_PKILLED ); victim->weight = obj->weight; act(AT_DGREY, "An unholy black aura surrounds the corpse of $n.", victim, NULL, NULL, TO_ROOM); while ((obj1 = obj->first_content)) { obj_from_obj(obj1); if ( obj1->item_type == ITEM_MONEY ) { amt = obj1->value[0]; ch->gold += amt; extract_obj(obj1); } else { obj_to_char(obj1, victim); } } separate_obj(obj); extract_obj(obj); fix_char(victim); victim->position = POS_RESTING; xCLEAR_BITS(victim->pcdata->perm_aff); xSET_BIT(victim->pcdata->perm_aff, AFF_UNDEAD); found = TRUE; if (!str_cmp(argument, "lich") && ch->curr_talent[TAL_DEATH] >= 150) { xSET_BIT(victim->pcdata->perm_aff, AFF_FEAR); xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); } else if (!str_cmp(argument, "vampire") && ch->curr_talent[TAL_DEATH] >= 100) { xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); SET_BIT(victim->pcdata->flags, PCFLAG_VAMPIRE); } else if (!str_cmp(argument, "skeleton") && ch->curr_talent[TAL_DEATH] >= 70) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); xSET_BIT(victim->pcdata->perm_aff, AFF_CONSTRUCT); } else if (!str_cmp(argument, "ghoul") && ch->curr_talent[TAL_DEATH] >= 60) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); } else if (!str_cmp(argument, "wraith") && ch->curr_talent[TAL_DEATH] >= 110) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE); xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR); } else if (!str_cmp(argument, "shadow") && ch->curr_talent[TAL_DEATH] >= 130) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE); xSET_BIT(victim->pcdata->perm_aff, AFF_DARK); xSET_BIT(victim->pcdata->perm_aff, AFF_UNHOLY); xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR); } else if (!str_cmp(argument, "ghost") && ch->curr_talent[TAL_DEATH] >= 80) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE); xSET_BIT(victim->pcdata->perm_aff, AFF_CURSE); xSET_BIT(victim->pcdata->perm_aff, AFF_FLOATING); xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR); } else if (!str_cmp(argument, "banshee") && ch->curr_talent[TAL_DEATH] >= 140) { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); xSET_BIT(victim->pcdata->perm_aff, AFF_NO_CORPSE); xSET_BIT(victim->pcdata->perm_aff, AFF_FEAR); xSET_BIT(victim->pcdata->perm_aff, AFF_FLOATING); xSET_BIT(victim->pcdata->perm_aff, AFF_PASS_DOOR); } else { xSET_BIT(victim->pcdata->perm_aff, AFF_INFRARED); xSET_BIT(victim->pcdata->perm_aff, AFF_NONLIVING); xSET_BIT(victim->pcdata->perm_aff, AFF_AQUA_BREATH); found = FALSE; } STRFREE(victim->pcdata->type); if (found) victim->pcdata->type = STRALLOC(argument); else victim->pcdata->type = STRALLOC("zombie"); act(AT_DGREY, "$n's eyes snap open, glowing with a faint reddish glow.", victim, NULL, NULL, TO_ROOM); act(AT_DGREY, "Your eyes snap open, and you look on the world with the sight of unlife.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "You feel drained and exhausted from the reanimation.", ch, NULL, NULL, TO_CHAR); ch->mental_state = -100; STRFREE(ch->last_taken); sprintf(buf, "reanimating %s", victim->name); ch->last_taken = STRALLOC(buf); WAIT_STATE(ch, PULSE_VIOLENCE*10); STRFREE(victim->last_taken); ch->last_taken = STRALLOC("being reanimated"); WAIT_STATE(victim, PULSE_VIOLENCE*10); return; } /* end player reanimate */ if (get_mob_index(MOB_VNUM_ANIMATED_CORPSE) == NULL) { bug("Vnum 5 not found for do_reanimate!", 0); return; } if ((pMobIndex = get_mob_index((sh_int) abs(obj->cost))) == NULL ) { bug("Can not find mob for cost of corpse, do_reanimate", 0); return; } if (xIS_SET(pMobIndex->affected_by, AFF_NONLIVING)) { obj_trick(ch, obj, type); break; } if (power - (pMobIndex->perm_con*4) < 0) { obj_trick(ch, obj, type); break; } if (chance(ch, 75) && pMobIndex->perm_con - ch->curr_talent[TAL_DEATH] < 10) { mob = create_mobile(get_mob_index(MOB_VNUM_ANIMATED_CORPSE)); char_to_room(mob, ch->in_room); mob->race = pMobIndex->race; xSET_BIT(mob->affected_by, AFF_UNDEAD); xSET_BIT(mob->affected_by, AFF_NONLIVING); xSET_BIT(mob->affected_by, AFF_TRUESIGHT); /* Fix so mobs wont have 0 hps and crash mud - Scryn 2/20/96 */ if (!pMobIndex->hitnodice) mob->max_hit = (pMobIndex->perm_con * TALENT(ch, TAL_DEATH)) / 10; else mob->max_hit = UMAX(URANGE(mob->max_hit / 4, (mob->max_hit * obj->value[3]) / 10, ch->curr_talent[TAL_DEATH] * dice(20,10)), 1); xSET_BIT(mob->affected_by, AFF_INFRARED); mob->hit = mob->max_hit; mob->damroll = TALENT(ch, TAL_DEATH) / 3; mob->hitroll = TALENT(ch, TAL_DEATH) / 2; mob->perm_str = obj->value[0]; mob->perm_int = obj->value[1]; mob->perm_wis = obj->value[2]; mob->perm_dex = obj->value[3]; mob->perm_con = obj->value[4]; mob->perm_cha = obj->value[5]; mob->perm_lck = obj->value[6]; act(AT_MAGIC, "$n makes $N rise from the grave!", ch, NULL, mob, TO_ROOM); act(AT_MAGIC, "You make $N rise from the grave!", ch, NULL, mob, TO_CHAR); sprintf(buf, "animated %s", obj->name); STRFREE(mob->name); mob->name = STRALLOC(buf); sprintf(buf, "animated %s", obj->short_descr); STRFREE(mob->short_descr); mob->short_descr = STRALLOC(buf); add_follower( mob, ch ); if (obj->timer > 0) { af.type = -1; af.duration = (number_fuzzy( obj->timer ) * DUR_CONV); af.location = 0; af.modifier = 0; af.bitvector = meb(AFF_CHARM); affect_to_char( mob, &af ); } else { xSET_BIT(mob->affected_by, AFF_CHARM); } /* run through the part flags on the corpse and give it the * ones it should have. if a part was severed before, it won't * have it now. i wish this wasn't necessary, but its needed to * be able to reattach them properly. */ if (xIS_SET(obj->parts, BP_CHEST)) add_part(mob, BP_CHEST, -1); if (xIS_SET(obj->parts, BP_NECK)) add_part(mob, BP_NECK, BP_CHEST); if (xIS_SET(obj->parts, BP_HEAD)) add_part(mob, BP_HEAD, BP_NECK); if (xIS_SET(obj->parts, BP_REAR)) add_part(mob, BP_REAR, BP_HEAD); if (xIS_SET(obj->parts, BP_LEAR)) add_part(mob, BP_LEAR, BP_HEAD); if (xIS_SET(obj->parts, BP_NOSE)) add_part(mob, BP_NOSE, BP_HEAD); if (xIS_SET(obj->parts, BP_REYE)) add_part(mob, BP_REYE, BP_HEAD); if (xIS_SET(obj->parts, BP_LEYE)) add_part(mob, BP_LEYE, BP_HEAD); if (xIS_SET(obj->parts, BP_TONGUE)) add_part(mob, BP_TONGUE, BP_HEAD); if (xIS_SET(obj->parts, BP_RHORN)) add_part(mob, BP_RHORN, BP_HEAD); if (xIS_SET(obj->parts, BP_LHORN)) add_part(mob, BP_LHORN, BP_HEAD); if (xIS_SET(obj->parts, BP_RARM)) add_part(mob, BP_RARM, BP_CHEST); if (xIS_SET(obj->parts, BP_LARM)) add_part(mob, BP_LARM, BP_CHEST); if (xIS_SET(obj->parts, BP_STOMACH)) add_part(mob, BP_STOMACH, -1); if (xIS_SET(obj->parts, BP_RHAND)) add_part(mob, BP_RWRIST, BP_RARM); if (xIS_SET(obj->parts, BP_LHAND)) add_part(mob, BP_LWRIST, BP_LARM); if (xIS_SET(obj->parts, BP_RHAND)) add_part(mob, BP_RHAND, BP_RWRIST); if (xIS_SET(obj->parts, BP_LHAND)) add_part(mob, BP_LHAND, BP_LWRIST); if (xIS_SET(obj->parts, BP_RLEG)) add_part(mob, BP_RLEG, BP_ASS); if (xIS_SET(obj->parts, BP_LLEG)) add_part(mob, BP_LLEG, BP_ASS); if (xIS_SET(obj->parts, BP_RFOOT)) add_part(mob, BP_RANKLE, BP_RLEG); if (xIS_SET(obj->parts, BP_LANKLE)) add_part(mob, BP_LANKLE, BP_LLEG); if (xIS_SET(obj->parts, BP_RFOOT)) add_part(mob, BP_RFOOT, BP_RANKLE); if (xIS_SET(obj->parts, BP_LFOOT)) add_part(mob, BP_LFOOT, BP_LANKLE); if (xIS_SET(obj->parts, BP_ASS)) add_part(mob, BP_ASS, -1); if (xIS_SET(obj->parts, BP_NOSE)) add_part(mob, BP_BACK, -1); if (xIS_SET(obj->parts, BP_RWING)) add_part(mob, BP_RWING, BP_BACK); if (xIS_SET(obj->parts, BP_LWING)) add_part(mob, BP_LWING, BP_BACK); if (xIS_SET(obj->parts, BP_RPAW)) add_part(mob, BP_RPAW, BP_RANKLE); if (xIS_SET(obj->parts, BP_LPAW)) add_part(mob, BP_LPAW, BP_LANKLE); if (xIS_SET(obj->parts, BP_RHOOF)) add_part(mob, BP_RHOOF, BP_RANKLE); if (xIS_SET(obj->parts, BP_LHOOF)) add_part(mob, BP_LHOOF, BP_LANKLE); if (xIS_SET(obj->parts, BP_CLAWS)) add_part(mob, BP_CLAWS, BP_RPAW); if (xIS_SET(obj->parts, BP_TAIL)) add_part(mob, BP_TAIL, BP_ASS); if (xIS_SET(obj->parts, BP_FANGS)) add_part(mob, BP_FANGS, BP_HEAD); if (xIS_SET(obj->parts, BP_RFLEG)) add_part(mob, BP_RFLEG, BP_CHEST); if (xIS_SET(obj->parts, BP_LFLEG)) add_part(mob, BP_LFLEG, BP_CHEST); if (xIS_SET(obj->parts, BP_RRLEG)) add_part(mob, BP_RRLEG, BP_ASS); if (xIS_SET(obj->parts, BP_LRLEG)) add_part(mob, BP_LRLEG, BP_ASS); if (xIS_SET(obj->parts, BP_RFIN)) add_part(mob, BP_RFIN, BP_CHEST); if (xIS_SET(obj->parts, BP_LFIN)) add_part(mob, BP_LFIN, BP_CHEST); if (xIS_SET(obj->parts, BP_DFIN)) add_part(mob, BP_DFIN, BP_BACK); if (obj->first_content) for( obj1 = obj->first_content; obj1; obj1 = obj_next) { obj_next = obj1->next_content; obj_from_obj(obj1); obj_to_char(obj1, mob); equip_char(mob, obj1); } separate_obj(obj); extract_obj(obj); STRFREE(ch->last_taken); sprintf(buf, "reanimating %s", mob->name); ch->last_taken = STRALLOC(buf); WAIT_STATE(ch, PULSE_VIOLENCE*4); STRFREE(mob->last_taken); ch->last_taken = STRALLOC("being reanimated"); WAIT_STATE(mob, PULSE_VIOLENCE*4); return; } else { send_to_char("You fail to reanimate the corpse.\n\r", ch); use_magic(ch, TAL_DEATH, 300 - ch->curr_talent[TAL_DEATH]*2); STRFREE(ch->last_taken); ch->last_taken = STRALLOC("trying to reanimate a corpse"); WAIT_STATE(ch, PULSE_VIOLENCE*2); } break; case MAG_HOLY: if (ch->curr_talent[TAL_HEALING] < 100) { obj_trick(ch, obj, type); break; } if (obj->item_type != ITEM_CORPSE_PC) { obj_trick(ch, obj, type); break; } for ( d = first_descriptor; d; d = d->next ) { if (d->connected == CON_PLAYING) { if (nifty_is_name(d->character->name, obj->name)) { victim = d->character; break; } } } if (!victim) { obj_trick(ch, obj, type); break; } if (power < victim->perm_con*10) { obj_trick(ch, obj, type); break; } if (!IS_CONSENTING(victim, ch)) { send_to_char("You cannot resurrect them without their consent.\n\r", ch); return; } if (!IS_AFFECTED(victim, AFF_ETHEREAL)) { send_to_char("You cannot resurrect them when they are not ethereal.\n\r", ch); return; } while ((obj1 = victim->first_carrying)) { obj_from_char(obj); obj_to_room(obj1, victim->in_room); } while (victim->first_affect) affect_remove ( victim, victim->first_affect ); act(AT_DGREY, "$n screams in agony as $e is drawn back into $s body.", victim, NULL, NULL, TO_ROOM); act(AT_DGREY, "You scream in agony as you are drawn back into your body.", victim, NULL, NULL, TO_CHAR); if (victim->in_room != ch->in_room) { char_from_room(victim); victim->in_obj = NULL; char_to_room(victim, ch->in_room); } part = victim->first_part; while (part) { part->cond = PART_WELL; part->flags = PART_WELL; part = part->next; } victim->exp += obj->cost; if ( get_timer( victim, TIMER_PKILLED ) > 0 ) remove_timer( victim, TIMER_PKILLED ); act(AT_WHITE, "A radiant white aura surrounds the corpse of $n.", victim, NULL, NULL, TO_ROOM); while ((obj1 = obj->first_content)) { obj_from_obj(obj1); if ( obj1->item_type == ITEM_MONEY ) { amt = obj->value[0]; ch->gold += amt; extract_obj(obj1); } else { obj_to_char(obj1, victim); } } separate_obj(obj); extract_obj(obj); fix_char(victim); victim->position = POS_RESTING; act(AT_WHITE, "$n's eyes flutter open, and $e takes in a deep breath.", victim, NULL, NULL, TO_ROOM); act(AT_WHITE, "Your eyes flutter open, and you take in a deep breath.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "You feel drained and exhausted from the resurrection.", ch, NULL, NULL, TO_CHAR); ch->mental_state = -100; STRFREE(ch->last_taken); sprintf(buf, "resurrecting %s", victim->name); ch->last_taken = STRALLOC(buf); WAIT_STATE(ch, PULSE_VIOLENCE*10); STRFREE(victim->last_taken); ch->last_taken = STRALLOC("being resurrected"); WAIT_STATE(victim, PULSE_VIOLENCE*10); /* If they were undead, resurrection will revive them */ if (xIS_SET(victim->pcdata->perm_aff, AFF_UNDEAD)) { STRFREE(victim->pcdata->type); victim->pcdata->type = STRALLOC("living"); xCLEAR_BITS(victim->pcdata->perm_aff); REMOVE_BIT(victim->pcdata->flags, PCFLAG_VAMPIRE); } break; case MAG_LIGHT: if (ch->curr_talent[TAL_ILLUSION] + ch->curr_talent[TAL_CHANGE] + ch->curr_talent[TAL_CATALYSM] < 100) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (!argument || argument[0] == '\0') { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) { obj_trick(ch, obj, type); break; } if (obj->material && obj->material->number == 116) { /* ether */ obj_trick(ch, obj, type); break; } separate_obj(obj); /* Thanks Zemus */ act(AT_MAGIC, "Your magic twists around $p, making it look like $T!", ch, obj, argument, TO_CHAR); act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!", ch, obj, argument, TO_ROOM); STRFREE(obj->name); STRFREE(obj->short_descr); STRFREE(obj->description); obj->name = STRALLOC(munch_colors(argument)); obj->short_descr = STRALLOC(argument); strcpy(buf, argument); strcat(buf, " is here."); obj->description = STRALLOC(buf); break; case MAG_ETHER: if (ch->curr_talent[TAL_VOID] < 30) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (!argument || argument[0] == '\0') { obj_trick(ch, obj, type); break; } if (!obj->material || obj->material->number != 116) { /* ether */ obj_trick(ch, obj, type); break; } separate_obj(obj); /* Thanks Zemus */ act(AT_MAGIC, "Your magic twists around $p, making it look like $T!", ch, obj, argument, TO_CHAR); act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!", ch, obj, argument, TO_ROOM); STRFREE(obj->name); STRFREE(obj->short_descr); STRFREE(obj->description); obj->name = STRALLOC(munch_colors(argument)); obj->short_descr = STRALLOC(argument); strcpy(buf, argument); strcat(buf, " is here."); obj->description = STRALLOC(buf); break; case MAG_DREAM: if (ch->curr_talent[TAL_DREAM] < 40) { obj_trick(ch, obj, type); break; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { obj_trick(ch, obj, type); break; } if (!argument || argument[0] == '\0') { obj_trick(ch, obj, type); break; } if (!IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) { obj_trick(ch, obj, type); break; } separate_obj(obj); /* Thanks Zemus */ act(AT_MAGIC, "Your magic twists around $p, making it look like $T!", ch, obj, argument, TO_CHAR); act(AT_MAGIC, "$n's magic twists around $p, and suddenly $e is holding $T!", ch, obj, argument, TO_ROOM); STRFREE(obj->name); STRFREE(obj->short_descr); STRFREE(obj->description); obj->name = STRALLOC(munch_colors(argument)); obj->short_descr = STRALLOC(argument); strcpy(buf, argument); strcat(buf, " is here."); obj->description = STRALLOC(buf); break; } } void ch_change(CHAR_DATA *victim, CHAR_DATA *ch, int type, char *argument) { NATION_DATA *nation; SPECIES_DATA *species; OBJ_DATA *obj; int i; char arg1[MAX_STRING_LENGTH]; switch (type) { default: ch_trick(victim, type); break; case MAG_CHANGE: if (!argument || argument[0] == '\0') { ch_trick(victim, type); break; } if (ch->curr_talent[TAL_CHANGE] < 30) { ch_trick(victim, type); break; } if (ch->mount) { send_to_char("And scare your mount?\n\r", ch); return; } if (IS_NPC(victim)) { ch_trick(victim, type); break; } if (IS_AFFECTED(ch, AFF_MOUNTED)) throw_rider(ch); if (!str_cmp(argument, "anthro")) { if (has_bodypart(victim, BP_RHAND)) { ch_trick(victim, type); break; } if (victim->height > 100) { ch_trick(victim, type); break; } xSET_BIT(victim->pcdata->perm_aff, AFF_ANTHRO); check_bodyparts(victim); if (victim->height < 60) victim->height = number_range(36,60); else victim->height = number_range(60,76); victim->weight = get_height_weight(victim); STRFREE(victim->pcdata->type); victim->pcdata->type = STRALLOC("anthropomorphic"); act(AT_MAGIC, "Your body warps into an anthropomorphic form.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's body warps into an anthropomorphic form.", ch, NULL, NULL, TO_NOTVICT); if (victim != ch) act(AT_MAGIC, "You warp $N's body into an anthropomorphic form.", ch, NULL, victim, TO_CHAR); return; } if (victim != ch) { if (TALENT(ch, TAL_CHANGE) < 80) { ch_trick(victim, type); break; } if (!IS_CONSENTING(victim, ch) && TALENT(ch, TAL_CHANGE) < 400) { send_to_char("You cannot do that without their consent.\n\r", ch); return; } } nation = find_nation(argument); if (!nation) { ch_trick(victim, type); break; } if (str_cmp(nation->species, victim->nation->species) && (ch->curr_talent[TAL_CHANGE] < 60)) { ch_trick(victim, type); break; } de_equip_char(victim); if (IS_AFFECTED(victim, AFF_FLYING)) do_land(victim, ""); species = find_species(nation->species); if (!species) { bug("do_change: cannot find species!"); send_to_char("You suddenly forget what one of those is.",ch); return; } ch_printf(victim, "Your body changes and warps, and you become %s.\n\r", aoran(nation->name)); act( AT_MAGIC, "$N's body changes and warps, and $E becomes $t.", ch, aoran(nation->name), victim, TO_NOTVICT); if (ch != victim) { act( AT_MAGIC, "You change and warp $N's body into $t.", ch, aoran(nation->name), victim, TO_CHAR); } if (IS_AFFECTED(victim, AFF_ANTHRO)) { xREMOVE_BIT(victim->pcdata->perm_aff, AFF_ANTHRO); STRFREE(victim->pcdata->type); if (IS_AFFECTED(victim, AFF_UNDEAD)) victim->pcdata->type = STRALLOC("undead"); else victim->pcdata->type = STRALLOC("living"); } victim->nation = nation; set_race(victim, FALSE); if (!IS_SET(nation->parts, PART_HANDS)) { if (ch->main_hand) { obj_unaffect_ch(ch, ch->main_hand); ch->main_hand = NULL; } if (ch->off_hand) { obj_unaffect_ch(ch, ch->off_hand); ch->off_hand = NULL; } } if (ch->curr_talent[TAL_CHANGE] >= 50) { for (obj = victim->first_carrying; obj; obj = obj->next_content) { obj->size = victim->height; } } re_equip_char(victim); update_aris(victim); victim->max_hit = UMAX(20, victim->nation->hit * get_curr_con(victim) + victim->base_hit); victim->max_mana = UMAX(20, victim->nation->mana * get_curr_int(victim) + victim->base_mana); victim->max_move = UMAX(20, 25 * get_curr_end(victim) + victim->base_move); victim->mana = UMIN(victim->max_mana, victim->mana); break; case MAG_TIME: if (ch->curr_talent[TAL_TIME] < 30) { ch_trick(victim, type); break; } if (IS_NPC(victim)) { ch_trick(victim, type); break; } i = atoi(argument); if (i < 1 || i > TALENT(ch, TAL_TIME)) { ch_trick(victim, type); break; } if (!IS_CONSENTING(victim, ch) && TALENT(ch, TAL_TIME) < 400) { send_to_char("You cannot do that without their consent.\n\r", ch); return; } WAIT_STATE(ch, abs(victim->pcdata->age_adjust - i)/10); if (victim->pcdata->age_adjust == i) { ch_trick(victim, type); break; } act(AT_BLUE, "$N's body changes as $E becomes $t.", ch, victim->pcdata->age_adjust < i ? "older" : "younger", victim, TO_NOTVICT); act(AT_BLUE, "Your body changes as you become $t.", victim, victim->pcdata->age_adjust < i ? "older" : "younger", NULL, TO_CHAR); if (ch != victim) act(AT_BLUE, "You change $N's body to become $t.", ch, victim->pcdata->age_adjust < i ? "older" : "younger", victim, TO_CHAR); victim->pcdata->age_adjust = i; break; case MAG_SEEK: if (ch->curr_talent[TAL_CHANGE] < 25) { ch_trick(victim, type); break; } if (IS_NPC(victim)) { ch_trick(victim, type); break; } argument = one_argument(argument, arg1); if (!argument || !arg1) { ch_trick(victim, type); break; } if (victim != ch) { if (TALENT(ch, TAL_CHANGE) < 50) { send_to_char("You are not strong enough to change others yet.\n\r", ch); return; } if (!IS_CONSENTING(victim, ch) && TALENT(ch, TAL_CHANGE) < 100) { send_to_char("You cannot do that without their consent.\n\r", ch); return; } } if (!str_cmp(arg1, "height")) { i = atoi(argument); if (i >= victim->nation->height * (1 + TALENT(ch, TAL_CHANGE) / 100)) { send_to_char("You can't make them that tall.\n\r", ch); return; } if (i <= victim->nation->height - victim->nation->height * TALENT(ch, TAL_CHANGE) / 100 || victim->height <= 10) { send_to_char("You can't make them that short.\n\r", ch); return; } victim->height = i; if (victim != ch) { act(AT_MAGIC, "Your height changes.", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "You make $N's height change.", ch, NULL, victim, TO_CHAR); } else { act(AT_MAGIC, "You change your height.", ch, NULL, NULL, TO_CHAR); } act(AT_MAGIC, "$N's height changes.", ch, NULL, victim, TO_NOTVICT); } else if (!str_cmp(arg1, "weight")) { i = atoi(argument); if (i >= victim->nation->weight * (1 + TALENT(ch, TAL_CHANGE) / 100)) { send_to_char("You can't make them that heavy.\n\r", ch); return; } if (i <= victim->nation->weight - victim->nation->weight * TALENT(ch, TAL_CHANGE) / 100 || victim->weight <= 10) { send_to_char("You can't make them that light.\n\r", ch); return; } victim->weight = i; if (victim != ch) { if (victim != ch) { act(AT_MAGIC, "Your weight changes.", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "You make $N's weight change.", ch, NULL, victim, TO_CHAR); } else { act(AT_MAGIC, "You change your weight.", ch, NULL, NULL, TO_CHAR); } act(AT_MAGIC, "$N's weight changes.", ch, NULL, victim, TO_NOTVICT); } } else if (!str_cmp(arg1, "sex")) { if (!str_prefix("f", argument)) victim->sex = SEX_FEMALE; else if (!str_prefix("m", argument)) victim->sex = SEX_MALE; else if (!str_prefix("n", argument)) victim->sex = SEX_NEUTRAL; else if (!str_prefix("h", argument)) victim->sex = SEX_HERMAPH; if (victim != ch) { act(AT_MAGIC, "You feel something strange change in your crotch.", ch, NULL, victim, TO_VICT); act(AT_MAGIC, "You change $N's gender.", ch, NULL, victim, TO_CHAR); } else { act(AT_MAGIC, "You change your own sex.", ch, NULL, NULL, TO_CHAR); } act(AT_MAGIC, "$N's crotch seems to shift a little.", ch, NULL, victim, TO_NOTVICT); check_bodyparts(victim); } else if (victim->pcdata->eyes && !str_cmp("eyes", arg1)) { STRFREE(victim->pcdata->eyes); victim->pcdata->eyes = STRALLOC(argument); act(AT_MAGIC, "Your eyes itch.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's eyes change to $T.", victim, NULL, argument, TO_ROOM); } else if (victim->pcdata->hair && !str_cmp("hair", arg1)) { STRFREE(victim->pcdata->hair); victim->pcdata->hair = STRALLOC(argument); act(AT_MAGIC, "Your hair shimmers for a moment.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's hair changes to $T.", victim, NULL, argument, TO_ROOM); } else if (victim->pcdata->skin_type && !str_cmp(victim->pcdata->skin_type, arg1)) { STRFREE(victim->pcdata->skin_color); victim->pcdata->skin_color = STRALLOC(argument); act(AT_MAGIC, "Your $t shimmers for a moment.", victim, victim->pcdata->skin_type, NULL, TO_CHAR); act(AT_MAGIC, "$n's $t changes to $T.", victim, victim->pcdata->skin_type, argument, TO_ROOM); } else if (victim->pcdata->extra_type && !str_cmp(victim->pcdata->extra_type, arg1)) { STRFREE(victim->pcdata->extra_color); victim->pcdata->extra_color = STRALLOC(argument); act(AT_MAGIC, "Your $t shimmers for a moment.", victim, victim->pcdata->extra_type, NULL, TO_CHAR); act(AT_MAGIC, "$n's $t changes to $T.", victim, victim->pcdata->extra_type, argument, TO_ROOM); } else { send_to_char("They don't have that.\n\r", ch); return; } break; case MAG_LIGHT: if (!argument || argument[0] == '\0' || argument[0] == ' ') { STRFREE(ch->pcdata->name_disguise); act(AT_MAGIC, "Your form flickers as you drop the illusion.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's form flickers for a moment.", ch, NULL, NULL, TO_ROOM); break; } if (ch->curr_talent[TAL_ILLUSION] < 100) { ch_trick(victim, type); break; } STRFREE(ch->pcdata->name_disguise); ch->pcdata->name_disguise = STRALLOC(argument); act(AT_MAGIC, "Your form shimmers as you raise an illusion.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's form shimmers for a moment.", ch, NULL, NULL, TO_ROOM); break; case MAG_ANTIMAGIC: if (ch->curr_talent[TAL_SEEKING] < 50) { ch_trick(victim, type); break; } if (IS_NPC(victim) || !victim->pcdata->name_disguise) { ch_trick(victim, type); break; } STRFREE(victim->pcdata->name_disguise); act(AT_MAGIC, "Your form flickers as your illusion vanishes.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's form flickers for a moment.", victim, NULL, NULL, TO_ROOM); break; case MAG_HOLY: if (ch->curr_talent[TAL_HEALING] < 200) { ch_trick(victim, type); break; } if (IS_AFFECTED(ch, AFF_ANGEL)) { ch_trick(victim, type); break; } set_char_color(AT_WHITE, ch); act(AT_WHITE, "A luminous white aura surrounds $n, radiance in holiness...", ch, NULL, NULL, TO_ROOM); send_to_char("A cleansing light washes through you, purifying you to the core of your being...\n\r", ch); STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("angelic"); act(AT_WHITE, "In a blinding flash of light the luminence fades, leaving $n surrounded in a holy halo.", ch, NULL, NULL, TO_ROOM); send_to_char("You feel changed, looking on the world in a whole new light.\n\r", ch); xSET_BIT(ch->pcdata->perm_aff, AFF_ANGEL); xSET_BIT(ch->pcdata->perm_aff, AFF_HOLY); break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 200) { ch_trick(victim, type); break; } if (IS_AFFECTED(ch, AFF_DEMON)) { ch_trick(victim, type); break; } set_char_color(AT_DGREY, ch); act(AT_DGREY, "Twisting demonic shadows surround $n, writhing and groping at $s body.", ch, NULL, NULL, TO_ROOM); send_to_char("You call upon the shadows of the underworld...\n\r", ch); send_to_char("The shadows surround you, penetrating your body, clutching at your very soul.\n\r", ch); STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("demonic"); act(AT_DGREY, "The shadows seem to sink into $n, rooting themselves deeply.", ch, NULL, NULL, TO_ROOM); send_to_char("The shadows claim your soul, and leave in its place an unholy aura.\n\r", ch); xSET_BIT(ch->pcdata->perm_aff, AFF_DEMON); xSET_BIT(ch->pcdata->perm_aff, AFF_UNHOLY); break; case MAG_ALL: if (ch->curr_talent[TAL_CATALYSM] < 200) { ch_trick(victim, type); break; } if (IS_AFFECTED(ch, AFF_ETHEREAL)) { ch_trick(victim, type); break; } set_char_color(AT_PURPLE, ch); act(AT_MAGIC, "$n glows in a mystical purplish light, brilliant and all-consuming.", ch, NULL, NULL, TO_ROOM); send_to_char("You focus yourself, gathering all your magic together in a solid core.\n\r", ch); STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("ethereal"); act(AT_MAGIC, "$n seems to transcend $s mortal body, stepping away from it in a magical ethereal form.", ch, NULL, NULL, TO_ROOM); send_to_char("In a step of tremendous power and will, you step out of your mortal body, leaving it behind.\n\r", ch); make_corpse(ch); xCLEAR_BITS(ch->pcdata->perm_aff); xSET_BIT(ch->pcdata->perm_aff, AFF_ETHEREAL); xSET_BIT(ch->pcdata->perm_aff, AFF_MAGICAL); xSET_BIT(ch->pcdata->perm_aff, AFF_NO_CORPSE); break; } } void draw_rune(CHAR_DATA *ch, ROOM_INDEX_DATA *room, int type) { OBJ_DATA *obj; if (IS_SET(ch->in_room->room_flags, ROOM_NO_MAGIC)) { ch_trick(ch, type); return; } switch (type) { default: ch_trick(ch, type); break; case MAG_HOLY: if (ch->curr_talent[TAL_HEALING] < 100) { ch_trick(ch, type); break; } act(AT_WHITE, "You trace runes of life on the walls.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "$n traces glowing white runes on the walls.", ch, NULL, NULL, TO_ROOM); SET_BIT(room->runes, RUNE_LIFE); break; case MAG_DREAM: if (ch->curr_talent[TAL_DREAM] < 100) { ch_trick(ch, type); break; } act(AT_PINK, "You trace runes of distraction on the walls.", ch, NULL, NULL, TO_CHAR); act(AT_PINK, "$n traces glowing pink runes on the walls.", ch, NULL, NULL, TO_ROOM); SET_BIT(room->runes, RUNE_DISTRACT); break; case MAG_ENERGY: if (ch->curr_talent[TAL_SECURITY] < 100) { ch_trick(ch, type); break; } act(AT_CYAN, "You trace runes of warding on the walls.", ch, NULL, NULL, TO_CHAR); act(AT_CYAN, "$n traces glowing cyan runes on the walls.", ch, NULL, NULL, TO_ROOM); SET_BIT(room->runes, RUNE_WARD); break; case MAG_TELEKINETIC: if (ch->curr_talent[TAL_MOTION] < 65) { ch_trick(ch, type); break; } act(AT_YELLOW, "You trace a yellow rune on the floor.", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n traces a yellow rune on the floor.", ch, NULL, NULL, TO_ROOM); obj = create_object(get_obj_index(87), 0); obj = obj_to_room(obj, room); obj->obj_by = STRALLOC(ch->name); break; case MAG_ANTIMAGIC: if (ch->curr_talent[TAL_VOID] < 50) { ch_trick(ch, type); break; } act(AT_MAGIC, "You wave your hands, dispelling any enchantments on the room.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n has dispelled the room!", ch, NULL, NULL, TO_ROOM); ch->in_room->runes = 0; break; } } void obj_enhance(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) { bool found; AFFECT_DATA *paf; int amount; if (obj->mana < 50) { obj_trick(ch, obj, type); return; } amount = obj->mana / 50; amount = UMIN(amount, power / 100); found = FALSE; switch (type) { default: obj_trick(ch, obj, type); return; case MAG_HOLY: if (obj->item_type != ITEM_ARMOR) { obj_trick(ch, obj, type); return; } amount = UMIN(amount, TALENT(ch, TAL_SECURITY) / 10 - obj->value[0] + obj->pIndexData->value[0]); if (amount > 0) { act(AT_WHITE, "You enhance the protective ability of $p.", ch, obj, NULL, TO_CHAR); obj->value[0] += amount; } else { obj_trick(ch, obj, type); return; } break; case MAG_EARTH: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CON && !found) { amount = UMIN(amount, TALENT(ch, TAL_EARTH) / 10 - paf->modifier); if (amount > 0) { act(AT_GREEN, "You enchant $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_EARTH) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_CON; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_GREEN, "You enchant $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); } break; case MAG_COLD: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_LCK && !found) { amount = UMIN(amount, TALENT(ch, TAL_FROST) / 10 - paf->modifier); if (amount > 0) { act(AT_FROST, "You enchant $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_FROST) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_LCK; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_FROST, "You enchant $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); } break; case MAG_FIRE: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_STR && !found) { amount = UMIN(amount, TALENT(ch, TAL_FIRE) / 10 - paf->modifier); if (amount > 0) { act(AT_FIRE, "You enchant $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_FIRE) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_STR; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_FIRE, "You enchant $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); } break; case MAG_SEEK: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CHA && !found) { amount = UMIN(amount, TALENT(ch, TAL_SEEKING) / 10 - paf->modifier); if (amount > 0) { act(AT_GREEN, "You enchant $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_SEEKING) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_CHA; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_GREEN, "You enchant $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); } break; case MAG_WIND: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DEX && !found) { amount = UMIN(amount, TALENT(ch, TAL_WIND) / 10 - paf->modifier); if (amount > 0) { act(AT_CYAN, "You enchant $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_WIND) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_DEX; paf->modifier = 1; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_CYAN, "You enchant $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); } break; case MAG_WATER: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_WIS && !found) { amount = UMIN(amount, TALENT(ch, TAL_WATER) / 10 - paf->modifier); if (amount > 0) { act(AT_BLUE, "You enchant $p with the power of Water.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_WATER) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_WIS; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_BLUE, "You enchant $p with the power of Water.", ch, obj, NULL, TO_CHAR); } break; case MAG_PSIONIC: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_INT && !found) { amount = UMIN(amount, TALENT(ch, TAL_MIND) / 10 - paf->modifier); if (amount > 0) { act(AT_PURPLE, "You enchant $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_INT; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_PURPLE, "You enchant $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); } break; case MAG_ELECTRICITY: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DAMROLL && !found) { amount = UMIN(amount, TALENT(ch, TAL_LIGHTNING) / 10 - paf->modifier); if (amount > 0) { act(AT_YELLOW, "You enchant $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_LIGHTNING) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_DAMROLL; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_YELLOW, "You enchant $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); } break; case MAG_TELEKINETIC: for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_HITROLL && !found) { amount = UMIN(amount, TALENT(ch, TAL_MOTION) / 10 - paf->modifier); if (amount > 0) { act(AT_YELLOW, "You enchant $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); paf->modifier += amount; } else { obj_trick(ch, obj, type); return; return; } found=TRUE; } } if (found==FALSE) { amount = UMIN(amount, TALENT(ch, TAL_MOTION) / 10); CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_HITROLL; paf->modifier = amount; xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_YELLOW, "You enchant $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); } break; } WAIT_STATE(ch, PULSE_VIOLENCE * amount); obj->mana -= 50 * amount; obj->cost += 50000 * amount; } /* obj_enhance */ void ch_enhance(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) { AFFECT_DATA af; SKILLTYPE *skill; int sn; switch (type) { default: ch_trick(victim, type); return; case MAG_FIRE: sn = gsn_fire; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_STR; af.modifier = TALENT(ch, TAL_FIRE)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_WATER: sn = gsn_water; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_WIS; af.modifier = TALENT(ch, TAL_WATER)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_COLD: sn = gsn_frost; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_LCK; af.modifier = TALENT(ch, TAL_FROST)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_EARTH: sn = gsn_earth; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_CON; af.modifier = TALENT(ch, TAL_EARTH)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_WIND: sn = gsn_wind; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_DEX; af.modifier = TALENT(ch, TAL_WIND)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_PSIONIC: sn = gsn_mind; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_INT; af.modifier = TALENT(ch, TAL_MIND)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_SEEK: sn = gsn_seeking; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_CHA; af.modifier = TALENT(ch, TAL_SEEKING)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_TELEKINETIC: sn = gsn_motion; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_HITROLL; af.modifier = TALENT(ch, TAL_MOTION)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_ELECTRICITY: sn = gsn_lightning; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_DAMROLL; af.modifier = TALENT(ch, TAL_LIGHTNING)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_HOLY: sn = gsn_security; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_AC; af.modifier = TALENT(ch, TAL_SECURITY)/10; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_DREAM: if (ch->curr_talent[TAL_DREAM] < 100) { ch_trick(victim, type); return; } sn = gsn_dream; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_IMMUNE; af.modifier = RIS_SLEEP; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_POISON: if (ch->curr_talent[TAL_HEALING] < 100) { ch_trick(victim, type); return; } sn = gsn_security; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_IMMUNE; af.modifier = RIS_POISON; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); break; case MAG_LIGHT: if (ch->curr_talent[TAL_ILLUSION] < 20) { ch_trick(victim, type); return; } sn = gsn_illusion; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_AFFECT; af.modifier = 0; af.bitvector = meb(AFF_GLOW); affect_join( victim, &af ); break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 20) { ch_trick(victim, type); return; } sn = gsn_death; if (is_affected(victim, sn)) { ch_trick(victim, type); return; } af.type = sn; af.duration = power*2; af.location = APPLY_AFFECT; af.modifier = 0; af.bitvector = meb(AFF_DARK); affect_join( victim, &af ); break; } skill = get_skilltype(sn); if (skill->hit_vict && skill->hit_vict[0] != '\0') act( AT_MAGIC, skill->hit_vict, victim, NULL, ch, TO_CHAR ); if (victim != ch && skill->hit_char && skill->hit_char[0] != '\0') act( AT_MAGIC, skill->hit_char, ch, NULL, victim, TO_CHAR ); if (skill->hit_room && skill->hit_room[0] != '\0') act( AT_MAGIC, skill->hit_room, ch, NULL, victim, TO_NOTVICT ); } void ch_sing(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power) { switch (type) { default: ch_trick(ch, type); break; } } void song_sing(CHAR_DATA *ch, int type, int power, char *argument) { switch (type) { default: ch_trick(ch, type); break; } } void obj_control(CHAR_DATA *ch, OBJ_DATA *obj, int type, int power) { OBJ_DATA *obj1; NATION_DATA *nation; char buf[MAX_STRING_LENGTH]; switch (type) { default: obj_trick(ch, obj, type); break; case MAG_UNHOLY: if (ch->curr_talent[TAL_DEATH] < 100) { obj_trick(ch, obj, type); break; } if (obj->item_type != ITEM_CORPSE_NPC) { obj_trick(ch, obj, type); break; } if (obj->obj_by == NULL || (nation = find_nation(obj->obj_by)) == NULL) { obj_trick(ch, obj, type); break; } if (!IS_AFFECTED(ch, AFF_ETHEREAL)) { obj_trick(ch, obj, type); break; } while ((obj1 = obj->first_content)) { obj_from_obj(obj1); if ( obj1->item_type == ITEM_MONEY ) { ch->gold += obj1->value[0]; extract_obj(obj1); } else { obj_to_char(obj1, ch); } } STRFREE(ch->last_taken); sprintf(buf, "possessing the %s", myobj(obj)); ch->last_taken = STRALLOC(buf); WAIT_STATE(ch, PULSE_VIOLENCE*12); separate_obj(obj); extract_obj(obj); ch->nation = nation; STRFREE(ch->species); ch->species = STRALLOC(nation->name); STRFREE(ch->pcdata->type); ch->pcdata->type = STRALLOC("living"); fix_char(ch); check_bodyparts(ch); xCLEAR_BITS(ch->pcdata->perm_aff); ch->position = POS_RESTING; act(AT_DGREY, "You take a deep breath and open your eyes.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "$n takes a deep breath and opens $s eyes.", ch, NULL, NULL, TO_ROOM); if ( get_timer( ch, TIMER_PKILLED ) > 0 ) remove_timer( ch, TIMER_PKILLED ); ch->mental_state = -100; send_to_char("You feel drained and exhausted by the possession.\n\r", ch); break; } } void ch_control(CHAR_DATA *victim, CHAR_DATA *ch, int type, int power, char *argument) { AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; int sn; switch (type) { default: ch_trick(victim, type); break; case MAG_PSIONIC: if (!IS_NPC(ch) && ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_SPEECH] < (IS_AFFECTED(ch, AFF_BEAUTY) ? 100 : 200)) { ch_trick(victim, type); break; } if ( victim == ch ) { send_to_char( "You like yourself even better!\n\r", ch ); return; } if ( IS_SET( victim->immune, RIS_MAGIC ) || IS_SET( victim->immune, RIS_CHARM ) || (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) ) { ch_trick(victim, type); break; } if (!IS_NPC(victim)) { send_to_char( "I don't think so...\n\r", ch ); send_to_char( "Someone is trying to charm you...\n\r", victim ); return; } if ( IS_AFFECTED(victim, AFF_CHARM) || IS_AFFECTED(ch, AFF_CHARM) || number_range(1, get_curr_wil(ch)) < get_curr_wil(victim) || circle_follow( victim, ch ) ) { act(AT_GREEN, "$N resists your attempts to tame $M.", ch, NULL, victim, TO_CHAR); act(AT_GREEN, "$n attempts to tame you, but you resist.", ch, NULL, victim, TO_VICT); return; } if ( victim->master ) stop_follower( victim ); add_follower( victim, ch ); af.type = -1; af.duration = number_fuzzy(get_curr_wil(ch)); af.location = 0; af.modifier = 0; af.bitvector = meb(AFF_CHARM); affect_to_char( victim, &af ); act(AT_GREEN, "You charm $N.", ch, NULL, victim, TO_CHAR); act(AT_GREEN, "You get the sudden urge to follow and obey $n.", ch, NULL, victim, TO_VICT); sprintf( buf, "%s has charmed %s.", ch->name, victim->name); to_channel( buf, "Spell", PERMIT_SECURITY ); break; case MAG_FIRE: if (ch->curr_talent[TAL_FIRE] < 50) { ch_trick(victim, type); return; } sn = gsn_fire; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_SUSCEPTIBLE; af.modifier = RIS_FIRE; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); send_to_char( "You are vulnerable to heat.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You make $N vulnerable to heat.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N is vulnerable to heat.", ch, NULL, victim, TO_NOTVICT); break; case MAG_COLD: if (ch->curr_talent[TAL_FROST] < 50) { ch_trick(victim, type); return; } sn = gsn_frost; if (is_affected(victim, sn)) { ch_trick(victim, type); break; } af.type = sn; af.duration = power; af.location = APPLY_SUSCEPTIBLE; af.modifier = RIS_COLD; xCLEAR_BITS(af.bitvector); affect_join( victim, &af ); update_pos(victim); send_to_char( "You are vulnerable to cold.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You make $N vulnerable to cold.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N is vulnerable to cold.", ch, NULL, victim, TO_NOTVICT); break; case MAG_WATER: if (ch->curr_talent[TAL_WATER] < 50) { ch_trick(victim, type); return; } sn = gsn_sticky_flame; if (!is_affected(victim, sn)) { ch_trick(victim, type); break; } affect_strip( victim, gsn_sticky_flame ); send_to_char( "The flames surrounding you are quenched.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You quench the flames surrounding $N.", ch, NULL, victim, TO_CHAR); } act( AT_MAGIC, "The flames surroudning $N are quenched.", ch, NULL, victim, TO_NOTVICT); break; } } void room_control(CHAR_DATA *ch, int type, int power, char *argument) { switch (type) { default: ch_trick(ch, type); break; case MAG_EARTH: if (ch->curr_talent[TAL_EARTH] < 20) { ch_trick(ch, type); return; } if (ch->in_room->curr_vegetation >= 100) { ch_trick(ch, type); return; } ch->in_room->curr_vegetation += 10; act( AT_GREEN, "At your command, vegetation flourishes in the room.", ch, NULL, NULL, TO_CHAR); act( AT_GREEN, "Vegetation flourishes in the room.", ch, NULL, NULL, TO_ROOM); break; case MAG_WATER: if (ch->curr_talent[TAL_WATER] < 20) { ch_trick(ch, type); return; } if(ch->in_room->curr_water >= 100) { ch_trick(ch, type); return; } ch->in_room->curr_water += 10; act( AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_CHAR); act( AT_BLUE, "Water floods into the room!", ch, NULL, NULL, TO_ROOM); break; } } /* Check the verb for the spell */ int check_verb(char *argument) { if ( !str_cmp(argument, "tricks")) return ACT_TRICKS; else if ( !str_cmp(argument, "harm") || !str_cmp(argument, "hurt") || !str_cmp(argument, "damage") || !str_cmp(argument, "destroy") || !str_cmp(argument, "slay") || !str_cmp(argument, "attack") || !str_cmp(argument, "kill") || !str_cmp(argument, "burn")) return ACT_HARM; else if ( !str_cmp(argument, "help") || !str_cmp(argument, "assist") || !str_cmp(argument, "cure") || !str_cmp(argument, "heal") || !str_cmp(argument, "aid") || !str_cmp(argument, "restore") || !str_cmp(argument, "revive")) return ACT_HELP; else if ( !str_cmp(argument, "hinder") || !str_cmp(argument, "slow") || !str_cmp(argument, "stop") || !str_cmp(argument, "halt") || !str_cmp(argument, "anchor") || !str_cmp(argument, "curse") || !str_cmp(argument, "reduce") || !str_cmp(argument, "immobilize")) return ACT_HINDER; else if ( !str_cmp(argument, "create") || !str_cmp(argument, "conjure") || !str_cmp(argument, "shape") || !str_cmp(argument, "form") || !str_cmp(argument, "make") || !str_cmp(argument, "summon") || !str_cmp(argument, "bring") || !str_cmp(argument, "fashion")) return ACT_CREATE; else if ( !str_cmp(argument, "seek") || !str_cmp(argument, "find") || !str_cmp(argument, "identify") || !str_cmp(argument, "examine") || !str_cmp(argument, "locate") || !str_cmp(argument, "watch") || !str_cmp(argument, "discover")) return ACT_FIND; else if ( !str_cmp(argument, "move") || !str_cmp(argument, "send") || !str_cmp(argument, "transfer") || !str_cmp(argument, "shift") || !str_cmp(argument, "travel") || !str_cmp(argument, "push") || !str_cmp(argument, "transport")) return ACT_MOVE; else if ( !str_cmp(argument, "change") || !str_cmp(argument, "alter") || !str_cmp(argument, "transform") || !str_cmp(argument, "morph") || !str_cmp(argument, "transmute") || !str_cmp(argument, "mutate")) return ACT_CHANGE; else if ( !str_cmp(argument, "enhance") || !str_cmp(argument, "enchant") || !str_cmp(argument, "bless") || !str_cmp(argument, "improve") || !str_cmp(argument, "strengthen") || !str_cmp(argument, "imbue")) return ACT_ENHANCE; else if ( !str_cmp(argument, "focus") || !str_cmp(argument, "brand") || !str_cmp(argument, "shield") || !str_cmp(argument, "protect") || !str_cmp(argument, "bind") || !str_cmp(argument, "circle")) return ACT_FOCUS; else if ( !str_cmp(argument, "rune") || !str_cmp(argument, "area") || !str_cmp(argument, "room") || !str_cmp(argument, "sigil") || !str_cmp(argument, "symbol") || !str_cmp(argument, "mark")) return ACT_RUNE; else if ( !str_cmp(argument, "sing") || !str_cmp(argument, "song") || !str_cmp(argument, "music") || !str_cmp(argument, "speak") || !str_cmp(argument, "play")) return ACT_SING; else if ( !str_cmp(argument, "control") || !str_cmp(argument, "charm") || !str_cmp(argument, "order") || !str_cmp(argument, "force") || !str_cmp(argument, "compel")) return ACT_CONTROL; else return ACT_TRICKS; } /* Check the power on the spell */ int check_power(char *argument) { if (!str_cmp(argument, "miniscule")) return 10; else if (!str_cmp(argument, "tiny")) return 20; else if (!str_cmp(argument, "weak")) return 30; else if (!str_cmp(argument, "low")) return 50; else if (!str_cmp(argument, "small")) return 80; else if (!str_cmp(argument, "medium")) return 100; else if (!str_cmp(argument, "moderate")) return 200; else if (!str_cmp(argument, "intermediate")) return 300; else if (!str_cmp(argument, "high")) return 400; else if (!str_cmp(argument, "strong")) return 500; else if (!str_cmp(argument, "great")) return 600; else if (!str_cmp(argument, "large")) return 700; else if (!str_cmp(argument, "mighty")) return 800; else if (!str_cmp(argument, "huge")) return 900; else if (!str_cmp(argument, "powerful")) return 1000; else if (!str_cmp(argument, "deadly")) return 1100; else if (!str_cmp(argument, "massive")) return 1200; else if (!str_cmp(argument, "enormous")) return 1300; else if (!str_cmp(argument, "gargantuan")) return 1400; else if (!str_cmp(argument, "collosal")) return 1500; else if (!str_cmp(argument, "extreme")) return 1600; else if (!str_cmp(argument, "amazing")) return 1700; else if (!str_cmp(argument, "incredible")) return 1800; else if (!str_cmp(argument, "severe")) return 1900; else if (!str_cmp(argument, "intense")) return 2000; else if (!str_cmp(argument, "supreme")) return 2500; else if (!str_cmp(argument, "ultimate")) return 3000; else if (!str_cmp(argument, "godlike")) return 3500; else if (!str_cmp(argument, "omnipotent")) return 3800; else if (!str_cmp(argument, "godly")) return 4000; else return -1; } /* Return true if they are mentally capable of concentrating */ bool check_concentration(CHAR_DATA *ch, int type, int action, int power) { AFFECT_DATA af; int sn; if (number_percent() - 5 > ch->pcdata->condition[COND_DRUNK] + abs(ch->mental_state)) return TRUE; switch(number_range(1,3)) { default: if (type == MAG_FIRE) { sn = gsn_sticky_flame; if (is_affected(ch, sn)) { ch_trick(ch, type); break; } af.type = sn; af.duration = power/10; af.location = APPLY_DAMROLL; af.modifier = TALENT(ch, TAL_FIRE)/40; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_FLAMING); affect_join(ch, &af); act(AT_FIRE, "You set yourself on fire!", ch, NULL, NULL, TO_CHAR); act(AT_FIRE, "$n sets $mself on fire!", ch, NULL, NULL, TO_ROOM); } else if (type == MAG_LIGHT) { sn = gsn_blindness; if (is_affected(ch, sn)) { ch_trick(ch, type); break; } if (IS_AFFECTED(ch, AFF_TRUESIGHT)) { ch_trick(ch, type); break; } af.type = sn; af.duration = power/10; af.location = APPLY_HITROLL; af.modifier = -1 * TALENT(ch, TAL_ILLUSION)/20; xCLEAR_BITS(af.bitvector); xSET_BIT(af.bitvector, AFF_FLAMING); affect_join(ch, &af); act(AT_YELLOW, "You are blinded!", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n blinds $mself!", ch, NULL, NULL, TO_ROOM); } else if (action == ACT_CREATE) { act(AT_WHITE, "You are covered in confetti.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "$n is covered in confetti.", ch, NULL, NULL, TO_ROOM); break; } else { ch_trick(ch, type); break; } break; case 1: huh(ch); break; case 2: ch_trick(ch, type); break; } return FALSE; } /* The big magic command and handler. Parses their input, * tries to figure out what they're trying to do, and * directs the results to the appropriate function above. */ void do_magic(CHAR_DATA *ch, char *argument) { int talent; int damage; int power; int action; CHAR_DATA *victim; CHAR_DATA *next_vict; OBJ_DATA *obj; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char arg3[MAX_INPUT_LENGTH]; char arg4[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch)) return; if (check_manastorm(ch)) return; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument_retain_case(argument, arg3); argument = one_argument_retain_case(argument, arg4); talent = TAL_CATALYSM; damage = MAG_ALL; power = 1; action = ACT_TRICKS; /* First argument, a Talent */ if (!str_cmp(arg1, "fire") || !str_cmp(arg1, "flame") || !str_cmp(arg1, "flames")) { act(AT_FIRE, "$n begins to channel Fire Magic.", ch, NULL, NULL, TO_ROOM); act(AT_FIRE, "You begin to channel Fire Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_FIRE; damage = MAG_FIRE; } else if (!str_cmp(arg1, "burn") || !str_cmp(arg1, "incinerate") || !str_cmp(arg1, "scorch")) { act(AT_GREEN, "$n begins to channel Fire Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Fire Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_FIRE; damage = MAG_FIRE; action = ACT_HARM; } else if (!str_cmp(arg1, "earth") || !str_cmp(arg1, "nature") || !str_cmp(arg1, "leaves")) { act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_EARTH; damage = MAG_EARTH; } else if (!str_cmp(arg1, "stone") || !str_cmp(arg1, "dirt") || !str_cmp(arg1, "soil") || !str_cmp(arg1, "rock")) { act(AT_ORANGE, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM); act(AT_ORANGE, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_EARTH; damage = MAG_BLUNT; } else if (!str_cmp(arg1, "crush")) { act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_EARTH; damage = MAG_BLUNT; action = ACT_HARM; } else if (!str_cmp(arg1, "tangle") || !str_cmp(arg1, "entangle")) { act(AT_GREEN, "$n begins to channel Earth Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Earth Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_EARTH; damage = MAG_EARTH; action = ACT_HINDER; } else if (!str_cmp(arg1, "lightning") || !str_cmp(arg1, "electric") || !str_cmp(arg1, "electricity")) { act(AT_YELLOW, "$n begins to channel Lightning Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Lightning Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_LIGHTNING; damage = MAG_ELECTRICITY; } else if (!str_cmp(arg1, "shock") || !str_cmp(arg1, "electrocute") || !str_cmp(arg1, "zap")) { act(AT_YELLOW, "$n begins to channel Lightning Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Lightning Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_LIGHTNING; damage = MAG_ELECTRICITY; action = ACT_HARM; } else if (!str_cmp(arg1, "wind") || !str_cmp(arg1, "air") || !str_cmp(arg1, "storm") || !str_cmp(arg1, "storms")) { act(AT_CYAN, "$n begins to channel Wind Magic.", ch, NULL, NULL, TO_ROOM); act(AT_CYAN, "You begin to channel Wind Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_WIND; damage = MAG_WIND; } else if (!str_cmp(arg1, "frost") || !str_cmp(arg1, "ice") || !str_cmp(arg1, "cold") || !str_cmp(arg1, "snow")) { act(AT_FROST, "$n begins to channel Frost Magic.", ch, NULL, NULL, TO_ROOM); act(AT_FROST, "You begin to channel Frost Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_FROST; damage = MAG_COLD; } else if (!str_cmp(arg1, "chill") || !str_cmp(arg1, "freeze")) { act(AT_FROST, "$n begins to channel Frost Magic.", ch, NULL, NULL, TO_ROOM); act(AT_FROST, "You begin to channel Frost Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_FROST; damage = MAG_COLD; action = ACT_HARM; } else if (!str_cmp(arg1, "water") || !str_cmp(arg1, "bubbles") || !str_cmp(arg1, "sea") || !str_cmp(arg1, "ocean")) { act(AT_BLUE, "$n begins to channel Water Magic.", ch, NULL, NULL, TO_ROOM); act(AT_BLUE, "You begin to channel Water Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_WATER; damage = MAG_WATER; } else if (!str_cmp(arg1, "acid")) { act(AT_DGREEN, "$n begins to channel Acid Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREEN, "You begin to channel Acid Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_WATER; damage = MAG_ACID; } else if (!str_cmp(arg1, "dream") || !str_cmp(arg1, "sleep") || !str_cmp(arg1, "nightmare")) { act(AT_PINK, "$n begins to channel Dream Magic.", ch, NULL, NULL, TO_ROOM); act(AT_PINK, "You begin to channel Dream Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_DREAM; damage = MAG_DREAM; } else if (!str_cmp(arg1, "illusion") || !str_cmp(arg1, "light")) { act(AT_YELLOW, "$n begins to channel Light Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Light Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_ILLUSION; damage = MAG_LIGHT; } else if (!str_cmp(arg1, "speech") || !str_cmp(arg1, "sound") || !str_cmp(arg1, "song") || !str_cmp(arg1, "sonics")) { act(AT_PINK, "$n begins to channel Speech Magic.", ch, NULL, NULL, TO_ROOM); act(AT_PINK, "You begin to channel Speech Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_SPEECH; damage = MAG_SOUND; } else if (!str_cmp(arg1, "healing") || !str_cmp(arg1, "life") || !str_cmp(arg1, "holy")) { act(AT_WHITE, "$n begins to channel Holy Magic.", ch, NULL, NULL, TO_ROOM); act(AT_WHITE, "You begin to channel Holy Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_HEALING; damage = MAG_HOLY; } else if (!str_cmp(arg1, "heal") || !str_cmp(arg1, "cure")) { act(AT_WHITE, "$n begins to channel Healing Magic.", ch, NULL, NULL, TO_ROOM); act(AT_WHITE, "You begin to channel Healing Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_HEALING; damage = MAG_HOLY; action = ACT_HELP; } else if (!str_cmp(arg1, "unholy") || !str_cmp(arg1, "shadow")) { act(AT_DGREY, "$n begins to channel Shadow Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to channel Shadow Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_DEATH; damage = MAG_UNHOLY; } else if (!str_cmp(arg1, "drain")) { act(AT_DGREY, "$n begins to channel Death Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to channel Death Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_DEATH; damage = MAG_DRAIN; action = ACT_HARM; } else if (!str_cmp(arg1, "death")) { act(AT_DGREY, "$n begins to channel Death Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to channel Death Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_DEATH; damage = MAG_DRAIN; } else if (!str_cmp(arg1, "venom") || !str_cmp(arg1, "poison")) { act(AT_DGREEN, "$n begins to channel Poison Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREEN, "You begin to channel Poison Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_DEATH; damage = MAG_POISON; } else if (!str_cmp(arg1, "changing") || !str_cmp(arg1, "chaos")) { act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM); act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_CHANGE; damage = MAG_CHANGE; } else if (!str_cmp(arg1, "distort")) { act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM); act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_CHANGE; damage = MAG_CHANGE; action = ACT_HARM; } else if (!str_cmp(arg1, "change") || !str_cmp(arg1, "alter") || !str_cmp(arg1, "morph")) { act(AT_ORANGE, "$n begins to channel Change Magic.", ch, NULL, NULL, TO_ROOM); act(AT_ORANGE, "You begin to channel Change Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_CHANGE; damage = MAG_CHANGE; action = ACT_CHANGE; } else if (!str_cmp(arg1, "time") || !str_cmp(arg1, "chronomancy") || !str_cmp(arg1, "prophecy")) { act(AT_DBLUE, "$n begins to channel Time Magic.", ch, NULL, NULL, TO_ROOM); act(AT_DBLUE, "You begin to channel Time Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_TIME; damage = MAG_TIME; } else if (!str_cmp(arg1, "mind") || !str_cmp(arg1, "psi") || !str_cmp(arg1, "psionics")) { act(AT_PURPLE, "$n begins to channel Mind Magic.", ch, NULL, NULL, TO_ROOM); act(AT_PURPLE, "You begin to channel Mind Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_MIND; damage = MAG_PSIONIC; } else if (!str_cmp(arg1, "motion") || !str_cmp(arg1, "telekinesis") || !str_cmp(arg1, "movement")) { act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_MOTION; damage = MAG_TELEKINETIC; } else if (!str_cmp(arg1, "travel") || !str_cmp(arg1, "teleport") || !str_cmp(arg1, "send")) { act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_MOTION; damage = MAG_TELEKINETIC; action = ACT_MOVE; } else if (!str_cmp(arg1, "recall") || !str_cmp(arg1, "return") || !str_cmp(arg1, "nexus")) { act(AT_YELLOW, "$n begins to channel Motion Magic.", ch, NULL, NULL, TO_ROOM); act(AT_YELLOW, "You begin to channel Motion Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_MOTION; damage = MAG_PSIONIC; action = ACT_MOVE; } else if (!str_cmp(arg1, "seeking") || !str_cmp(arg1, "finding") || !str_cmp(arg1, "divination")) { act(AT_GREEN, "$n begins to channel Seeking Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Seeking Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_SEEKING; damage = MAG_SEEK; } else if (!str_cmp(arg1, "seek") || !str_cmp(arg1, "find") || !str_cmp(arg1, "divine") || !str_cmp(arg1, "locate")) { act(AT_GREEN, "$n begins to channel Seeking Magic.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You begin to channel Seeking Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_SEEKING; damage = MAG_SEEK; action = ACT_FIND; } else if (!str_cmp(arg1, "security") || !str_cmp(arg1, "binding") || !str_cmp(arg1, "protection")) { act(AT_WHITE, "$n begins to channel Security Magic.", ch, NULL, NULL, TO_ROOM); act(AT_WHITE, "You begin to channel Security Magic.", ch, NULL, NULL, TO_CHAR); talent = TAL_SECURITY; damage = MAG_HOLY; } else if (!str_cmp(arg1, "void") || !str_cmp(arg1, "anti") || !str_cmp(arg1, "antimatter")) { act(AT_DGREY, "$n begins to channel antimatter.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to channel antimatter.", ch, NULL, NULL, TO_CHAR); talent = TAL_VOID; damage = MAG_ANTIMATTER; } else if (!str_cmp(arg1, "ether")) { act(AT_DGREY, "$n begins to draw upon ether.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to draw upon ether.", ch, NULL, NULL, TO_CHAR); talent = TAL_VOID; damage = MAG_ETHER; } else if (!str_cmp(arg1, "antimagic") || !str_cmp(arg1, "dispel")) { act(AT_DGREY, "$n begins to channel antimagic.", ch, NULL, NULL, TO_ROOM); act(AT_DGREY, "You begin to channel antimagic.", ch, NULL, NULL, TO_CHAR); talent = TAL_VOID; damage = MAG_ANTIMAGIC; } else if (!str_cmp(arg1, "catalysm") || !str_cmp(arg1, "mana") || !str_cmp(arg1, "magic")) { act(AT_PURPLE, "$n begins to channel raw mana.", ch, NULL, NULL, TO_ROOM); act(AT_PURPLE, "You begin to channel raw mana.", ch, NULL, NULL, TO_CHAR); talent = TAL_CATALYSM; damage = MAG_ALL; } else if (!str_cmp(arg1, "energy") || !str_cmp(arg1, "power") || !str_cmp(arg1, "force")) { act(AT_PURPLE, "$n begins to channel raw energy.", ch, NULL, NULL, TO_ROOM); act(AT_PURPLE, "You begin to channel raw energy.", ch, NULL, NULL, TO_CHAR); talent = TAL_CATALYSM; damage = MAG_ENERGY; } else if (!str_cmp(arg1, "swords") || !str_cmp(arg1, "blades") || !str_cmp(arg1, "blade") || !str_cmp(arg1, "sword")) { act(AT_PLAIN, "$n begins to dance with magic swords.", ch, NULL, NULL, TO_ROOM); act(AT_PLAIN, "You begin to dance with magic swords.", ch, NULL, NULL, TO_CHAR); talent = TAL_CATALYSM; damage = MAG_SLASH; } else if (!str_cmp(arg1, "daggers") || !str_cmp(arg1, "dagger") || !str_cmp(arg1, "knife") || !str_cmp(arg1, "knives")) { act(AT_PLAIN, "$n begins to juggle magic daggers.", ch, NULL, NULL, TO_ROOM); act(AT_PLAIN, "You begin to juggle magic daggers.", ch, NULL, NULL, TO_CHAR); talent = TAL_CATALYSM; damage = MAG_PIERCE; } else { act(AT_PURPLE, "$n begins to channel raw mana.", ch, NULL, NULL, TO_ROOM); act(AT_PURPLE, "You begin to channel raw mana.", ch, NULL, NULL, TO_CHAR); talent = TAL_CATALYSM; damage = MAG_ALL; if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); strcpy(arg3,arg2); strcpy(arg2,arg1); } /* Examine the second argument. * Power and verb are interchangable, so we have to check both. */ if (action == ACT_TRICKS) { if (arg2 && (action = check_verb(arg2)) == ACT_TRICKS) { if (power < 10) { if (arg2 && (power = check_power(arg2)) == -1) { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); strcpy(arg3,arg2); } } else { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(argument,buf); strcpy(arg4,arg3); strcpy(arg3,arg2); } } } else { if (power < 10) { if (arg2 && (power = check_power(arg2)) == -1) { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); strcpy(arg3,arg2); } } else { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); strcpy(arg3,arg2); } } /* Examine the third argument. Again, power and verb. */ if (power < 10) { if (arg3 && (power = check_power(arg3)) == -1) { if (action == ACT_TRICKS) { if (arg3 && (action = check_verb(arg3)) == ACT_TRICKS) { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); } } else { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); } } } else { if (action == ACT_TRICKS) { if (arg3 && (action = check_verb(arg3)) == ACT_TRICKS) { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); } } else { if (argument && argument[0] != '\0' && argument[0] != ' ') { sprintf(buf, "%s %s", arg4, argument); strcpy(argument,buf); } else { strcpy(argument,arg4); } strcpy(arg4,arg3); } } if (power < 10) power = 10; if (!check_concentration(ch, damage, action, power)) return; if (damage == MAG_SOUND && IS_SILENT(ch)) { send_to_char("No sound comes out.\n\r", ch); return; } /* Fourth arguemnt, handle and find an appropriate target */ switch (action) { default: if (!str_cmp(arg4, "all")) { for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) { ch_trick(victim, damage); } } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_trick(victim, damage); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_trick(ch, obj, damage); } else { ch_trick(ch, damage); } break; case ACT_HARM: if (!str_cmp(arg4, "all")) { for (victim = ch->in_room->first_person;victim;victim=next_vict) { next_vict = victim->next_in_room; if (ch == victim) continue; ch_harm(victim, ch, power, damage, FALSE); } } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_harm(victim, ch, power, damage, FALSE); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_harm(ch, obj, damage, power); } else if (IS_FIGHTING(ch)) { ch_harm(ch->last_hit, ch, power, damage, FALSE); } else { ch_trick(ch, damage); } break; case ACT_HELP: if (!str_cmp(arg4, "all")) { for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) { ch_help(victim, ch, damage, power/2); } } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_help(victim, ch, damage, power); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_help(ch, obj, damage, power); } else { ch_help(ch, ch, damage, power); } break; case ACT_HINDER: if (!str_cmp(arg4, "all")) { for (victim = ch->in_room->first_person;victim;victim=victim->next_in_room) { if (ch == victim) continue; ch_hinder(victim, ch, damage, power/2); } } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_hinder(victim, ch, damage, power); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_hinder(ch, obj, damage); } else { room_hinder(ch, ch->in_room, damage, power, arg4); } break; case ACT_CREATE: learn_talent(ch, TAL_CATALYSM); if (damage == MAG_ETHER && ch->curr_talent[TAL_VOID] >= 100) { void_create(ch, power, arg4); } else if (damage == MAG_DREAM && ch->curr_talent[TAL_DREAM] >= 30) { dream_create(ch, power, arg4, argument); } else { obj_create(ch, damage, power, arg4); } break; case ACT_FIND: learn_talent(ch, TAL_SEEKING); if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_find(ch, obj, damage); } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_find(victim, ch, damage); } else { seek_find(ch, damage, arg4); } break; case ACT_FOCUS: if ((victim = get_char_room(ch, arg4)) != NULL) { ch_focus(victim, ch, damage, power); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_focus(ch, obj, damage); } else { ch_focus(ch, ch, damage, power); } break; case ACT_MOVE: learn_talent(ch, TAL_MOTION); if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_move(ch, obj, damage, power, argument); } else if ((victim = get_char_room(ch, arg4)) != NULL) { ch_move(victim, ch, damage, arg4, argument); } else if (!arg4 || arg4[0] == '\0') { ch_move(ch, ch, damage, arg4, argument); } else { summon_move(ch, damage, power, arg4); } break; case ACT_CHANGE: if ((victim = get_char_room(ch, arg4)) != NULL) { ch_change(victim, ch, damage, argument); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_change(ch, obj, damage, power, argument); } else { ch_change(ch, ch, damage, argument); } break; case ACT_ENHANCE: if ((victim = get_char_room(ch, arg4)) != NULL) { ch_enhance(victim, ch, damage, power); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_enhance(ch, obj, damage, power); } else { ch_enhance(ch, ch, damage, power); } break; case ACT_RUNE: draw_rune(ch, ch->in_room, damage); break; case ACT_SING: if ((victim = get_char_room(ch, arg4)) != NULL) { ch_sing(victim, ch, damage, power); } else { song_sing(ch, damage, power, arg4); } break; case ACT_CONTROL: if ((victim = get_char_room(ch, arg4)) != NULL) { ch_control(victim, ch, damage, power, arg4); } else if ((obj = get_obj_here(ch, arg4)) != NULL) { obj_control(ch, obj, damage, power); } else { room_control(ch, damage, power, arg4); } break; } if (TALENT(ch, talent) >= 20) power /= ((TALENT(ch, talent)+100)/100); use_magic(ch, talent, power); STRFREE(ch->last_taken); ch->last_taken = STRALLOC("channeling"); WAIT_STATE(ch, power/100); }