/* * Talents * ======= * Abilities and handling * Written by Keolah and Triskal for Rogue Winds * * You may not use or distribute any of this code without the * explicit permission of the code maintainer, Heather Dunn (Keolah) */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #ifdef sun #include <strings.h> #endif #include <time.h> #include "mud.h" /* from birth.c */ extern void set_race(CHAR_DATA *ch, bool died); /* from handler.c */ extern SPECIES_DATA *find_species(char *name); extern char *munch_colors(char *word); /* from update.c */ extern void check_bodyparts(CHAR_DATA *ch); /* from interp.c */ extern bool check_social(CHAR_DATA *ch, char *command, char *argument); /* from mud_comm.c */ extern int get_color(char *argument); /* 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 bodyparts.c */ extern void add_part(CHAR_DATA *ch, int loc, int to_loc); /* from misc.c */ extern sh_int get_full(CHAR_DATA *ch); /* Trade in Talent points for Talents tradein <amount> <Talent name> */ void do_tradein(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; int amount; char arg[MAX_INPUT_LENGTH]; DEITY_DATA *talent; bool inborn; if (IS_NPC(ch)) { huh(ch); return; } if (!argument || argument[0] == '\0') { for (talent = first_deity; talent; talent = talent->next) { sprintf(buf, "&Y%-20s: %-3d &CCost per point: %d\r\n", talent->name, (ch->talent[talent->index] > 0 ? ch->talent[talent->index] : 0), talent->cost); send_to_char(buf, ch); } ch_printf(ch, "&YYou have %d points remaining to spend.\r\n", ch->pcdata->points); ch_printf(ch, "&YSyntax: tradein <# of points to raise> <talent to raise>&w\r\n"); ch_printf(ch, "&YSyntax: tradein <points> <attribute>\n\r"); ch_printf(ch, "&YSyntax: tradein inborn <talent>&w\n\r"); return; } argument = one_argument(argument, arg); inborn = FALSE; if (!str_cmp(arg, "inborn")) inborn = TRUE; else if (!is_number(arg)) { send_to_char("That isn't a number!\n\r", ch); return; } amount = atoi(arg); argument = one_argument(argument, arg); if (!arg || arg[0] == '\0') { send_to_char("Trade into what?\n\r", ch); return; } for (talent = first_deity; talent; talent = talent->next) { if ( toupper(arg[0]) == toupper(talent->name[0]) && !str_prefix( arg, talent->name ) ) break; } if (!talent && arg && arg[0] != '\0') { if (amount < 1) { send_to_char("You wish you could do that.\n\r", ch); return; } if (ch->pcdata->points < amount) { send_to_char("You don't have enough points for that.\n\r", ch); return; } if (!str_prefix(arg, "strength")) ch->perm_str += amount; else if (!str_prefix(arg, "dexterity")) ch->perm_dex += amount; else if (!str_prefix(arg, "constitution")) ch->perm_con += amount; else if (!str_prefix(arg, "willpower")) ch->perm_wis += amount; else if (!str_prefix(arg, "intelligence")) ch->perm_int += amount; else if (!str_prefix(arg, "perception")) ch->perm_cha += amount; else if (!str_prefix(arg, "endurance")) ch->perm_lck += amount; else { send_to_char("You know of no such Talent or attribute.\r\n", ch); return; } ch->pcdata->points -= amount; send_to_char("&YDone.\n\r", ch); return; } if (inborn) { if (ch->pcdata->inborn > -1) { send_to_char("You already have been inborn with a Talent.\n\r", ch); return; } else { ch_printf(ch, "You have been inborn with the %s Talent.\n\r", talent->name); ch->pcdata->inborn = talent->index; return; } } if (amount * talent->cost > ch->pcdata->points) { send_to_char("You don't have that many points to spend.\r\n", ch); return; } if (amount < 1) { send_to_char("You'd like to do that, wouldn't you?\r\n", ch); return; } if (ch->talent[talent->index] + amount > 200) { send_to_char("You may only raise a Talent to 200 points.\r\n", ch); return; } if (ch->talent[talent->index] < 0) ch->talent[talent->index] = 0; if (ch->curr_talent[talent->index] < 0) ch->curr_talent[talent->index] = 1; ch->pcdata->points -= amount * talent->cost; ch->talent[talent->index] += amount; talent->count += amount; save_deity(talent); ch_printf(ch, "Your %s power raises by %d to %d.\r\n", talent->name, amount, ch->talent[talent->index]); } /* see if they can travel to the victim -keo */ bool can_travel(int i, CHAR_DATA *ch, CHAR_DATA *victim) { if (TALENT(ch, TAL_MOTION) >= 200) return TRUE; if (!ch->in_room || (IS_SET(ch->in_room->room_flags, ROOM_NO_SUMMON) && (TALENT(ch, TAL_MOTION) < i || IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS) || IS_SET(ch->in_room->runes, RUNE_WARD))) || (IS_SET(victim->in_room->room_flags, ROOM_NO_ASTRAL) && (TALENT(ch, TAL_MOTION) < i || IS_SET(victim->in_room->area->flags, AFLAG_NOBYPASS) || IS_SET(victim->in_room->runes, RUNE_WARD))) || (IS_AFFECTED(ch, AFF_DREAMWORLD) && IS_SET(victim->in_room->room_flags, ROOM_NO_DREAM)) || (ch != victim && !IS_NPC(ch) && TALENT(ch, TAL_SEEKING) < TALENT(victim, TAL_SECURITY) && !IS_NPC(victim) && IS_SET(victim->pcdata->flags, PCFLAG_NOSUMMON))) return FALSE; if (ch->curr_talent[TAL_MOTION] > 0) return TRUE; return FALSE; } /* I was very reluctant to make this command, but I'm sick of * doing it manually -keo */ void do_talent_advance(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char arg1[MAX_STRING_LENGTH]; int tal; int amt; argument = one_argument(argument, arg1); victim = get_char_world(ch, arg1); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } argument = one_argument(argument, arg1); if (!is_number(arg1) || !is_number(argument)) { ch_printf(ch, "&w%s, %s\n\r", arg1, argument); send_to_char("That's not a number.\n\r", ch); return; } else { tal = atoi(arg1); amt = atoi(argument); } if (tal > MAX_DEITY) { send_to_char("There is no such talent.\n\r", ch); return; } victim->curr_talent[tal] = amt; send_to_char("You change their magic.\n\r", ch); send_to_char("You feel your magic change.\n\r", victim); SET_BIT(victim->pcdata->flags, PCFLAG_CHEAT); } void do_deduct(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int amt; char arg2[MAX_STRING_LENGTH]; argument = one_argument(argument, arg2); victim = get_char_world(ch, arg2); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_NPC(victim) || IS_NPC(ch)) { send_to_char("Mobs have no use for talents.\n\r", ch); return; } if (victim == ch) { send_to_char("Awarding yourself? How conceited!\n\r", ch); return; } if (!is_number(argument)) { send_to_char("Invalid number of points.\n\r", ch); return; } amt = atoi(argument); ch_printf(ch, "You deduct %d talent points from %s.\n\r", amt, victim->name); ch_printf(victim, "You lose %d talent points!\n\r", amt); victim->pcdata->points -= amt; } void do_award(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int amt; char arg2[MAX_STRING_LENGTH]; argument = one_argument(argument, arg2); victim = get_char_world(ch, arg2); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_NPC(victim) || IS_NPC(ch)) { send_to_char("Mobs have no use for talents.\n\r", ch); return; } if (victim == ch) { send_to_char("Awarding yourself? How conceited!\n\r", ch); return; } if (!is_number(argument)) { send_to_char("Invalid number of points.\n\r", ch); return; } amt = atoi(argument); ch_printf(ch, "You award %s with %d talent points.\n\r", victim->name, amt); ch_printf(victim, "You gain %d talent points!\n\r", amt); victim->pcdata->points += amt; } /* sense use of magic in the room. the more magic being used, * the easier it is to detect -keo */ void sense_magic(CHAR_DATA *ch, int tal, int mana) { CHAR_DATA *rch; if (mana < 1) mana = 1; if (!ch->in_room) return; for (rch=ch->in_room->first_person;rch;rch=rch->next_in_room) { if (IS_NPC(rch)) continue; if (rch == ch) continue; if (mana > 1200 - TALENT(ch, TAL_SEEKING)*5) ch_printf(rch, "&BYou sense %s magic.\n\r", talent_name[tal]); } } void learn_talent(CHAR_DATA *ch, int tal) { if (IS_NPC(ch)) return; if (ch->curr_talent[tal] < 200 && ch->talent[tal] > 0) { ch->pcdata->talent_exp[tal] += (int) ch->exp / 5; ch->exp -= (int) ch->exp / 5; if (ch->pcdata->talent_exp[tal] + talent_exp(ch, ch->curr_talent[tal], tal) >= talent_exp(ch, ch->curr_talent[tal]+1, tal)) { ch->pcdata->talent_exp[tal] -= (talent_exp(ch, ch->curr_talent[tal]+1, tal) - talent_exp(ch, ch->curr_talent[tal], tal)); ch->curr_talent[tal]++; update_aris(ch); ch_printf(ch, "&BYou feel your skill at %s magic has improved.\n\r", talent_name[tal]); if (ch->curr_talent[tal] == 100) { ch_printf(ch, "&BYou have mastered the magic of %s.\n\r", talent_name[tal]); } if (ch->curr_talent[tal] == 200) { ch_printf(ch, "&BYou have truly mastered the magic of %s.\n\r", talent_name[tal]); } } } } void mana_from_char(CHAR_DATA *ch, int i) { ch->mana -= UMAX(0, i); ch->in_room->area->weather->mana += (int)i/100; if (ch->mana < -1000) { send_to_char("Your life force is drained into the spell!\n\r", ch); lose_hp(ch, i/10); } check_rebirth(ch, i); } void use_magic(CHAR_DATA *ch, int tal, int mana) { if (IS_NPC(ch)) return; mana -= ch->pcdata->noncombat[SK_CHANNEL]; if (number_range(1,5) == 1) learn_noncombat(ch, SK_CHANNEL); if (mana < 0) mana = 0; learn_talent(ch, tal); sense_magic(ch, tal, mana); if (ch->pcdata->magiclink) { mana_from_char(ch->pcdata->magiclink, mana/2); mana_from_char(ch, mana/2); } else mana_from_char(ch, mana); } CHAR_DATA *find_target(CHAR_DATA *ch, char *argument, bool offense) { CHAR_DATA *victim = NULL; if (!argument || argument[0] == '\0') { if (!offense) victim = ch; else if (ch->last_hit && ch->last_hit->in_room ? ch->last_hit->in_room == ch->in_room : FALSE) victim = ch->last_hit; } else { victim = get_char_room(ch, argument); } if (!victim || victim == NULL) { if (!offense && ch->curr_talent[TAL_MOTION] >= 100 && ch->curr_talent[TAL_SEEKING] >= 100) { victim = get_char_world(ch, argument); if (!victim) { send_to_char("You are unable to find anyone like that.\n\r", ch); return NULL; } } else { send_to_char("They aren't here.\n\r", ch); return NULL; } } if (!IS_SAME_PLANE(ch, victim)) { send_to_char("You can't seem to affect them.\n\r", ch); victim = NULL; } return victim; } void magic_damage(CHAR_DATA *victim, CHAR_DATA *ch, int dam, int type, int talent, bool dont_wait) { if (check_manastorm(ch)) return; if (!victim || victim == NULL) { send_to_char("Attack whom?\n\r", ch); return; } if (char_died(victim)) return; if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) 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 (IS_NPC(ch)) dam = get_curr_int(ch); use_magic(ch, talent, dam); 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 */ magic_damage(ch, victim, dam, type, talent, TRUE); return; } if (check_displacement(ch, victim)) return; if (check_antimagic(ch, victim)) return; dam = number_range(dam, dam*5); dam = URANGE(1, dam, 5000); dam = (100 - TALENT(victim, talent)) * dam / 100; 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 do_status(CHAR_DATA *ch, char *argument) { if (IS_NPC(ch)) { send_to_char("Don't worry about it, you're fine.\n\r", ch); return; } send_to_char("&BYour current status:\n\r", ch); if (ch->pcdata->condition[COND_FULL] == -1) ch_printf(ch, "You don't need to eat.\n\r"); else if (ch->pcdata->condition[COND_FULL] == 0) ch_printf(ch, "You are starving to death.\n\r"); else if (ch->pcdata->condition[COND_FULL] < get_full(ch)/5) ch_printf(ch, "You are really hungry.\n\r"); else if (ch->pcdata->condition[COND_FULL] < get_full(ch)/4) ch_printf(ch, "You are hungry.\n\r"); else if (ch->pcdata->condition[COND_FULL] < get_full(ch)/3) ch_printf(ch, "You are a mite peckish.\n\r"); if (ch->pcdata->condition[COND_THIRST] == -1) ch_printf(ch, "You don't need to drink.\n\r"); else if (ch->pcdata->condition[COND_THIRST] == 0) ch_printf(ch, "You are dying of thirst.\n\r"); else if (ch->pcdata->condition[COND_THIRST] < get_full(ch)/5) ch_printf(ch, "You are really thirsty.\n\r"); else if (ch->pcdata->condition[COND_THIRST] < get_full(ch)/4) ch_printf(ch, "You are thirsty.\n\r"); else if (ch->pcdata->condition[COND_THIRST] < get_full(ch)/3) ch_printf(ch, "You could use something to drink.\n\r"); if (ch->mental_state == 100) ch_printf(ch, "Reality is slipping away.\n\r"); else if (ch->mental_state > 50) ch_printf(ch, "You are hallucinating.\n\r"); else if (ch->mental_state > 0) ch_printf(ch, "You are light-headed.\n\r"); else if (ch->mental_state == -100) ch_printf(ch, "You can't keep your eyes open.\n\r"); else if (ch->mental_state < -50) ch_printf(ch, "You are extremely drousy.\n\r"); else if (ch->mental_state < 0) ch_printf(ch, "You are tired.\n\r"); if (ch->pcdata->condition[COND_DRUNK] > 50) ch_printf(ch, "You are drunk.\n\r"); else if (ch->pcdata->condition[COND_DRUNK] > 10) ch_printf(ch, "You are a bit tipsy.\n\r"); if (ch->pcdata->inborn == -1) ch_printf(ch, "You do not have an inborn Talent.\n\r"); else ch_printf(ch, "You have been inborn with the %s Talent.\n\r", talent_name[ch->pcdata->inborn]); if (ch->pcdata->consenting) ch_printf(ch, "You give consent to %s.\n\r", ch->pcdata->consenting->name); if (ch->pcdata->mindlink) ch_printf(ch, "You are mindlinked to %s.\n\r", ch->pcdata->mindlink->name); if (ch->pcdata->magiclink) ch_printf(ch, "Your magic is linked to %s.\n\r", ch->pcdata->magiclink->name); if (ch->shield) ch_printf(ch, "You are surrounded by a shield of %s.\n\r", magic_table[ch->shield]); if (ch->pcdata->were_race) { if (has_bodypart(ch, BP_RHAND)) { ch_printf(ch, "You are a were-%s.\n\r", ch->pcdata->were_race); } else { ch_printf(ch, "You are a were-%s.\n\r", ch->species); } } if (ch->pcdata->name_disguise) ch_printf(ch, "You are disguised as %s.\n\r", ch->pcdata->name_disguise); if (ch->singing) ch_printf(ch, "You are singing a song of %s.\n\r", song_name[ch->singing]); if (ch->pcdata->wizinvis) ch_printf(ch, "Invisibility &C[&W%s&C][&W%d&C]&B\n\r", xIS_SET(ch->act, PLR_WIZINVIS) ? "*" : " ", ch->pcdata->wizinvis); } void do_heal(CHAR_DATA *ch, char *argument) { PART_DATA *part; CHAR_DATA *victim; int amt; if (ch->curr_talent[TAL_HEALING] <= 0) { huh(ch); return; } victim = find_target(ch, argument, FALSE); if (!victim) return; if (IS_AFFECTED(victim, AFF_UNDEAD)) { magic_damage(victim, ch, TALENT(ch, TAL_HEALING)*3 + TALENT(ch, TAL_DEATH), MAG_DRAIN, TAL_HEALING, FALSE); return; } if (IS_AFFECTED(victim, AFF_CONSTRUCT)) { send_to_char("For some reason, that doesn't work.\n\r", ch); return; } 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); } amt = number_range(TALENT(ch, TAL_HEALING), TALENT(ch, TAL_HEALING)*5); /* take mana first so the bonus doesn't cost more */ use_magic(ch, TAL_HEALING, amt); if (IS_AFFECTED(ch, AFF_UNHOLY) && amt != 0) amt /= 2; if (IS_AFFECTED(ch, AFF_HOLY)) amt *= 2; if (victim == ch) amt *= 2; if (!IS_FIGHTING(ch)) amt *= 2; victim->hit += amt; 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) && amt > 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+amt/10); } } if (victim != ch && ch->curr_talent[TAL_DEATH] > 0) { amt = number_range(TALENT(ch, TAL_DEATH), TALENT(ch, TAL_DEATH)*5); mana_from_char(victim, amt); if (!IS_FIGHTING(ch)) amt *= 2; victim->hit += amt; } if (victim->hit > victim->max_hit) victim->hit = victim->max_hit; WAIT_STATE(ch, PULSE_VIOLENCE); } /* moved from skills.c and modified -keo */ void do_recall(CHAR_DATA *ch, char *argument) { int slot; int mem; ROOM_INDEX_DATA *location; if (ch->curr_talent[TAL_MOTION] <= 0) { huh(ch); return; } location = NULL; if (!argument || argument[0] == '\0') slot = 0; else slot = 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 { 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 mysteriously 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; } use_magic(ch, TAL_MOTION, ch->mount ? 50 : 25); 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"); WAIT_STATE(ch, PULSE_VIOLENCE); } /* Each attack command must find its own target so that some of them * can optionally do other things to the victim, such as mindflay's * affect on mentalstate -keo */ void do_burn(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; CHAR_DATA *victim; if (ch->curr_talent[TAL_FIRE] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_FIRE, "Flames fly from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FIRE, "Flames fly from $n's $t!", ch, hands(ch), NULL, TO_ROOM); if (!str_cmp(argument, "room") && ch->curr_talent[TAL_FIRE] >= 60) { if (ch->in_room->curr_vegetation < 10) { send_to_char("There is no vegetation here to burn.\n\r", ch); return; } if (ch->in_room->curr_water > 30) { send_to_char("The vegetation is too damp to burn.\n\r", ch); return; } use_magic(ch, TAL_FIRE, 300); 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); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, IS_UNDERWATER(ch) ? TALENT(ch, TAL_FIRE)/2 : TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); if (ch->curr_talent[TAL_FIRE] >= 50 && !IS_SET(victim->immune, RIS_FIRE) && !(IS_NPC(ch) && xIS_SET(ch->act, ACT_PACIFIST))) { af.type = gsn_sticky_flame; af.duration = 20; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = meb(AFF_FLAMING); affect_join( victim, &af ); } } void do_poisoncloud(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; AFFECT_DATA af; if (ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_WIND] < 200) { huh(ch); return; } act(AT_DGREEN, "A cloud of poisonous gas erupts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_DGREEN, "A cloud if poisonous gas erupts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); for ( victim=ch->in_room->first_person; victim; victim=next_vict ) { next_vict=victim->next_in_room; magic_damage(victim, ch, (TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_WIND)), MAG_POISON, TAL_DEATH, FALSE); if (char_died(ch)) return; if (ch->curr_talent[TAL_DEATH] >= 10 && !IS_SET(victim->immune, RIS_POISON)) { af.type = gsn_poison; af.duration = 20; af.location = APPLY_STR; af.modifier = -2; af.bitvector = meb(AFF_POISON); affect_join( victim, &af ); victim->mental_state = URANGE( 20, victim->mental_state, 100 ); } } } void do_quake(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; if ((ch->curr_talent[TAL_EARTH] < 20 && !IS_NPC(ch)) || IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR)) { huh(ch); return; } act(AT_HUNGRY, "The earth trembles at your command!", 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; magic_damage(victim, ch, TALENT(ch, TAL_EARTH), MAG_BLUNT, TAL_EARTH, FALSE); if (char_died(ch)) return; } } void do_telekinetics(CHAR_DATA *ch, char *argument) { int n; CHAR_DATA *victim; CHAR_DATA *next_vict; if (!IS_NPC(ch) && (ch->curr_talent[TAL_MOTION] < 20 || ch->curr_talent[TAL_MIND] < 10)) { huh(ch); return; } if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; learn_talent(ch, TAL_MIND); magic_damage(victim, ch, (ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_MOTION])/2, MAG_PSIONIC, TAL_MOTION, FALSE); } use_magic(ch, TAL_MOTION, n*TALENT(ch, TAL_MOTION)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_MIND); magic_damage(victim, ch, TALENT(ch, TAL_MIND) + TALENT(ch, TAL_MOTION), MAG_PSIONIC, TAL_MOTION, FALSE); } void do_sandstorm(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; CHAR_DATA *victim; CHAR_DATA *next_vict; int n=0; if (ch->curr_talent[TAL_WIND] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_ORANGE, "Blasting sand swirls from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_ORANGE, "Blasting sand swirls from $n's $t!", ch, hands(ch), NULL, TO_ROOM); if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; learn_talent(ch, TAL_EARTH); magic_damage(victim, ch, (TALENT(ch, TAL_WIND) + TALENT(ch, TAL_EARTH))/2, MAG_WIND, TAL_WIND, FALSE); } use_magic(ch, TAL_WIND, n*TALENT(ch, TAL_WIND)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_EARTH); magic_damage(victim, ch, TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_WIND), MAG_WIND, TAL_WIND, FALSE); if (number_range(50,300) < TALENT(ch, TAL_EARTH)) { af.type = gsn_blindness; af.duration = 20; af.location = APPLY_HITROLL; af.modifier = -2; af.bitvector = meb(AFF_BLIND); affect_join( victim, &af ); } } void do_magma(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; int n=0; if ((ch->curr_talent[TAL_EARTH] < 1 || ch->curr_talent[TAL_FIRE] < 1) && !IS_NPC(ch)) { huh(ch); return; } act(AT_FIRE, "Molten lava pours from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FIRE, "Molten lava pours from $n's $t!", ch, hands(ch), NULL, TO_ROOM); if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; learn_talent(ch, TAL_FIRE); magic_damage(victim, ch, (TALENT(ch, TAL_FIRE) + TALENT(ch, TAL_EARTH))/2, MAG_FIRE, TAL_EARTH, FALSE); } use_magic(ch, TAL_FIRE, n*TALENT(ch, TAL_FIRE)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_EARTH); magic_damage(victim, ch, TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); } void do_flare(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; int n=0; if (ch->curr_talent[TAL_ILLUSION] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_YELLOW, "Searing light radiates from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "Searing light radiates from $n's $t!", ch, hands(ch), NULL, TO_ROOM); if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; learn_talent(ch, TAL_CATALYSM); magic_damage(victim, ch, (TALENT(ch, TAL_CATALYSM) + TALENT(ch, TAL_ILLUSION))/2, MAG_LIGHT, TAL_ILLUSION, FALSE); } use_magic(ch, TAL_ILLUSION, n*TALENT(ch, TAL_ILLUSION)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_CATALYSM); magic_damage(victim, ch, TALENT(ch, TAL_CATALYSM) + TALENT(ch, TAL_ILLUSION), MAG_LIGHT, TAL_ILLUSION, FALSE); } void do_antimatter(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_VOID] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_DGREY, "Crackling black antimatter streams from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_DGREY, "Crackling black antimatter streams from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, TALENT(ch, TAL_VOID), MAG_ANTIMATTER, TAL_VOID, FALSE); } void do_chainlightning(CHAR_DATA *ch, char *argument) { int zaps; CHAR_DATA *victim = NULL; CHAR_DATA *next_vict = NULL; if (ch->curr_talent[TAL_LIGHTNING] < 50 && !IS_NPC(ch)) { huh(ch); return; } act(AT_YELLOW, "Chain lightning streaks from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "Chain lightning streaks from $n's $t!", ch, hands(ch), NULL, TO_ROOM); zaps = number_range(1, TALENT(ch, TAL_LIGHTNING)/25); if (ch->in_room->curr_water > 60) zaps *= 2; use_magic(ch, TAL_LIGHTNING, zaps*100); while (zaps--) { victim = next_vict; if (!next_vict) victim = ch->in_room->first_person; next_vict = victim->next_in_room; magic_damage(victim, ch, 100, MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } } void do_electrocute(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_LIGHTNING] + ch->curr_talent[TAL_WIND] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS) || ch->in_room->area->weather->precip < 100 || ch->in_room->area->weather->temp < 100) { send_to_char("The weather isn't stormy enough here to call lightning.\n\r", ch); return; } act(AT_YELLOW, "A dozen bolts of electricity merge in the sky and shoot down a powerful bolt!", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "A dozen bolts of electricity merge in the sky and shoot down a powerful bolt!", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, TALENT(ch, TAL_WIND) + TALENT(ch, TAL_LIGHTNING)*5, MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } void do_flamingrain(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; if (ch->curr_talent[TAL_FIRE] + ch->curr_talent[TAL_WIND] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) { send_to_char("You can't call flaming rain indoors.\n\r", ch); return; } act(AT_FIRE, "The sky turns red as fire rains from the heavens.", ch, NULL, NULL, TO_CHAR); act(AT_FIRE, "The sky turns red as fire rains from the heavens.", ch, NULL, NULL, TO_ROOM); for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; magic_damage(victim, ch, TALENT(ch, TAL_WIND) + TALENT(ch, TAL_FIRE) + ch->in_room->area->weather->temp, MAG_FIRE, TAL_FIRE, FALSE); } } void do_manastorm(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; if (ch->curr_talent[TAL_CATALYSM] + ch->curr_talent[TAL_WIND] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) { send_to_char("You can't call a manastorm indoors.\n\r", ch); return; } act(AT_PURPLE, "You make the energy rage in a manastorm!", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "The energy in the air rages in a manastorm!", ch, NULL, NULL, TO_ROOM); for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; magic_damage(victim, ch, TALENT(ch, TAL_WIND) + TALENT(ch, TAL_CATALYSM) + ch->in_room->area->weather->mana, MAG_ENERGY, TAL_CATALYSM, FALSE); } } void do_meteor(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_EARTH] + ch->curr_talent[TAL_VOID] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) { send_to_char("You can't call a meteor indoors.\n\r", ch); return; } act(AT_DGREY, "A meteor streaks from the sky!", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "A meteor streaks from the sky!", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, (TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_VOID))*2, MAG_BLUNT, TAL_EARTH, FALSE); } void do_sonics(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; if (ch->curr_talent[TAL_SPEECH] < 100 && !IS_NPC(ch)) { huh(ch); return; } if (ch->in_room->curr_water >= 100) { send_to_char("There is not enough air here.\n\r", ch); return; } act(AT_YELLOW, "You make the air vibrate loudly!", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "The very air seems to hum loudly!", ch, NULL, NULL, TO_ROOM); for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; learn_talent(ch, TAL_WIND); magic_damage(victim, ch, TALENT(ch, TAL_SPEECH) + TALENT(ch, TAL_MOTION) + TALENT(ch, TAL_WIND), MAG_SOUND, TAL_SPEECH, FALSE); } } void do_steam(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_WATER] + ch->curr_talent[TAL_FIRE] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_BLUE, "A burst of steam blasts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_BLUE, "A burst of steam blasts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_FIRE); magic_damage(victim, ch, (TALENT(ch, TAL_FIRE) + TALENT(ch, TAL_WATER))* (IS_UNDERWATER(ch) ? 2 : 1), MAG_FIRE, TAL_WATER, FALSE); } void do_blizzard(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; if (ch->curr_talent[TAL_FROST] + ch->curr_talent[TAL_WIND] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS) || ch->in_room->area->weather->precip < 50 || ch->in_room->area->weather->temp > -100) { send_to_char("The weather isn't right here to call a blizzard.\n\r", ch); return; } act(AT_FROST, "A swirling blizzard blasts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FROST, "A swirling blizzard blasts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; learn_talent(ch, TAL_WIND); magic_damage(victim, ch, (TALENT(ch, TAL_WIND) + TALENT(ch, TAL_FROST))*2, MAG_COLD, TAL_FROST, FALSE); } } void do_sunstroke(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_ILLUSION] + ch->curr_talent[TAL_FIRE] < 200 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS) || ch->in_room->area->weather->precip > 0 || time_info.hour<6 || time_info.hour>=18 || get_light_room(ch->in_room) < 0) { send_to_char("There isn't enough sunlight here.\n\r", ch); return; } act(AT_YELLOW, "Your $t beam a ray of searing sunlight!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "$n's $t beam a ray of searing sunlight!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_FIRE); magic_damage(victim, ch, (TALENT(ch, TAL_ILLUSION) + TALENT(ch, TAL_FIRE))*2, MAG_LIGHT, TAL_ILLUSION, FALSE); } void do_soulfire(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_FIRE] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_DGREY, "Black fire streaks from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_DGREY, "Black fire streaks from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (!IS_AFFECTED(victim, AFF_UNHOLY) && !IS_AFFECTED(victim, AFF_UNDEAD) && !IS_AFFECTED(victim, AFF_NONLIVING)) { learn_talent(ch, TAL_FIRE); magic_damage(victim, ch, (TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_FIRE))*1.5, MAG_UNHOLY, TAL_DEATH, FALSE); } else { act(AT_DGREY, "$N is unaffected.", ch, NULL, victim, TO_CHAR); } } void do_unholyblast(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_SECURITY] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_DGREY, "Unholy energy blasts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_DGREY, "Unholy energy blasts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_HOLY) || IS_AFFECTED(victim, AFF_ANGEL)) { learn_talent(ch, TAL_SECURITY); magic_damage(victim, ch, (TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_SECURITY))*2, MAG_UNHOLY, TAL_DEATH, FALSE); } else { act(AT_DGREY, "$N is unaffected.", ch, NULL, victim, TO_CHAR); } } void do_sworddance(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (IS_NPC(ch) || ch->curr_talent[TAL_TIME] + ch->curr_talent[TAL_VOID] + ch->curr_talent[TAL_CATALYSM] + ch->pcdata->weapon[SK_SWORD] < 200) { huh(ch); return; } if (!ch->main_hand || ch->main_hand->value[5] != SK_SWORD) { send_to_char("You must be holding a sword in your main hand to use the Sword Dance.\n\r", ch); return; } act(AT_WHITE, "You dance with the sword, and a dozen other swords dance with you.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "$n dances, a dozen whirling swords slashing around $n!", ch, NULL, NULL, TO_ROOM); lose_ep(ch, 100); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, ch->main_hand->value[2] + ch->pcdata->weapon[SK_SWORD] + ch->curr_talent[TAL_CATALYSM], MAG_SLASH, TAL_CATALYSM, FALSE); learn_talent(ch, TAL_VOID); learn_talent(ch, TAL_TIME); learn_weapon(ch, SK_SWORD); } void do_pyrokinetics(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_FIRE] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_BLUE, "Blazing blue psionic flames streak from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_BLUE, "Blazing blue psionic flames streak from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_CONSTRUCT) || IS_AFFECTED(victim, AFF_UNDEAD)) { magic_damage(victim, ch, TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); } else { learn_talent(ch, TAL_FIRE); magic_damage(victim, ch, (TALENT(ch, TAL_MIND) + TALENT(ch, TAL_FIRE))*2, MAG_PSIONIC, TAL_MIND, FALSE); learn_talent(ch, TAL_FIRE); } } void do_geyser(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_FIRE] + ch->curr_talent[TAL_WATER] + ch->curr_talent[TAL_EARTH] < 100 && !IS_NPC(ch)) { huh(ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR)) { send_to_char("There is no ground to make a geyser erupt from here.\n\r",ch); return; } act(AT_BLUE, "A geyser erupts from the ground!", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "A geyser erupts from the ground!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; learn_talent(ch, TAL_FIRE); learn_talent(ch, TAL_EARTH); magic_damage(victim, ch, TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_WATER) + TALENT(ch, TAL_FIRE), MAG_WATER, TAL_WATER, FALSE); } void do_brainshock(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_LIGHTNING] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_YELLOW, "A surge of psionic lightning bursts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "A surge of psionic lightning bursts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_CONSTRUCT) || IS_AFFECTED(victim, AFF_UNDEAD)) { magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } else { learn_talent(ch, TAL_LIGHTNING); magic_damage(victim, ch, (TALENT(ch, TAL_MIND) + TALENT(ch, TAL_LIGHTNING))*2, MAG_ELECTRICITY, TAL_MIND, FALSE); } } void do_smite(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_HEALING] + ch->curr_talent[TAL_LIGHTNING] + ch->curr_talent[TAL_SECURITY] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_WHITE, "Holy lightning erupts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_WHITE, "Holy lightning erupts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_UNHOLY) || IS_AFFECTED(victim, AFF_UNDEAD) || IS_AFFECTED(victim, AFF_DEMON)) { magic_damage(victim, ch, TALENT(ch, TAL_HEALING)*3 + (TALENT(ch, TAL_LIGHTNING) + TALENT(ch, TAL_SECURITY))*2, MAG_HOLY, TAL_HEALING, FALSE); learn_talent(ch, TAL_LIGHTNING); learn_talent(ch, TAL_SECURITY); } else { magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING)*2, MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } } void do_holyblast(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_HEALING] + ch->curr_talent[TAL_SECURITY] < 200 && !IS_NPC(ch)) { huh(ch); return; } act(AT_WHITE, "Holy energy blasts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_WHITE, "Holy energy blasts from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_UNHOLY) || IS_AFFECTED(victim, AFF_UNDEAD) || IS_AFFECTED(victim, AFF_DEMON)) { magic_damage(victim, ch, (TALENT(ch, TAL_HEALING) + TALENT(ch, TAL_SECURITY))*2, MAG_HOLY, TAL_HEALING, FALSE); learn_talent(ch, TAL_SECURITY); } else { act(AT_WHITE, "$N is unaffected.", ch, NULL, victim, TO_CHAR); } } void do_lightning(CHAR_DATA *ch, char *argument) { OBJ_DATA *bullet; int amt; if (ch->curr_talent[TAL_LIGHTNING] < 30 && !IS_NPC(ch)) { huh(ch); return; } act(AT_YELLOW, "A bolt of lightning flies from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "A bolt of lightning flies from $n's $t!", ch, hands(ch), NULL, TO_ROOM); bullet = create_object( get_obj_index( 50 ), 0 ); /* blast */ if (!bullet) { send_to_char("Your weapon jams mysteriously.\n\r", ch); bug("Do_shoot: Cannot find type for projectile.", 0); return; } amt = number_range(TALENT(ch, TAL_LIGHTNING), TALENT(ch, TAL_LIGHTNING) * 5); use_magic(ch, TAL_LIGHTNING, amt); bullet->value[2] = amt; ranged_attack(ch, bullet, argument); } void do_chill(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_FROST] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_FROST, "Frigid snow flies from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FROST, "Frigid snow flies from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); learn_talent(ch, TAL_WATER); magic_damage(victim, ch, TALENT(ch, TAL_FROST) + TALENT(ch, TAL_WATER), MAG_COLD, TAL_FROST, FALSE); } void do_frostbite(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (IS_NPC(ch) || ch->curr_talent[TAL_FROST] + ch->pcdata->weapon[SK_FANG] < 150) { huh(ch); return; } act(AT_FROST, "You snap your teeth with the chill of frost!", ch, NULL, NULL, TO_CHAR); act(AT_FROST, "$n snaps $s glistening icy teeth!", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; learn_weapon(ch, SK_FANG); magic_damage(victim, ch, (TALENT(ch, TAL_FROST) + ch->pcdata->weapon[SK_FANG])*2, MAG_COLD, TAL_FROST, FALSE); } void do_taint(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; if (ch->curr_talent[TAL_DEATH] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_DGREEN, "Noxious fumes burst from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_DGREEN, "Noxious fumes burst from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch->curr_talent[TAL_DEATH] >= 10 && !IS_SET(victim->immune, RIS_POISON)) { af.type = gsn_poison; af.duration = 20; af.location = APPLY_STR; af.modifier = -2; af.bitvector = meb(AFF_POISON); affect_join( victim, &af ); victim->mental_state = URANGE( 20, victim->mental_state, 100 ); } magic_damage(victim, ch, TALENT(ch, TAL_DEATH), MAG_POISON, TAL_DEATH, FALSE); } void do_splash(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_WATER] < 1 && !IS_NPC(ch)) { huh(ch); return; } if (ch->curr_talent[TAL_EARTH] < 1) { act(AT_BLUE, "Water shoots from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_BLUE, "Water shoots fly from $n's $t!", ch, hands(ch), NULL, TO_ROOM); } else { act(AT_GREEN, "Acid sprays from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_GREEN, "Acid sprays from $n's $t!", ch, hands(ch), NULL, TO_ROOM); } victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch->curr_talent[TAL_EARTH] < 1) magic_damage(victim, ch, TALENT(ch, TAL_WATER), MAG_WATER, TAL_WATER, FALSE); else magic_damage(victim, ch, TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_WATER), MAG_ACID, TAL_WATER, FALSE); } void do_distort(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_CHANGE] > 0 || ch->curr_talent[TAL_VOID] > 0 || ch->curr_talent[TAL_TIME] > 0) { act(AT_FIRE, "Ripples of distortion radiate from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FIRE, "Ripples of distortion radiate from $n's $t!", ch, hands(ch), NULL, TO_ROOM); } victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch->curr_talent[TAL_CHANGE] > 0) magic_damage(victim, ch, TALENT(ch, TAL_CHANGE), MAG_CHANGE, TAL_CHANGE, FALSE); if (ch->curr_talent[TAL_TIME] > 0) magic_damage(victim, ch, TALENT(ch, TAL_TIME), MAG_CHANGE, TAL_TIME, FALSE); if (ch->curr_talent[TAL_VOID] > 0) magic_damage(victim, ch, TALENT(ch, TAL_VOID), MAG_CHANGE, TAL_VOID, FALSE); } void do_nightmare(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) { send_to_char("Only in the dreamworld.\n\r", ch); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, 2 * (TALENT(ch, TAL_DREAM) + TALENT(ch, TAL_MIND) + TALENT(ch, TAL_ILLUSION)), MAG_DREAM, TAL_DREAM, FALSE); } void do_wail(CHAR_DATA *ch, char *argument) { CHAR_DATA *next_vict; CHAR_DATA *victim; int n=0; if (IS_SET(ch->in_room->room_flags, ROOM_SILENCE) || (ch->curr_talent[TAL_SPEECH] < 1 && !IS_NPC(ch))) { huh(ch); return; } act(AT_YELLOW, "You emit a high pitched wail!", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n emits a high pitched wail!", ch, NULL, NULL, TO_ROOM); if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; magic_damage(victim, ch, TALENT(ch, TAL_SPEECH), MAG_SOUND, TAL_SPEECH, FALSE); } use_magic(ch, TAL_SPEECH, n*TALENT(ch, TAL_SPEECH)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, TALENT(ch, TAL_SPEECH), MAG_SOUND, TAL_SPEECH, FALSE); } void do_shock(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_LIGHTNING] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_YELLOW, "Lightning crackles from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_YELLOW, "Lightning crackles from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_UNDERWATER(ch) || ch->in_room->curr_water > 30) { act(AT_YELLOW, "The electricity surges alarmingly through the water!", ch, NULL, NULL, TO_CHAR); act(AT_YELLOW, "$n's electricity surges alarmingly through the water!", ch, NULL, NULL, TO_ROOM); if (!IS_NPC(ch)) magic_damage(ch, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING)*2, MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } else { magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } } /* creates a storm from a hybrid of wind and whichever talents of * fire, water, frost, lightning, or catalysm that they have -keo */ void do_storm(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; int last_attack; int n=0; if (ch->curr_talent[TAL_WIND] < 10 && !IS_NPC(ch)) { huh(ch); return; } if (ch->in_room->curr_water >= 100) { act(AT_CYAN, "There isn't enough air here.", ch, NULL, NULL, TO_CHAR); act(AT_CYAN, "Some air bubbles float up toward the surface.", ch, NULL, NULL, TO_ROOM); return; } act(AT_CYAN, "An elemental storm rages around you!", ch, NULL, NULL, TO_CHAR); act(AT_CYAN, "An elemental storm rages around $n!", ch, NULL, NULL, TO_ROOM); if (!str_cmp(argument, "all")) { last_attack = 0; for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; if (last_attack == TAL_FIRE) { last_attack = TAL_WIND; magic_damage(victim, ch, TALENT(ch, TAL_WIND), MAG_WIND, TAL_WIND, FALSE); continue; } if (last_attack == TAL_WIND) { last_attack = TAL_WATER; if (ch->curr_talent[TAL_WATER] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_WATER), MAG_WATER, TAL_WATER, FALSE); continue; } } if (last_attack == TAL_WATER) { last_attack = TAL_FROST; if (ch->curr_talent[TAL_FROST] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_FROST), MAG_COLD, TAL_FROST, FALSE); continue; } } if (last_attack == TAL_FROST) { last_attack = TAL_LIGHTNING; if (ch->curr_talent[TAL_LIGHTNING] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); continue; } } if (last_attack == TAL_LIGHTNING) { last_attack = TAL_CATALYSM; if (ch->curr_talent[TAL_CATALYSM] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_CATALYSM), MAG_ENERGY, TAL_CATALYSM, FALSE); continue; } } if (last_attack == TAL_CATALYSM) { last_attack = TAL_FIRE; if (ch->curr_talent[TAL_FIRE] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); continue; } } if (last_attack == TAL_FIRE) { last_attack = TAL_WIND; magic_damage(victim, ch, TALENT(ch, TAL_WIND), MAG_WIND, TAL_WIND, FALSE); continue; } } use_magic(ch, TAL_WIND, n*TALENT(ch, TAL_WIND)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, TALENT(ch, TAL_WIND), MAG_WIND, TAL_WIND, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_WATER] > 0) magic_damage(victim, ch, TALENT(ch, TAL_WATER), MAG_WATER, TAL_WATER, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_FROST] > 0) magic_damage(victim, ch, TALENT(ch, TAL_FROST), MAG_COLD, TAL_FROST, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_LIGHTNING] > 0) magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_FIRE] > 0) magic_damage(victim, ch, TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_CATALYSM] > 0) magic_damage(victim, ch, TALENT(ch, TAL_WIND), MAG_ENERGY, TAL_CATALYSM, FALSE); } void do_wind(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_WIND] < 1 && !IS_NPC(ch)) { huh(ch); return; } if (ch->in_room->curr_water >= 100) { act(AT_CYAN, "There isn't enough air here.", ch, NULL, NULL, TO_CHAR); act(AT_CYAN, "Some air bubbles float up toward the surface.", ch, NULL, NULL, TO_ROOM); return; } act(AT_CYAN, "Strong winds blow from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_CYAN, "Strong winds blow from $n's $t!", ch, hands(ch), NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, (TALENT(ch, TAL_WIND)*2 + ch->in_room->area->weather->wind)/3, MAG_WIND, TAL_WIND, FALSE); } void do_vines(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_EARTH] < 1 && !IS_NPC(ch)) { huh(ch); return; } act(AT_GREEN, "Thorny vines coil like snakes!", ch, NULL, NULL, TO_CHAR); act(AT_GREEN, "Thorny vines coil like snakes!", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, (TALENT(ch, TAL_EARTH)*2 + ch->in_room->curr_vegetation)/3, MAG_EARTH, TAL_EARTH, FALSE); } /* a destructive blast of fire, lightning, and/or catalysm - keo */ void do_blast(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_CATALYSM] > 0 || ch->curr_talent[TAL_FIRE] > 0 || ch->curr_talent[TAL_LIGHTNING] > 0) { act(AT_FIRE, "A blast of energy bursts from your $t!", ch, hands(ch), NULL, TO_CHAR); act(AT_FIRE, "A blast of energy bursts from $s $t!", ch, hands(ch), NULL, TO_ROOM); } victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch->curr_talent[TAL_CATALYSM] > 0) magic_damage(victim, ch, TALENT(ch, TAL_CATALYSM), MAG_ENERGY, TAL_CATALYSM, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_FIRE] > 0) magic_damage(victim, ch, TALENT(ch, TAL_FIRE), MAG_FIRE, TAL_FIRE, FALSE); if (char_died(victim)) return; if (ch->curr_talent[TAL_LIGHTNING] > 0) magic_damage(victim, ch, TALENT(ch, TAL_LIGHTNING), MAG_ELECTRICITY, TAL_LIGHTNING, FALSE); } void do_mindflay(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; act(AT_PURPLE, "You concentrate.", ch, NULL, NULL, TO_CHAR); act(AT_PURPLE, "$n concentrates.", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if ((ch->curr_talent[TAL_MIND] > 40 || IS_NPC(ch)) && !IS_SET(victim->resistant, RIS_PSIONIC)) victim->mental_state += number_range(0, ch->curr_talent[13] / 10); if (ch->curr_talent[TAL_MIND] >= 1) magic_damage(victim, ch, TALENT(ch, TAL_MIND) + victim->perm_int - victim->perm_wis, MAG_PSIONIC, TAL_MIND, FALSE); if (ch->curr_talent[TAL_DREAM] >= 1) magic_damage(victim, ch, TALENT(ch, TAL_DREAM), MAG_DREAM, TAL_DREAM, FALSE); if (ch->curr_talent[TAL_ILLUSION] >= 1) magic_damage(victim, ch, TALENT(ch, TAL_ILLUSION), MAG_LIGHT, TAL_ILLUSION, FALSE); } void do_flood(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; CHAR_DATA *next_vict; int n=0; if (IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR) || (ch->curr_talent[TAL_WATER] < 1 && !IS_NPC(ch))) { huh(ch); return; } if (ch->curr_talent[TAL_WATER] > 10 && ch->in_room->curr_water < 100) { act(AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_CHAR); act(AT_BLUE, "Water floods the room!", ch, NULL, NULL, TO_ROOM); if (IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) ch->in_room->curr_water += TALENT(ch, TAL_WATER) / 10; } if (!str_cmp(argument, "all")) { for ( victim = ch->in_room->first_person; victim; victim = next_vict ) { next_vict = victim->next_in_room; n++; if ( victim == ch ) continue; magic_damage(victim, ch, TALENT(ch, TAL_WATER), MAG_WATER, TAL_WATER, FALSE); } use_magic(ch, TAL_WATER, n*TALENT(ch, TAL_WATER)); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; magic_damage(victim, ch, (TALENT(ch, TAL_WATER)*2 + ch->in_room->curr_water)/3, MAG_WATER, TAL_WATER, FALSE); } /* if someone has both death and catalysm, they will end up with * a double energy drain. -keo */ void do_drain(CHAR_DATA *ch, char *argument) { PART_DATA *part; CHAR_DATA *victim; int amt; if (ch->curr_talent[TAL_DEATH] < 1 && !IS_NPC(ch) && ch->curr_talent[TAL_CATALYSM] < 1 && ch->curr_talent[TAL_HEALING] < 1) { huh(ch); return; } act(AT_DGREY, "Tendrils of darkness surround you.", ch, NULL, NULL, TO_CHAR); act(AT_DGREY, "Tendrils of darkness surround $n.", ch, NULL, NULL, TO_ROOM); victim = find_target(ch, argument, TRUE); if (!victim) return; if (IS_AFFECTED(victim, AFF_UNDEAD)) { if (ch != victim && IS_FIGHTING(victim)) { magic_damage(ch, victim, TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_HEALING), MAG_DRAIN, TAL_DEATH, TRUE); } amt = number_range(TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_HEALING), (TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_HEALING))*10); use_magic(ch, TAL_DEATH, amt); learn_talent(ch, TAL_HEALING); if (!IS_SET(ch->immune, RIS_DRAIN) || ch == victim) { act(AT_MAGIC, "Your undead flesh repairs itself.", victim, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n's undead flesh repairs itself.", victim, NULL, NULL, TO_ROOM); if (IS_AFFECTED(ch, AFF_UNHOLY)) amt *= 2; if (IS_AFFECTED(ch, AFF_HOLY) && amt != 0) amt /= 2; victim->hit += amt; if (victim->hit > victim->max_hit) victim->hit = victim->max_hit; 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) && amt > 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+amt/10); } } WAIT_STATE(ch, PULSE_VIOLENCE); if (IS_NPC(ch) && number_range(1,40) < get_curr_int(ch)) xSET_BIT(ch->act, ACT_MAG_FAIL); return; } } if (ch->curr_talent[TAL_DEATH] > 0) { magic_damage(victim, ch, TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_HEALING), MAG_DRAIN, TAL_DEATH, FALSE); amt = number_range(1, TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_HEALING)); use_magic(ch, TAL_HEALING, amt); if (!IS_SET(victim->immune, RIS_DRAIN) && TALENT(victim, TAL_DEATH) < 100) { if (IS_AFFECTED(ch, AFF_UNHOLY)) amt *= 2; if (IS_AFFECTED(victim, AFF_UNHOLY)) amt *= 2; if (IS_AFFECTED(ch, AFF_HOLY) && amt != 0) amt /= 2; if (IS_AFFECTED(victim, AFF_HOLY) && amt != 0) amt /= 2; ch->hit += amt; if (ch->hit > ch->max_hit) ch->hit = ch->max_hit; } } if (char_died(victim)) return; if (ch->curr_talent[TAL_CATALYSM] > 0) { magic_damage(victim, ch, 1, MAG_DRAIN, TAL_CATALYSM, FALSE); amt = number_range(TALENT(ch, TAL_CATALYSM), TALENT(ch, TAL_CATALYSM)*5); if (!IS_SET(victim->immune, RIS_DRAIN)) { victim->mana -= amt; ch->mana += amt; } learn_talent(ch, TAL_CATALYSM); /* no extra mana cost from mana drain (that would be pointless) */ } } void seek_object(CHAR_DATA *ch, char *argument) { char buf[MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *in_obj; int cnt, found = 0; 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 ( cnt = 0, in_obj = obj; in_obj->in_obj && cnt < 100; in_obj = in_obj->in_obj, ++cnt ) ; if ( cnt >= 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]); set_char_color( AT_MAGIC, ch ); send_to_char( buf, ch ); } if ( !found ) { send_to_char("You were unable to locate anything like that.\n\r", ch); } mana_from_char(ch, 10); learn_talent(ch, TAL_SEEKING); return; } void do_seek( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if (ch->curr_talent[TAL_SEEKING] < 20) { send_to_char("You are unable to find anything.\n\r", ch); return; } 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 ) ) { 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 ) ) { pager_printf( ch, "%s is in %s, in %s\n\r", PERS(victim, ch), victim->in_room->name, victim->in_room->area->name ); } } seek_object(ch, argument); use_magic(ch, TAL_SEEKING, 120 - ch->curr_talent[TAL_SEEKING]); } void travel_teleport(CHAR_DATA *ch) { ROOM_INDEX_DATA *pRoomIndex; if (char_died(ch)) return; if (IS_NPC(ch) && xIS_SET(ch->act, ACT_SENTINEL)) return; 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 ( ;; ) { pRoomIndex = get_room_index( number_range( 0, 1048576000 ) ); if ( pRoomIndex ) if ( !IS_SET(pRoomIndex->room_flags, ROOM_PRIVATE) && !IS_SET(pRoomIndex->room_flags, ROOM_SOLITARY) && !IS_SET(pRoomIndex->room_flags, ROOM_NO_ASTRAL) && !IS_SET(pRoomIndex->area->flags, AFLAG_NOTELEPORT) && !IS_SET(pRoomIndex->room_flags, ROOM_PROTOTYPE) && !IS_SET(pRoomIndex->room_flags, ROOM_NO_RECALL) ) break; } use_magic(ch, TAL_MOTION, ch->mount ? 50 : 25); act( AT_MAGIC, "Reality seems to twist for a moment, and your surroundings warp and change.", ch, NULL, NULL, TO_CHAR); act( AT_MAGIC, "Reality seems to twist for a moment, and $n vanishes.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); ch->in_obj = NULL; char_to_room( ch, pRoomIndex ); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, pRoomIndex); } act( AT_MAGIC, "Reality ripples for a moment, and $n suddenly appears.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_travel(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; DEITY_DATA *talent; AREA_DATA *pArea; ROOM_INDEX_DATA *pRoomIndex; EXPLORED_AREA *xarea; int i, vnum; if (IS_NPC(ch) && (xIS_SET(ch->act, ACT_PACIFIST) || xIS_SET(ch->act, ACT_SENTINEL))) return; if (ch->curr_talent[TAL_MOTION] < 20 && !IS_NPC(ch)) { travel_teleport(ch); return; } if (!argument || argument[0] == '\0') { travel_teleport(ch); return; } if (IS_AFFECTED(ch, AFF_VOID)) { travel_teleport(ch); return; } 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 ((pRoomIndex = get_room_index(vnum)) == NULL) continue; if (IS_SET(pRoomIndex->room_flags, ROOM_NO_ASTRAL)) { if (IS_SET(pRoomIndex->runes, RUNE_WARD)) continue; if (IS_SET(pArea->flags, AFLAG_NOBYPASS)) continue; if (TALENT(ch, TAL_MOTION) < 100) continue; } break; } if (!pRoomIndex) { send_to_char("You can't find a place to land.\n\r", ch); return; } use_magic(ch, TAL_MOTION, (250 - ch->curr_talent[TAL_MOTION]*2) * (ch->mount ? 2 : 1)); 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, pRoomIndex); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, pRoomIndex); 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; } use_magic(ch, TAL_MOTION, (250 - ch->curr_talent[TAL_MOTION]*2) * (ch->mount ? 2 : 1)); 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" ); learn_talent(ch, TAL_MOTION); WAIT_STATE(ch, PULSE_VIOLENCE*2 - ch->curr_talent[TAL_MOTION]/5); } void do_summon(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim = NULL; char buf[MAX_STRING_LENGTH]; if (ch->curr_talent[TAL_MOTION] < 40 && !IS_NPC(ch)) { travel_teleport(ch); return; } if (IS_SET(ch->in_room->area->flags, AFLAG_NOBYPASS)) { huh(ch); return; } if (IS_AFFECTED(ch, AFF_VOID)) { travel_teleport(ch); return; } victim = get_char_world(ch, argument); if (!victim || (IS_NPC(victim) && !xIS_SET(victim->act, ACT_NAMED))) victim = generate_mob_nation(argument); if (!victim) { send_to_char("You cannot find anything like that.\n\r",ch); return; } if (victim == ch) { send_to_char("That was a short trip!\n\r", ch); return; } if (victim->in_room && !can_travel(100, ch, victim)) { send_to_char("Something prevents you from opening a rift.\n\r", ch); return; } use_magic(ch, TAL_MOTION, 500 - (ch->curr_talent[TAL_MOTION]*4)); 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); } if (victim->in_room) { 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); if (victim->in_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); WAIT_STATE(victim, PULSE_VIOLENCE); } void do_morph(CHAR_DATA *ch, char* argument) { NATION_DATA *newrace; SPECIES_DATA *species; OBJ_DATA *obj; if (ch->curr_talent[TAL_CHANGE] < 10) { huh(ch); return; } if (IS_NPC(ch)) { huh(ch); return; } if (argument && !ch->pcdata->were_race) { /* if they dont have a morph, set it to the argument */ newrace = find_nation(argument); if (!newrace) { send_to_char("There is no such race.\n\r", ch); return; } if (IS_SET(newrace->flags, NAT_NPC)) { send_to_char("You cannot change into that!", ch); return; } if (has_bodypart(ch, BP_RHAND) && IS_SET(newrace->parts, PART_HANDS)) { send_to_char("That race is too similar, pick one without hands.\n\r", ch); return; } if (!has_bodypart(ch, BP_RHAND) && !IS_SET(newrace->parts, PART_HANDS)) { send_to_char("That race is too similar, pick one with hands.\n\r", ch); return; } if (has_bodypart(ch, BP_RHAND)) ch_printf(ch, "You are now a were-%s.\n\r", newrace->name); else ch_printf(ch, "You are now a were-%s.\n\r", ch->species); ch->pcdata->were_race = STRALLOC(newrace->name); return; } if (ch->mount) { send_to_char("And scare your mount?\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_MOUNTED)) throw_rider(ch); if (ch->mana <= 0) { send_to_char("You do not have enough mana to change.\n\r",ch); return; } newrace = find_nation(ch->pcdata->were_race); STRFREE(ch->pcdata->were_race); if (IS_AFFECTED(ch, AFF_ANTHRO)) ch->pcdata->were_race = STRALLOC("anthro"); else ch->pcdata->were_race = STRALLOC(ch->species); if (!newrace) { send_to_char("Select your were-race first with morph <race>.", ch); return; } use_magic(ch, TAL_CHANGE, 100); de_equip_char(ch); if (IS_AFFECTED(ch, AFF_FLYING)) do_land(ch, ""); species = find_species(newrace->species); if (!species) { bug("do_morph: cannot find species!"); send_to_char("You suddenly forget what one of those is.",ch); return; } act( AT_MAGIC, "Your body changes and warps, and you become $t.", ch, aoran(newrace->name), NULL, TO_CHAR); act( AT_MAGIC, "$n's body changes and warps, and $e becomes $t.", ch, aoran(newrace->name), NULL, TO_ROOM); if (IS_AFFECTED(ch, AFF_ANTHRO)) { xREMOVE_BIT(ch->pcdata->perm_aff, AFF_ANTHRO); STRFREE(ch->pcdata->type); if (IS_AFFECTED(ch, AFF_UNDEAD)) ch->pcdata->type = STRALLOC("undead"); else ch->pcdata->type = STRALLOC("living"); } ch->nation = newrace; set_race(ch, FALSE); if (!can_use_bodypart(ch, BP_RHAND)) { 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 = ch->first_carrying; obj; obj = obj->next_content) { obj->size = ch->height; } } re_equip_char(ch); update_aris(ch); ch->max_hit = UMAX(20, ch->nation->hit * get_curr_con(ch) + ch->base_hit); ch->max_mana = UMAX(20, ch->nation->mana * get_curr_int(ch) + ch->base_mana); ch->max_move = UMAX(20, 25 * get_curr_end(ch) + ch->base_move); ch->mana = ch->max_mana; } void do_change(CHAR_DATA *ch, char* argument) { NATION_DATA *newrace; SPECIES_DATA *species; char arg[MAX_STRING_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; if (ch->curr_talent[TAL_CHANGE] < 1) { huh(ch); return; } if (IS_NPC(ch)) { huh(ch); return; } if (!argument || argument[0] == '\0') { send_to_char("Change into what?\n\r", ch); return; } if (ch->mount) { send_to_char("And scare your mount?\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_MOUNTED)) throw_rider(ch); if (ch->mana <= 0) { send_to_char("You do not have enough mana to change.\n\r",ch); return; } argument = one_argument(argument, arg); victim = find_target(ch, arg, FALSE); if (!victim) return; if (IS_NPC(victim)) { send_to_char("You can't change that!\n\r", ch); return; } if (!str_cmp(argument, "anthro")) { if (has_bodypart(victim, BP_RHAND)) { send_to_char("They already have hands.\n\r", ch); return; } if (victim->height > 100) { send_to_char("They are too large to become an anthropomorphic form.\n\r", ch); return; } 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 (ch->curr_talent[TAL_CHANGE] < 30 || !argument) { send_to_char("Your Changing magic goes awry...\n\r", ch); if (!add_mutation(victim, 0)) send_to_char("However, there is no effect.\n\r", ch); return; } if (victim != ch) { if (TALENT(ch, TAL_CHANGE) < 80) { 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) < 400) { send_to_char("You cannot do that without their consent.\n\r", ch); return; } } newrace = find_nation(argument); if (!newrace) { send_to_char("You can't change into any such thing.", ch); return; } if (str_cmp(newrace->species, victim->nation->species) && (ch->curr_talent[TAL_CHANGE] < 60)) { send_to_char("You are not skilled enough to make such a drastic change.\n\r", ch); return; } use_magic(ch, TAL_CHANGE, 300); de_equip_char(victim); if (IS_AFFECTED(victim, AFF_FLYING)) do_land(victim, ""); species = find_species(newrace->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(newrace->name)); act( AT_MAGIC, "$N's body changes and warps, and $E becomes $t.", ch, aoran(newrace->name), victim, TO_NOTVICT); if (ch != victim) { act( AT_MAGIC, "You change and warp $N's body into $t.", ch, aoran(newrace->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 = newrace; set_race(victim, FALSE); if (!IS_SET(newrace->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); } void do_alter(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int i; if (ch->curr_talent[TAL_CHANGE] < 25) { huh(ch); return; } if (IS_NPC(ch)) { huh(ch); return; } if (!argument || argument[0] == '\0') { send_to_char("Alter what?\n\r", ch); return; } if (ch->mana <= 0) { send_to_char("You do not have enough mana to change.\n\r",ch); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); victim = find_target(ch, arg1, FALSE); if (!victim) return; if (IS_NPC(victim)) { send_to_char("You can't change that!\n\r", ch); return; } 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(arg2, "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(arg2, "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(arg2, "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", arg2)) { 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", arg2)) { 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, arg2)) { 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, arg2)) { 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; } use_magic(ch, TAL_CHANGE, 50); } /* * Check for antimagic. */ bool check_antimagic( CHAR_DATA *ch, CHAR_DATA *victim ) { if (!victim) return FALSE; if (ch == victim) return FALSE; if ( !IS_AWAKE(victim) ) return FALSE; if ( !IS_SET(victim->mood, MOOD_READY)) return FALSE; if ( victim->curr_talent[TAL_VOID] < 10 ) return FALSE; if (victim->mana < 100) return FALSE; if ( number_range(1,105) > (number_range(1, TALENT(victim, TAL_VOID) ))) { return FALSE; } use_magic(victim, TAL_VOID, 100); act( AT_MAGIC, "You cast $n's magic into the Void.", ch, NULL, victim, TO_VICT ); act( AT_MAGIC, "$N channels antimagic, stopping your attack.", ch, NULL, victim, TO_CHAR ); act( AT_MAGIC, "$N channels antimagic, stopping $n's attack.", ch, NULL, victim, TO_NOTVICT ); return TRUE; } /* * Check for blur. */ bool check_blur( CHAR_DATA *ch, CHAR_DATA *victim ) { if (!victim) return FALSE; if (ch == victim) return FALSE; if ( !IS_AWAKE(victim) ) return FALSE; if ( !IS_SET(victim->mood, MOOD_READY)) return FALSE; if ( victim->curr_talent[TAL_TIME] < 10 ) return FALSE; if (victim->mana < 100) return FALSE; if ( number_range(1,200) > (number_range(1, TALENT(victim, TAL_TIME) - victim->encumberance))) { return FALSE; } use_magic(victim, TAL_TIME, 50); act( AT_MAGIC, "$n swings at you, but you blur out of the way.", ch, NULL, victim, TO_VICT ); act( AT_MAGIC, "You swing at $N, but $E blurs out of the way.", ch, NULL, victim, TO_CHAR ); act( AT_MAGIC, "$n swings at $N, but $E blurs out of the way.", ch, NULL, victim, TO_NOTVICT ); return TRUE; } /* * Check for displacement. */ bool check_displacement( CHAR_DATA *ch, CHAR_DATA *victim ) { if (!victim) return FALSE; if (ch == victim) return FALSE; if ( !IS_AWAKE(victim) ) return FALSE; if ( !IS_SET(victim->mood, MOOD_READY)) return FALSE; if ( victim->curr_talent[TAL_ILLUSION] < 10 ) return FALSE; if (victim->mana < 50) return FALSE; if ( number_range(1,100 + get_curr_per(ch)) > (number_range(1, TALENT(victim, TAL_ILLUSION) ))) { return FALSE; } use_magic(victim, TAL_ILLUSION, 50); act( AT_MAGIC, "$n strikes at your displaced image, missing you.", ch, NULL, victim, TO_VICT ); act( AT_MAGIC, "You strike at $N's displaced image, missing $M.", ch, NULL, victim, TO_CHAR ); act( AT_MAGIC, "$n strikes at $N's displaced image, missing $M.", ch, NULL, victim, TO_NOTVICT ); return TRUE; } void do_blink(CHAR_DATA *ch, char *argument) { if (ch->curr_talent[TAL_MOTION] < 50) { check_social(ch, "blink", argument); return; } use_magic(ch, TAL_MOTION, 20); act(AT_MAGIC, "You blink a short distance away.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n blinks out of existance.", ch, NULL, NULL, TO_ROOM); stop_fighting(ch, TRUE); } void do_pacify(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (IS_SILENT(ch)) { send_to_char("No sound comes out.\n\r", ch); return; } if (ch->curr_talent[TAL_SPEECH] < 60) { send_to_char("They don't seem overly impressed by your singing skills.", ch); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; use_magic(ch, TAL_SPEECH, 1000 - ch->curr_talent[TAL_SPEECH]*9); stop_fighting(ch, FALSE); 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); } void do_purify(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->curr_talent[TAL_HEALING] < 100) { huh(ch); return; } victim = find_target(ch, argument, FALSE); if (!victim) return; if (IS_NPC(victim)) { send_to_char("You cannot purify them!\n\r", ch); return; } if (victim != ch) { act(AT_WHITE, "You completely purify $N!", ch, NULL, victim, TO_CHAR); act(AT_WHITE, "A white aura surrounds $N as $n purifies $M.", ch, NULL, victim, TO_NOTVICT); act(AT_WHITE, "Your blood is cleansed and you feel purified.", ch, NULL, victim, TO_VICT); } else { act(AT_WHITE, "You completely purify yourself.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "A white aura surrounds $n as $e purifies $mself.", ch, NULL, NULL, TO_ROOM); } victim->pcdata->condition[COND_FULL] = 10; victim->pcdata->condition[COND_THIRST] = 10; victim->pcdata->condition[COND_DRUNK] = 0; if ( is_affected( victim, gsn_poison ) ) affect_strip( victim, gsn_poison ); if ( is_affected( victim, gsn_corruption ) ) affect_strip( victim, gsn_corruption ); if ( is_affected( victim, gsn_curse ) ) affect_strip( victim, gsn_curse ); if ( is_affected( victim, gsn_blindness ) ) affect_strip( victim, gsn_blindness ); if ( is_affected( victim, gsn_weaken ) ) affect_strip( victim, gsn_weaken ); if ( is_affected( victim, gsn_disease ) ) affect_strip( victim, gsn_disease ); if ( is_affected( victim, gsn_mummy_rot ) ) affect_strip( victim, gsn_mummy_rot ); REMOVE_BIT(victim->pcdata->flags, PCFLAG_VAMPIRE); } void do_cure(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; if (!argument || argument[0] == '\0') { send_to_char("Cure whom of what?\n\r", ch); return; } argument = one_argument(argument, arg); victim = find_target(ch, argument, FALSE); if (!victim) return; if (!str_cmp(arg, "poison") && ch->curr_talent[TAL_HEALING] >= 15) { if ( is_affected( victim, gsn_poison ) ) { 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 ); if ( ch != victim ) { act( AT_MAGIC, "A flush of health washes over $N.", ch, NULL, victim, TO_NOTVICT); act( AT_MAGIC, "You lift the poison from $N's body.", ch, NULL, victim, TO_CHAR); } } else { set_char_color( AT_MAGIC, ch ); if ( ch != victim ) send_to_char( "You work your cure, but it has no apparent effect.\n\r", ch); else send_to_char( "You don't seem to be poisoned.\n\r", ch ); } } else if (!str_cmp(arg, "rot") && (ch->curr_talent[TAL_HEALING] >= 60)) { if ( !is_affected( victim, gsn_mummy_rot ) ) { if ( ch != victim ) send_to_char( "They don't seem to be rotting.\n\r", ch); else send_to_char( "You don't seem to be rotting.\n\r", ch ); return; } affect_strip( victim, gsn_mummy_rot ); set_char_color( AT_MAGIC, victim); send_to_char("Your flesh stops rotting.\n\r", victim ); if ( ch != victim ) send_to_char( "You restore the rotten flesh to normal.\n\r", ch ); } else if (!str_cmp(arg, "plague") && (ch->curr_talent[TAL_HEALING] >= 75)) { if ( !is_affected( victim, gsn_disease ) ) { if ( ch != victim ) send_to_char( "They don't seem to be infected.\n\r", ch); else send_to_char( "You don't seem to be infected.\n\r", ch ); return; } affect_strip( victim, gsn_disease ); set_char_color( AT_MAGIC, victim); send_to_char("The plague is purged from you.\n\r", victim ); if ( ch != victim ) send_to_char( "You work your cure, purging the plague.\n\r", ch ); } else if (!str_cmp(arg, "blind") && (ch->curr_talent[TAL_HEALING] >= 25 || ch->curr_talent[TAL_SEEKING] >= 25)) { if ( !is_affected( victim, gsn_blindness ) ) { if ( ch != victim ) send_to_char( "They don't seem to be blind.\n\r", ch); else send_to_char( "You don't seem to be blind.\n\r", ch ); 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 ); } else if (!str_cmp(arg, "curse") && ch->curr_talent[TAL_SECURITY] >= 35) { if ( is_affected( victim, gsn_curse ) ) { affect_strip( victim, gsn_curse ); set_char_color( AT_MAGIC, victim ); send_to_char( "The weight of your curse is lifted.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You dispel the curses afflicting $N.", ch, NULL, victim, TO_CHAR); act( AT_MAGIC, "$n's dispels the curses afflicting $N.", ch, NULL, victim, TO_NOTVICT); } } else { if (ch != victim ) send_to_char("They don't seem to be cursed.\n\r", ch); else send_to_char("You don't seem to be cursed.\n\r", ch); } } else if (!str_cmp(arg, "corrupt") && (ch->curr_talent[TAL_HEALING] >= 35 || ch->curr_talent[TAL_CHANGE] >= 50)) { if ( is_affected( victim, gsn_corruption ) ) { 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); } else { if (ch != victim ) send_to_char("They don't seem to be corrupted.\n\r", ch); else send_to_char("You don't seem to be corrupted.\n\r", ch); } } else if (!str_cmp(arg, "weak") && ch->curr_talent[TAL_HEALING] >= 10) { if ( is_affected( victim, gsn_weaken ) ) { affect_strip( victim, gsn_weaken ); set_char_color( AT_MAGIC, victim ); send_to_char( "You feel your strength returning.\n\r", victim ); if ( ch != victim ) { act( AT_MAGIC, "You dispel the magical weakness from $N.", ch,NULL, victim, TO_CHAR); } act( AT_MAGIC, "$N appears to grow stronger.", ch, NULL, victim,TO_NOTVICT); } else { if (ch != victim ) send_to_char("They don't seem to be magically weakened.\n\r",ch); else send_to_char("You don't seem to be magically weakened.\n\r",ch); } } else if (!str_cmp(arg, "drunk") && ch->curr_talent[TAL_MIND] + ch->curr_talent[TAL_HEALING] >= 20) { 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 ); learn_talent(ch, TAL_MIND); } else { send_to_char("You do not know how to cure any such thing.\n\r", ch); return; } use_magic(ch, TAL_HEALING, 110 - ch->curr_talent[TAL_HEALING]); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_dispel(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; OBJ_DATA *obj; if (ch->curr_talent[TAL_CATALYSM] < 10 && ch->curr_talent[TAL_VOID] < 10) { huh(ch); return; } if (!str_cmp(argument, "room") && ch->curr_talent[TAL_CATALYSM] >= 50) { 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; return; } obj = get_obj_carry(ch, argument); if (!obj) { victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch->curr_talent[TAL_CATALYSM] < 30 && victim != ch && ch->curr_talent[TAL_VOID] < 30) { send_to_char("You are not yet strong enough to strip another's enchantments.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_MAGICAL)) { magic_damage(victim, ch, TALENT(ch, TAL_CATALYSM)*3 + TALENT(ch, TAL_VOID)*5, MAG_ANTIMAGIC, TAL_CATALYSM, FALSE); } /* fall through to get their affs too */ use_magic(ch, TAL_CATALYSM, 200 - ch->curr_talent[TAL_CATALYSM]); if (TALENT(victim, TAL_SECURITY) > TALENT(ch, TAL_CATALYSM) + TALENT(ch, TAL_VOID) && ch != victim) { 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 ) { set_char_color(AT_MAGIC, victim); 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 { if (ch == victim) send_to_char("You are not affected by any enchantments.\n\r", ch); else send_to_char("They dont seem to be affected by any enchantments.\n\r", ch); } } /* end player dispel */ else { if (ch->curr_talent[TAL_CATALYSM] < 60) { send_to_char("You cannot yet disenchant items.\n\r", ch); return; } if ( !IS_OBJ_STAT(obj, ITEM_MAGIC) ) { send_to_char("This item appears to have no enchantments on it.\r\n",ch); return; } if ( xIS_SET(obj->pIndexData->extra_flags, ITEM_MAGIC) ) { send_to_char("This item is inherently magical, you cannot dispel its affects.\r\n",ch); return; } act(AT_DGREY, "Wisps of black smoke rise from $p.", ch, obj, NULL, TO_CHAR); act(AT_DGREY, "Wisps of black smoke rise from $p.", ch, obj, NULL, TO_ROOM); xREMOVE_BIT(obj->extra_flags, ITEM_MAGIC); xREMOVE_BIT(obj->extra_flags, ITEM_GLOW); xREMOVE_BIT(obj->extra_flags, ITEM_DARK); xREMOVE_BIT(obj->extra_flags, ITEM_HUM); if (obj->item_type == ITEM_WEAPON) { /* dispel banes and brands too */ obj->value[0] = 0; obj->value[4] = 0; obj->value[7] = 0; } use_magic(ch, TAL_CATALYSM, 1000 - ch->curr_talent[TAL_CATALYSM]*4); WAIT_STATE(ch, PULSE_VIOLENCE*2); } } void do_sing(CHAR_DATA *ch, char *argument) { int i; char buf[MAX_STRING_LENGTH]; bool found; OBJ_DATA *obj; if (IS_SILENT(ch)) { send_to_char("No sound comes out.\n\r", ch); return; } if (ch->curr_talent[TAL_SPEECH] < 10) { check_social(ch, "sing", argument); return; } if (!argument || argument[0] == '\0') { if (ch->singing) ch_printf(ch, "&PYou are singing a song of %s.\n\r", song_name[ch->singing]); else send_to_char("&PSing what?\n\r", ch); return; } if (ch->singing == SONG_FLIGHT) xREMOVE_BIT(ch->affected_by, AFF_FLYING); found = FALSE; for ( obj = ch->first_carrying; obj; obj = obj->next_content) { if ( obj->item_type == ITEM_INSTRUMENT ) { found = TRUE; break; } } if (!str_cmp(argument, "none")) { act(AT_PINK, "You stop singing.", ch, NULL, NULL, TO_CHAR); act(AT_PINK, "$n stops singing.", ch, NULL, NULL, TO_ROOM); ch->singing = SONG_NONE; if (obj) xREMOVE_BIT(obj->extra_flags, ITEM_IN_USE); update_aris(ch); return; } if (ch->curr_talent[TAL_SPEECH] < 50) { if (found) { act(AT_PINK, "You play $p.", ch, obj, NULL, TO_CHAR); act(AT_PINK, "$n plays $p.", ch, obj, NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_IN_USE); } else { send_to_char("You need an instrument to play.\n\r", ch); ch->singing = SONG_NONE; return; } } for (i = 1;i < MAX_SONG;i++) { if (!str_cmp(argument, song_name[i])) { ch->singing = i; ch_printf(ch, "&PYou sing a song of %s.\n\r", song_name[i]); sprintf(buf, "$n sings a song of %s.", song_name[i]); act(AT_PINK, buf, ch, NULL, NULL, TO_ROOM); update_aris(ch); return; } } send_to_char("You know of no such song.\n\r", ch); } void do_rune(CHAR_DATA *ch, char *argument) { int tal; if (IS_SET(ch->in_room->room_flags, ROOM_NO_MAGIC)) { send_to_char("The runes fade and vanish.\n\r", ch); return; } if (!str_cmp(argument, "life") && ch->curr_talent[TAL_HEALING] >= 100) { 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(ch->in_room->runes, RUNE_LIFE); tal = TAL_HEALING; } else if (!str_cmp(argument, "distract") && ch->curr_talent[TAL_DREAM] >= 100) { 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(ch->in_room->runes, RUNE_DISTRACT); tal = TAL_DREAM; } else if (!str_cmp(argument, "ward") && ch->curr_talent[TAL_SECURITY] >= 100) { 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(ch->in_room->runes, RUNE_WARD); tal = TAL_SECURITY; } else { send_to_char("You know no such rune.\n\r", ch); return; } use_magic(ch, tal, 1000); } void do_shield(CHAR_DATA *ch, char *argument) { int tal; if (!argument || argument[0] == '\0') { if (ch->shield) ch_printf(ch, "You are surrounded by a shield of %s.\n\r", magic_table[ch->shield]); else send_to_char("You are not shielded.\n\r", ch); return; } if (!str_cmp(argument, "none") && ch->shield) { 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); ch->shield = MAG_NONE; return; } else if (!str_cmp(argument, "acid") && ch->curr_talent[TAL_WATER] >= 30 && ch->curr_talent[TAL_EARTH] >= 10) { 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); ch->shield = MAG_ACID; tal = TAL_WATER; } else if (!str_cmp(argument, "dagger") && ch->curr_talent[TAL_CATALYSM] >= 30 && ch->curr_talent[TAL_EARTH] >= 10) { act(AT_WHITE, "Dozens of dancing daggers twirl around you.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "Dozens of dancing daggers twirl around $n.", ch, NULL, NULL, TO_ROOM); ch->shield = MAG_PIERCE; tal = TAL_CATALYSM; } else if (!str_cmp(argument, "dream") && ch->curr_talent[TAL_DREAM] >= 40) { 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); ch->shield = MAG_DREAM; tal = TAL_DREAM; } else if (!str_cmp(argument, "energy") && ch->curr_talent[TAL_CATALYSM] >= 40) { 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); ch->shield = MAG_ENERGY; tal = TAL_CATALYSM; } else if (!str_cmp(argument, "fire") && ch->curr_talent[TAL_FIRE] >= 40) { 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); ch->shield = MAG_FIRE; tal = TAL_FIRE; } else if (!str_cmp(argument, "ice") && ch->curr_talent[TAL_FROST] >= 40) { 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); ch->shield = MAG_COLD; tal = TAL_FROST; } else if (!str_cmp(argument, "light") && ch->curr_talent[TAL_ILLUSION] >= 40) { 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); ch->shield = MAG_LIGHT; tal = TAL_ILLUSION; } else if (!str_cmp(argument, "mana") && ch->curr_talent[TAL_CATALYSM] >= 60) { 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); ch->shield = MAG_ALL; tal = TAL_CATALYSM; } else if (!str_cmp(argument, "poison") && ch->curr_talent[TAL_DEATH] >= 40) { 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); ch->shield = MAG_POISON; tal = TAL_DEATH; } else if (!str_cmp(argument, "shock") && ch->curr_talent[TAL_LIGHTNING] >= 40) { 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); ch->shield = MAG_ELECTRICITY; tal = TAL_LIGHTNING; } else if (!str_cmp(argument, "sound") && ch->curr_talent[TAL_SPEECH] >= 40) { 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); ch->shield = MAG_SOUND; tal = TAL_SPEECH; } else if (!str_cmp(argument, "stone") && ch->curr_talent[TAL_EARTH] >= 40) { 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); ch->shield = MAG_BLUNT; tal = TAL_EARTH; } else if (!str_cmp(argument, "sword") && ch->curr_talent[TAL_CATALYSM] >= 10 && ch->curr_talent[TAL_EARTH] >= 30) { act(AT_WHITE, "A dozen dancing swords spin around you.", ch, NULL, NULL, TO_CHAR); act(AT_WHITE, "A dozen dancing swords spin around $n.", ch, NULL, NULL, TO_ROOM); ch->shield = MAG_SLASH; tal = TAL_EARTH; } else if (!str_cmp(argument, "thought") && ch->curr_talent[TAL_MIND] >= 40) { 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); ch->shield = MAG_PSIONIC; tal = TAL_MIND; } else if (!str_cmp(argument, "vines") && ch->curr_talent[TAL_EARTH] >= 40) { 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); ch->shield = MAG_EARTH; tal = TAL_EARTH; } else if (!str_cmp(argument, "warp") && (ch->curr_talent[TAL_CHANGE] >= 40 || ch->curr_talent[TAL_TIME] >= 40 || ch->curr_talent[TAL_VOID] >= 40)) { 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); ch->shield = MAG_CHANGE; tal = TAL_CHANGE; } else if (!str_cmp(argument, "water") && ch->curr_talent[TAL_WATER] >= 40) { 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); ch->shield = MAG_WATER; tal = TAL_WATER; } else if (!str_cmp(argument, "wind") && ch->curr_talent[TAL_WIND] >= 40) { 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); ch->shield = MAG_WIND; tal = TAL_WIND; } else { send_to_char("You can't form any such shield.\n\r", ch); return; } use_magic(ch, tal, 500 - (ch->curr_talent[tal] *4)); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_bind(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; OBJ_DATA *obj; DEITY_DATA *talent; if (ch->curr_talent[TAL_CATALYSM] < 60) { huh(ch); return; } argument = one_argument(argument, arg); victim = find_target(ch, argument, FALSE); if (!victim) return; obj=get_obj_carry(ch, arg); if (!obj) { send_to_char("You don't have one of those to bind.\r\n",ch); return; } if (IS_OBJ_STAT(obj, ITEM_LOYAL) || IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { send_to_char("Your magic twists around it but fails to take hold.\n\r", ch); return; } if (obj->mana < 500) { send_to_char("The mana in this item is insufficient to hold the binding.\n\r", ch); return; } if (ch->pcdata->inborn == -1) talent = get_talent_by_index(TAL_CATALYSM); else talent = get_talent_by_index(ch->pcdata->inborn); use_magic(ch, TAL_CATALYSM, 1000 - ch->curr_talent[TAL_CATALYSM] * 9); obj->mana -= 500; obj->cost += 500000; xSET_BIT(obj->extra_flags, ITEM_LOYAL); act(AT_MAGIC, "You bind $p to $N.", ch, obj, victim, TO_CHAR); act(AT_BLUE, "$T $p, binding it with power.", ch, obj,talent->message, TO_ROOM); WAIT_STATE(ch, PULSE_VIOLENCE*2); } void do_brand(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; OBJ_DATA *obj; int tal; argument = one_argument(argument, arg); obj=get_obj_carry(ch, arg); if (!obj) { send_to_char("You don't have one of those to brand.\r\n",ch); return; } if (obj->item_type != ITEM_WEAPON && obj->item_type != ITEM_MISSILE_WEAPON) { ch_printf(ch, "You can only brand weapons.\n\r"); return; } if (obj->value[4]) { ch_printf(ch, "That item is already branded.\n\r"); return; } if (obj->mana < 500) { ch_printf(ch, "That item lacks the mana to sustain the enchantment.\n\r"); return; } if (!str_cmp(argument, "fire") && ch->curr_talent[TAL_FIRE] >= 50) { 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; tal = TAL_FIRE; } else if (!str_cmp(argument, "frost") && ch->curr_talent[TAL_FROST] >= 50) { 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; tal = TAL_FROST; } else if (!str_cmp(argument, "lightning") && ch->curr_talent[TAL_LIGHTNING] >= 50) { 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; tal = TAL_LIGHTNING; } else if (!str_cmp(argument, "acid") && ch->curr_talent[TAL_WATER] >= 50) { 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; tal = TAL_WATER; } else if (!str_cmp(argument, "antimatter") && ch->curr_talent[TAL_VOID] >= 60) { act( AT_DGREY, "Black lightning crackles around $p!", ch, obj, NULL, TO_CHAR); act( AT_DGREY, "Black lightning crackles around $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; tal = TAL_VOID; } else if (!str_cmp(argument, "sonic") && ch->curr_talent[TAL_SPEECH] >= 50) { 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; tal = TAL_SPEECH; } else if (!str_cmp(argument, "distort") && ch->curr_talent[TAL_CHANGE] + ch->curr_talent[TAL_TIME] + ch->curr_talent[TAL_VOID] >= 60) { act( AT_DBLUE, "The air warps and twists around $p!", ch, obj, NULL, TO_CHAR ); act( AT_DBLUE, "The air warps and twists around $n's $p!", ch, obj, NULL, TO_ROOM); obj->value[4] = BRAND_DISTORT; tal = TAL_CHANGE; } else if (!str_cmp(argument, "venom") && ch->curr_talent[TAL_DEATH] >= 50) { 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; tal = TAL_DEATH; } else if (!str_cmp(argument, "vorpal") && ch->curr_talent[TAL_CATALYSM] >= 60) { 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 ) { send_to_char("You can only vorpalize edged weapons.\r\n",ch); 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; tal = TAL_CATALYSM; } else if (!str_cmp(argument, "storm") && ch->curr_talent[TAL_WIND] >= 60) { 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; tal = TAL_WIND; } else if (!str_cmp(argument, "radiant") && ch->curr_talent[TAL_ILLUSION] >= 50) { 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); tal = TAL_ILLUSION; } else if (!str_cmp(argument, "crush") && ch->curr_talent[TAL_EARTH] >= 60) { if (obj->value[5] != SK_MACE && obj->value[5] != SK_STAFF && obj->value[5] != SK_WHIP ) { send_to_char("Only blunt weapons can crush.\n\r", ch); 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; tal = TAL_EARTH; } else if (!str_cmp(argument, "drain") && ch->curr_talent[TAL_DEATH] >= 60) { 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; tal = TAL_DEATH; } else if (!str_cmp(argument, "psionic") && ch->curr_talent[TAL_MIND] >= 50) { 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); tal = TAL_MIND; } else { send_to_char("You can't make any such brand.\n\r", ch); return; } obj->mana -= 500; obj->cost += 500000; use_magic(ch, tal, 200 - ch->curr_talent[tal]); WAIT_STATE(ch, PULSE_VIOLENCE); sprintf(buf, "%s%s", weapon_brand[obj->value[4]],myobj(obj)); STRFREE(obj->short_descr); obj->short_descr = STRALLOC(buf); } void do_funnel(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int amt; int magic; OBJ_DATA *obj; obj = get_obj_carry(ch, argument); if (obj) { 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; } amt = get_curr_wil(ch) * 10; use_magic(ch, TAL_CATALYSM, amt); amt /= obj->weight == 0 ? 1 : obj->weight; obj->raw_mana += amt; if (obj->gem) obj->gem->raw_mana += amt; 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 / 30)); extract_obj(obj); } if (obj->raw_mana > 2000) act(AT_PURPLE, "$p vibrates violently!", ch, obj, NULL, TO_CHAR); return; } if (ch->curr_talent[TAL_CATALYSM] < 30) { send_to_char("You have nothing like that.\n\r", ch); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; if (ch == victim) return; if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) { send_to_char("You shouldn't do that to a pacifist.\n\r", ch); return; } magic = UMIN(ch->curr_talent[TAL_CATALYSM], 100); magic = 100 / magic; amt = ch->mana / magic; 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 + amt; 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 -= amt; victim->mana += amt; return; } void do_dream(CHAR_DATA *ch, char *argument) { int i, vnum; ROOM_INDEX_DATA *pRoomIndex; AREA_DATA *pArea; CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; ROOM_INDEX_DATA *location; ROOM_INDEX_DATA *original; argument = one_argument(argument, arg); if (!str_cmp(arg, "enter") && ch->curr_talent[TAL_DREAM] >= 10) { if ( IS_AFFECTED (ch, AFF_DREAMWORLD ) ) { act( AT_MAGIC, "You are already in the dreamworld!", ch, NULL, NULL, TO_CHAR); 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))) { act( AT_MAGIC, "For some reason, you cannot enter the dream here.", ch, NULL, NULL, TO_CHAR); return; } 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); } else if (!str_cmp(arg, "pull") && ch->curr_talent[TAL_DREAM] >= 40) { victim = get_char_room(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) { act( AT_MAGIC, "You need to be in the dreamworld to cast that.", ch, NULL, NULL, TO_CHAR); return; } if (victim->position != POS_SLEEPING) { act( AT_MAGIC, "$N needs to be asleep to pull $M into your dream.", ch, NULL, victim, TO_CHAR); return; } act( AT_MAGIC, "You pull $N into the dreamworld!", 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, "Your dreams seem to change, and become more vivid.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); return; } else if (!str_cmp(arg, "rip") && ch->curr_talent[TAL_DREAM] >= 60) { victim = get_char_world(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if ( victim == ch || !victim->in_room || !IS_AFFECTED(ch, AFF_DREAMWORLD) || !IS_AFFECTED(victim, AFF_DREAMWORLD) ) { send_to_char("You both need to be in dreamworld for this spell.", ch); return; } act( AT_MAGIC, "You are ripped out of your dream and $n pulls you into $s dream!", ch, NULL, victim, TO_VICT); act( AT_MAGIC, "$n is ripped out of the dream!", victim, NULL, NULL, TO_ROOM); char_from_room( victim ); victim->in_obj = NULL; char_to_room( victim, ch->in_room ); act( AT_MAGIC, "$n is ripped into the dream!", victim, NULL, NULL, TO_ROOM); do_look( victim, "auto" ); } else if (!str_cmp(arg, "shift") && ch->curr_talent[TAL_DREAM] >= 30) { if ( !IS_AFFECTED(ch, AFF_DREAMWORLD) ) { act( AT_MAGIC, "You need to be in the dreamworld to cast that.", ch, NULL, NULL, TO_CHAR); return; } victim = get_char_world(ch, argument); if (!victim) { /* Start travel to location */ for(pArea = first_area; pArea; pArea = pArea->next) { if ((arg[0] == '\0' || nifty_is_name_prefix(argument, pArea->name)) && !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) { for (i = 0;i < 20;i++) { vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum); if ((pRoomIndex = get_room_index(vnum)) == NULL) continue; if (IS_SET(pRoomIndex->room_flags, ROOM_NO_DREAM)) continue; break; } if (!pRoomIndex) { send_to_char("You can't find a place to land.\n\r", ch); 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, pRoomIndex ); act( AT_MAGIC, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); } } 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" ); } else if (!str_cmp(arg, "watch") && ch->curr_talent[TAL_DREAM] >= 25) { victim = get_char_world(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if (!IS_AFFECTED(ch, AFF_DREAMWORLD)) { act( AT_MAGIC, "You need to be in the dreamworld to cast that.", ch, NULL, NULL, TO_CHAR); return; } location = victim->in_room; if (!location) { send_to_char("You can't find them.\n\r", ch); return; } original = ch->in_room; char_from_room( ch ); char_to_room( ch, location ); do_look( ch, "auto" ); char_from_room( ch ); char_to_room( ch, original ); } else { send_to_char("You don't know how to do that.\n\r", ch); return; } use_magic(ch, TAL_DREAM, 200 - ch->curr_talent[TAL_DREAM]); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_connect(CHAR_DATA *ch, char *argument) { char buf[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; if (ch->curr_talent[TAL_MIND] < 10) { huh(ch); return; } if ( !argument || argument[0] == '\0' ) { send_to_char( "Telepathically connect to whom?\n\r", ch ); return; } argument = one_argument(argument, arg); victim = get_char_world(ch, arg); if ((!victim) || IS_NPC(victim) || IS_NPC(ch)) { send_to_char("They aren't here.\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 (argument[0] != '\0' && ch != victim) { sprintf( buf, "&pYou tell %s telepathically '%s'\n\r", victim->name, argument); send_to_char(buf, ch); sprintf( buf, "&p%s telepathically tells you '%s'\n\r", ch->name, argument); send_to_char(buf, victim); use_magic(ch, TAL_MIND, 10); return; } if ( ch == victim ) { if (ch->pcdata->mindlink) { victim = ch->pcdata->mindlink; send_to_char( "Your telepathic connection is broken.\n\r", victim); victim->pcdata->mindlink = NULL; send_to_char( "You break your telepathic connection.\n\r", ch); ch->pcdata->mindlink = NULL; } else { send_to_char("You aren't telepathically connected.\n\r", ch); } return; } if (ch->pcdata->mindlink) { send_to_char("You are already linked to someone.\n\r", ch); return; } if (victim->pcdata->mindlink) { send_to_char("They are already linked to someone.\n\r", ch); return; } use_magic(ch, TAL_MIND, 25); sprintf(buf, "You open your mind in a telepathic connection to %s.\n\r", victim->name); send_to_char(buf, ch); sprintf(buf, "%s opens a telepathic connection to you.\n\r", ch->name); send_to_char(buf, victim); ch->pcdata->mindlink = victim; victim->pcdata->mindlink = ch; } void do_think(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if (ch->pcdata->mindlink) { victim = ch->pcdata->mindlink; } else { ch_printf(ch, "&pYou think '%s'\n\r", argument); for (victim = ch->in_room->first_person;victim;victim = victim->next_in_room) { if (victim == ch) continue; if (TALENT(victim, TAL_MIND) >= number_percent()) ch_printf(victim, "&p%s thinks '%s'\n\r", ch->name, argument); } return; } ch_printf( ch, "&pYou think '%s'\n\r", argument); ch_printf( victim, "&p%s thinks '%s'\n\r", ch->name, argument); } /* * Improved version of reanimate -keo * Now restores exp lost from death, July 9, 2001 */ void do_resurrect( CHAR_DATA *ch, char *argument ) { CHAR_DATA *mob; OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *obj_next; MOB_INDEX_DATA *pMobIndex; AFFECT_DATA af; CHAR_DATA *victim; DESCRIPTOR_DATA *d; PART_DATA *part; int amt; if (ch->curr_talent[TAL_DEATH] < 100 || ch->curr_talent[TAL_HEALING] < 100) { huh(ch); return; } corpse = get_obj_here(ch, argument); if (!corpse) { send_to_char("You see nothing like that here.\n\r", ch); return; } for ( d = first_descriptor; d; d = d->next ) { if (d->connected == CON_PLAYING) if (nifty_is_name(d->character->name, corpse->name)) { victim = d->character; if (ch->mana < victim->perm_con*10) { send_to_char("You dont have enough energy to resurrect this corpse.\n\r", ch); return; } 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 ((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 += corpse->cost; if ( get_timer( victim, TIMER_PKILLED ) > 0 ) remove_timer( victim, TIMER_PKILLED ); use_magic(ch, TAL_HEALING, 1500); act(AT_WHITE, "A radiant white aura surrounds the corpse of $n.", victim, NULL, NULL, TO_ROOM); while ((obj = corpse->first_content)) { obj_from_obj(obj); if ( obj->item_type == ITEM_MONEY ) { amt = obj->value[0]; ch->gold += amt; extract_obj( obj ); } else { obj_to_char(obj, victim); } } separate_obj(corpse); extract_obj(corpse); 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; WAIT_STATE(ch, PULSE_VIOLENCE*4); WAIT_STATE(victim, PULSE_VIOLENCE*2); /* 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); } return; } } /* end player resurrection */ /* mob resurrection disabled for the moment */ send_to_char("You can't resurrect that.\n\r", ch); return; if ( (pMobIndex = get_mob_index((sh_int) abs(corpse->cost) )) == NULL ) { bug("Can not find mob for cost of corpse, do_resurrect", 0); return; } if ( ch->mana - (pMobIndex->perm_con*50) < 0 ) { send_to_char("You do not have enough mana to resurrect this corpse.\n\r", ch); return; } if ( ( chance(ch, 75) && pMobIndex->perm_con - ch->curr_talent[TAL_DEATH] < 10)) { mob = create_mobile( pMobIndex ); char_to_room( mob, ch->in_room ); use_magic(ch, TAL_HEALING, ch->mana); act(AT_MAGIC, "$n resurrect $T!", ch, NULL, pMobIndex->short_descr, TO_ROOM); act(AT_MAGIC, "You resurrect $T!", ch, NULL, pMobIndex->short_descr, TO_CHAR); add_follower( mob, ch ); if (corpse->timer > 0) { af.type = gsn_charm_person; af.duration = (number_fuzzy( corpse->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); } if (corpse->first_content) for( obj = corpse->first_content; obj; obj = obj_next) { obj_next = obj->next_content; obj_from_obj(obj); obj_to_char(obj, mob); } separate_obj(corpse); extract_obj(corpse); ch->mental_state = -100; WAIT_STATE(ch, PULSE_VIOLENCE*2); return; } else { send_to_char("You fail to reanimate the corpse.\n\r", ch); use_magic(ch, TAL_HEALING, 300 - ch->curr_talent[TAL_DEATH]*2); WAIT_STATE(ch, PULSE_VIOLENCE); } } void do_identify( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; AFFECT_DATA *paf; SKILLTYPE *sktmp; CHAR_DATA *victim; char *name; if (ch->curr_talent[TAL_SEEKING] <= 0) { send_to_char("You are unable to do that.\n\r",ch); return; } if ( argument[0] == '\0' ) { send_to_char( "Identify what?\n\r", ch ); return; } if ( ( obj = get_obj_here( ch, argument ) ) == NULL) if ( ( victim = get_char_room( ch, argument ) ) == NULL ) { ch_printf(ch, "You can't find %s!\n\r", argument ); return; } WAIT_STATE(ch, PULSE_VIOLENCE); use_magic(ch, TAL_SEEKING, 20); if ( ( obj = get_obj_here( ch, argument ) ) != NULL ) { int gp; set_char_color( AT_LBLUE, ch ); 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); 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 > 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); set_char_color( AT_MAGIC, ch ); 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_WAND: case ITEM_STAFF: if (ch->curr_talent[TAL_SEEKING] >= 20) { ch_printf( ch, "Has %d out of %d charges left of", obj->value[1], obj->value[2] ); 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_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; } if (ch->curr_talent[TAL_SEEKING] >= 15) { 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 ); } } /* START CHARACTER IDENTIFY */ else if ( ( victim = get_char_room( ch, argument ) ) != NULL ) { 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)) { DEITY_DATA *talent; 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] >= 75 && 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); } } } } } void do_enchant( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; AFFECT_DATA *paf; int tal; int amt; char arg2[MAX_INPUT_LENGTH]; bool found; argument = one_argument(argument, arg2); obj=get_obj_carry(ch, arg2); if (!obj) { send_to_char("You don't have that.\n\r", ch); return; } if ( IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { act( AT_MAGIC, "Your magic twists and winds around $p but cannot take hold.", ch, obj, NULL, TO_CHAR ); return; } separate_obj(obj); amt = 50; tal = TAL_CATALYSM; found = FALSE; if (obj->mana < amt) { send_to_char("That item doesn't have enough energy to hold the enchantment.\n\r", ch); return; } if (!str_cmp(argument, "magic")) { if (IS_OBJ_STAT(obj, ITEM_MAGIC)) { send_to_char("That item is already magic.\n\r", ch); return; } if (ch->curr_talent[tal] < 40) { send_to_char("You can't imbue something with magic.\n\r", ch); return; } act(AT_MAGIC, "You imbue $p with a field of magic.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_MAGIC); } else if (!str_cmp(argument, "shield")) { tal = TAL_SECURITY; amt = 500; if (IS_OBJ_STAT(obj, ITEM_SHIELD)) { send_to_char("That item already emits a forcefield.\n\r", ch); return; } if (ch->curr_talent[TAL_SECURITY] + ch->curr_talent[TAL_CATALYSM] < 195) { send_to_char("You can't imbue something with a forcefield.\n\r", ch); return; } if (obj->mana < amt) { send_to_char("That item does not have enough energy to sustain the enchantment.\n\r", ch); return; } act(AT_MAGIC, "You imbue $p with a protective forcefield.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_SHIELD); } else if (!str_cmp(argument, "returning")) { tal = TAL_MOTION; amt = 100; if (IS_OBJ_STAT(obj, ITEM_RETURNING)) { send_to_char("That item is already returning.\n\r", ch); return; } if (ch->curr_talent[TAL_MOTION] < 50 && TALENT(ch, TAL_MOTION) < 50) { send_to_char("You can't enchant somthing to return when thrown.\n\r", ch); return; } if (obj->mana < amt) { send_to_char("That item does not have enough energy to hold the enchantment.\n\r", ch); return; } act(AT_MAGIC, "You enchant $p to return when thrown.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_RETURNING); } else if (!str_cmp(argument, "durable")) { tal = TAL_SECURITY; amt = 200; if (IS_OBJ_STAT(obj, ITEM_DURABLE)) { send_to_char("That item is already durable.\n\r", ch); return; } if (ch->curr_talent[TAL_SECURITY] + ch->curr_talent[TAL_VOID] < 100) { send_to_char("You can't imbue something with durability.\n\r", ch); return; } if (obj->mana < amt) { send_to_char("That item needs 200 energy to sustain this enchantment.\n\r", ch); return; } act(AT_MAGIC, "You imbue $p with durability.", ch, obj, NULL, TO_CHAR); xSET_BIT(obj->extra_flags, ITEM_DURABLE); } else if (!str_cmp(argument, "breath") && ch->curr_talent[TAL_WATER] >= 40) { tal = TAL_WATER; if (found==FALSE) { 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_MAGIC, "You imbue $p with magical breathing.", ch, obj, NULL, TO_CHAR); } } else if (!str_cmp(argument, "flight") && ch->curr_talent[TAL_WIND] >= 60) { tal = TAL_WIND; if (found==FALSE) { 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_MAGIC, "You imbue $p with the power of flight.", ch, obj, NULL, TO_CHAR); } } else if (!str_cmp(argument, "nightvision") && ch->curr_talent[TAL_SEEKING] >= 35) { tal = TAL_SEEKING; if (found==FALSE) { CREATE(paf, AFFECT_DATA, 1); paf->type = -1; paf->duration = -1; paf->location = APPLY_AFFECT; SET_BIT(paf->modifier, 1 << AFF_INFRARED); xCLEAR_BITS(paf->bitvector); paf->next = NULL; LINK(paf, obj->first_affect, obj->last_affect, next, prev); act(AT_MAGIC, "You imbue $p with nightvision.", ch, obj, NULL, TO_CHAR); } } else if (!str_cmp(argument, "armor") && obj->item_type == ITEM_ARMOR) { tal = TAL_SECURITY; if (TALENT(ch, tal) / 10 > (obj->value[0] - obj->pIndexData->value[0])) { act(AT_MAGIC, "You enhance the protective ability of $p.", ch, obj, NULL, TO_CHAR); obj->value[0]++; } else { send_to_char("You are not strong enough to further enchant that item.\n\r", ch); return; } } else if (!str_cmp(argument, "weapon") && (obj->item_type == ITEM_WEAPON || obj->item_type == ITEM_MISSILE_WEAPON) && ch->curr_talent[TAL_DEATH] >= 10) { tal = TAL_DEATH; amt = URANGE(10, 250 - TALENT(ch, TAL_DEATH), 200); amt += obj->value[2]; if (obj->mana < amt) { send_to_char("This item can't hold the enchantment.\n\r", ch); return; } obj->value[2] += 5; act(AT_MAGIC, "You imbue $p with the power of Death.", ch, obj, NULL, TO_CHAR); } else if (!str_cmp(argument, "weight")) { if (obj->weight > 1 && TALENT(ch, tal) / 10 > (obj->pIndexData->weight - obj->weight)) { act(AT_MAGIC, "You magically lighten $p.", ch, obj, NULL, TO_CHAR); obj->weight--; } else { send_to_char("You can't lighten that item any further.\n\r", ch); return; } } else if (!str_prefix(argument, "constitution")) { tal = TAL_EARTH; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CON && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the strength of the Earth.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "endurance")) { tal = TAL_FROST; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_LCK && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); return; } paf->modifier++; 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_MAGIC, "You enchant $p with the strength of the Ice.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "strength")) { tal = TAL_FIRE; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_STR && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the strength of the Flames.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "perception")) { tal = TAL_SEEKING; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_CHA && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the power of Seeking.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "dexterity")) { tal = TAL_WIND; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DEX && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the speed of the Wind.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "willpower")) { tal = TAL_WATER; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_WIS && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the power of Water.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the power of Water.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "intelligence")) { tal = TAL_MIND; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_INT && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the power of the Mind.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "damroll")) { tal = TAL_LIGHTNING; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_DAMROLL && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the strength of the Storm.", ch, obj, NULL, TO_CHAR); } } else if (!str_prefix(argument, "hitroll")) { tal = TAL_MOTION; for (paf = obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_HITROLL && !found) { if (TALENT(ch, tal) / 10 > paf->modifier) { act(AT_MAGIC, "You enchant $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); paf->modifier++; } else { send_to_char("You are not strong enough to further", ch); send_to_char(" enchant this item.\n\r", ch); 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_MAGIC, "You enchant $p with the speed of Motion.", ch, obj, NULL, TO_CHAR); } } else if (!str_cmp(argument, "container") && (obj->item_type == ITEM_CONTAINER && ch->curr_talent[TAL_VOID] >= 10)) { tal = TAL_VOID; amt = URANGE(10, 250 - TALENT(ch, TAL_VOID), 200); amt += obj->value[0] / 10; if (obj->mana < amt) { send_to_char("This item can't hold the enchantment.\n\r", ch); return; } obj->value[0] += TALENT(ch, TAL_VOID) / 10; act(AT_MAGIC, "You imbue $p with the power of the Void.", ch, obj, NULL, TO_CHAR); } else { send_to_char("You can't add any such enchantment.\n\r", ch); return; } WAIT_STATE(ch, PULSE_VIOLENCE*2); obj->mana -= amt; use_magic(ch, tal, amt*5); obj->cost += 50000; } void do_preserve( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; int lvl; obj=get_obj_here(ch, argument); if (!obj) { send_to_char("You dont have that.\n\r", ch); return; } lvl = TALENT(ch, TAL_EARTH) + TALENT(ch, TAL_DEATH) + TALENT(ch, TAL_FROST) + TALENT(ch, TAL_TIME) + TALENT(ch, TAL_VOID) + TALENT(ch, TAL_CATALYSM); if (lvl <= 0) { huh(ch); return; } if (obj->timer <= 0 || IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { act( AT_MAGIC, "$p is not deteriorating.", ch, obj, NULL, TO_CHAR); return; } if (lvl >= 100) obj->timer = 0; else obj->timer = lvl; act( AT_MAGIC, "$p flickers for a moment.", ch, obj, NULL, TO_CHAR); WAIT_STATE(ch, PULSE_VIOLENCE); use_magic(ch, TAL_CATALYSM, 600 - lvl); } void do_retrieve( CHAR_DATA *ch, char *argument) { char buf3[MAX_STRING_LENGTH]; OBJ_DATA *obj; bool found; CHAR_DATA *victim; if ( ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_MOTION] < 95 ) { huh(ch); return; } victim = get_char_world(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } 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; sprintf(buf3, " "); 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 suddenly wavers away.", victim, NULL, NULL, TO_CHAR ); act( AT_MAGIC, "The image of $n's corpse appears, but suddenly wavers away.", victim, NULL, NULL, TO_ROOM ); return; } use_magic(ch, TAL_DEATH, 1000 - ch->curr_talent[TAL_DEATH] * 9); 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); } /* Summer 1997 --Blod */ /* Modified for players Oct 12 2000 -keo */ /* Support for objects Nov 29 2000 -keo */ void do_scatter( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; ROOM_INDEX_DATA *pRoomIndex; OBJ_DATA *obj; if (ch->curr_talent[TAL_MOTION] < 70) { huh(ch); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Scatter what?\n\r", ch ); return; } if ( (victim = get_char_room( ch, arg )) == NULL && (obj = get_obj_carry( ch, arg )) == NULL ) { send_to_char( "You see nothing like that here.\n\r", ch ); return; } if (victim) { if ( victim == ch ) { send_to_char( "It's called travel. Try it.\n\r", ch ); return; } if (ch->curr_talent[TAL_MOTION] < 100 && (IS_SET(ch->in_room->room_flags, ROOM_NO_ASTRAL) || IS_NPC(victim))) { send_to_char("Your magic fails to take hold.\n\r", ch); return; } } for ( ; ; ) { pRoomIndex = get_room_index( number_range( 0, 1048576000 ) ); if ( pRoomIndex ) if ( !IS_SET(pRoomIndex->room_flags, ROOM_PRIVATE) && !IS_SET(pRoomIndex->room_flags, ROOM_SOLITARY) && !IS_SET(pRoomIndex->room_flags, ROOM_NO_ASTRAL) && !IS_SET(pRoomIndex->room_flags, ROOM_PROTOTYPE) ) break; } use_magic(ch, TAL_MOTION, 750 - ch->curr_talent[TAL_MOTION]*4); if (victim) { act( AT_MAGIC, "With the sweep of an arm, $n flings $N to the winds.", ch, NULL, victim, TO_NOTVICT ); act( AT_MAGIC, "With the sweep of an arm, $n flings you to the winds.", ch, NULL, victim, TO_VICT ); act( AT_MAGIC, "With the sweep of an arm, you fling $N to the winds.", ch, NULL, victim, TO_CHAR ); char_from_room( victim ); victim->in_obj = NULL; char_to_room( victim, pRoomIndex ); victim->position = POS_RESTING; act( AT_MAGIC, "$n staggers forth from a sudden gust of wind, and collapses.", victim, NULL, NULL, TO_ROOM ); do_look( victim, "auto" ); } else if (obj) { 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, pRoomIndex); } WAIT_STATE(ch, PULSE_VIOLENCE); } void do_reshape(CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; int lvl; argument = one_argument(argument, arg); obj=get_obj_carry(ch, arg); if (!obj) { send_to_char("You don't have that.\n\r", ch); return; } lvl = ch->curr_talent[TAL_CHANGE] + ch->curr_talent[TAL_CATALYSM] + ch->curr_talent[TAL_ILLUSION]; if (lvl < 95) { if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) { if ( ch->curr_talent[TAL_DREAM] < 40) { huh(ch); return; } } else { if (!obj->material || obj->material->number == 116) { /* ether */ if ( ch->curr_talent[TAL_VOID] < 30) { huh(ch); return; } } else { huh(ch); return; } } } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { send_to_char("Your magic won't take hold.\n\r", ch); return; } if (!argument || argument[0] == '\0') { send_to_char("Reshape it to what?\n\r", ch); return; } 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); use_magic(ch, TAL_CATALYSM, 1000 - lvl*3); WAIT_STATE(ch, PULSE_VIOLENCE); } void do_void(CHAR_DATA *ch, char *argument) { int i, vnum; CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; AREA_DATA *pArea; ROOM_INDEX_DATA *pRoomIndex; if (number_range(1, 100) > TALENT(ch, TAL_VOID)) { travel_teleport(ch); lose_hp(ch, number_range(1, 100)); return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "enter") && ch->curr_talent[TAL_VOID] >= 1) { if (IS_AFFECTED(ch, AFF_VOID)) { send_to_char("You are already in the Void!\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_DREAMWORLD)) { huh(ch); return; } 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); } else if (!str_cmp(arg, "leave") && ch->curr_talent[TAL_VOID] >= 20) { if (!IS_AFFECTED(ch, AFF_VOID)) { send_to_char("You aren't in the Void!\n\r", ch); return; } 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); } else if (!str_cmp(arg, "pull") && ch->curr_talent[TAL_VOID] >= 35) { victim = get_char_room(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_DREAMWORLD)) { send_to_char("You are unable to touch them.\n\r", ch); return; } if (IS_NPC(victim) && xIS_SET(victim->act, ACT_PACIFIST)) { send_to_char("Stop that you twit, don't void pacifists.\n\r",ch); return; } 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"); return; } else if (!str_cmp(arg, "extract") && ch->curr_talent[TAL_VOID] >= 45) { victim = get_char_room(ch, argument); if (!victim) { send_to_char("They aren't here.\n\r", ch); return; } 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"); return; } else if (!str_cmp(arg, "shift") && ch->curr_talent[TAL_VOID] >= 50) { if ( !IS_AFFECTED(ch, AFF_VOID) ) { act( AT_MAGIC, "You need to be in the Void to do that that.", ch, NULL, NULL, TO_CHAR); return; } victim = get_char_world(ch, argument); if (!victim) { /* Start travel to location */ for(pArea = first_area; pArea; pArea = pArea->next) { if((arg[0] == '\0' || nifty_is_name_prefix(argument, pArea->name)) && !IS_SET(pArea->flags, AFLAG_NOTRAVEL)) { for (i = 0;i < 20;i++) { vnum = number_range(pArea->low_r_vnum, pArea->hi_r_vnum); if ((pRoomIndex = get_room_index(vnum)) == NULL) continue; break; } if (!pRoomIndex) { send_to_char("You can't find a place to land.\n\r", ch); return; } 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, pRoomIndex ); act( AT_DGREY, "$n slows fades into view.", ch, NULL, NULL, TO_ROOM); do_look( ch, "auto" ); } } send_to_char("You can't find anyplace like that.\n\r", ch); return; } if (victim == ch) { send_to_char("That was a shoft trip!\n\r", ch); return; } 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" ); } else if (!str_cmp(arg, "rift") && ch->curr_talent[TAL_VOID] >= 80) { if (!IS_AFFECTED(ch, AFF_VOID)) { send_to_char("You need to be in the Void to do that.\n\r", ch); return; } victim = get_char_world(ch, argument); if (!victim || (IS_NPC(victim) && !xIS_SET(victim->act, ACT_NAMED))) victim = generate_mob_nation(argument); if (!victim) { send_to_char("You cannot find anything like that.", ch); return; } if (victim == ch) { send_to_char("That was a shoft trip!\n\r", ch); return; } 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" ); } else { send_to_char("You can't do any such thing.\n\r", ch); return; } WAIT_STATE(ch, PULSE_VIOLENCE); use_magic(ch, TAL_VOID, 1000 - ch->curr_talent[TAL_VOID]*9); } void do_decay( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; int lvl; obj=get_obj_carry(ch, argument); if (!obj) { send_to_char("You dont have that.\n\r", ch); return; } lvl = (ch->curr_talent[TAL_TIME] + ch->curr_talent[TAL_EARTH] + ch->curr_talent[TAL_CATALYSM] + ch->curr_talent[TAL_DEATH] + ch->curr_talent[TAL_VOID]) / 2; if (lvl <= 0) { huh(ch); return; } 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); if (lvl < 40) obj->timer -= lvl; else obj->timer -= 40; if (obj->timer < 1) obj->timer = 1; WAIT_STATE(ch, PULSE_VIOLENCE); use_magic(ch, TAL_DEATH, 600 - lvl); return; } void player_echo( CHAR_DATA *ch, sh_int AT_COLOR, char *argument, sh_int tar ) { DESCRIPTOR_DATA *d; if ( !argument || argument[0] == '\0' ) return; for ( d = first_descriptor; d; d = d->next ) { if ( d->connected == CON_PLAYING ) { if (tar == ECHOTAR_AREA && ch->in_room->area != d->character->in_room->area) continue; if (tar == ECHOTAR_ROOM && ch->in_room != d->character->in_room) continue; if (tar == ECHOTAR_WORLD && str_cmp(ch->in_room->area->resetmsg, d->character->in_room->area->resetmsg)) continue; set_char_color( AT_COLOR, d->character ); send_to_char( argument, d->character ); send_to_char( "\n\r", d->character ); } } return; } void do_player_echo( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; sh_int color; int target; char *parg; int lvl = ch->curr_talent[TAL_SPEECH]; if (lvl < 30 && ch->curr_talent[TAL_ILLUSION] < 60) { huh(ch); return; } set_char_color( AT_PLAIN, ch ); if ( xIS_SET(ch->act, PLR_NO_EMOTE) ) { send_to_char( "You can't do that right now.\n\r", ch ); return; } if ( argument[0] == '\0' ) { send_to_char( "Echo what?\n\r", ch ); return; } if ( (color = get_color(argument)) ) argument = one_argument(argument, arg); parg = argument; argument = one_argument(argument, arg); if ( !str_cmp( arg, "room" )) target = ECHOTAR_ROOM; else if ( !str_cmp( arg, "area" ) && lvl >= 50) target = ECHOTAR_AREA; else if ( !str_cmp( arg, "world" ) && lvl >= 80) target = ECHOTAR_WORLD; else { if (lvl >= 100) target = ECHOTAR_ALL; else if (lvl >= 80) target = ECHOTAR_WORLD; else if (lvl >= 50) target = ECHOTAR_AREA; else target = ECHOTAR_ROOM; argument = parg; } if ( !color && (color = get_color(argument)) ) argument = one_argument(argument, arg); if ( !color ) color = AT_PLAIN; one_argument(argument, arg); player_echo( ch, color, argument, target ); mana_from_char (ch,500 - ch->curr_talent[TAL_SPEECH]*4); WAIT_STATE(ch, PULSE_VIOLENCE); learn_talent(ch, TAL_SPEECH); } void do_detonate(CHAR_DATA *ch, char *argument) { char arg[MAX_STRING_LENGTH]; OBJ_DATA *obj; argument = one_argument(argument, arg); obj=get_obj_carry(ch, arg); if (ch->curr_talent[TAL_FIRE] < 75) { huh(ch); return; } if (!obj) { send_to_char("You don't have one of those to add an explosive charge to.\r\n",ch); return; } if (IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { send_to_char("Your magic fails to take hold.\n\r", ch); return; } if (!IS_OBJ_STAT(obj, ITEM_EXPLOSIVE)) { if (obj->weight < TALENT(ch, TAL_FIRE)) { 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 { send_to_char("You are not strong enough to detonate that.\n\r", ch); return; } } 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); } use_magic(ch, TAL_FIRE, 500); } void do_immobilize(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int lvl; if (IS_NPC(ch)) return; lvl = ch->curr_talent[TAL_EARTH] + ch->curr_talent[TAL_TIME] + ch->curr_talent[TAL_FROST]; if (lvl < 20) { huh(ch); return; } victim = find_target(ch, argument, TRUE); if (!victim) return; /* if they're frost, freeze */ if (ch->pcdata->inborn == TAL_FROST) { if (ch->in_room->area->weather->temp > ch->curr_talent[TAL_FROST]*10 - 400) { act(AT_FROST, "It isn't cold enough here.", ch, NULL, NULL, TO_CHAR); 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); } use_magic(ch, TAL_FROST, 100); return; } /* end freeze */ /* if they're earth, entangle */ if (ch->pcdata->inborn == TAL_EARTH) { if (ch->in_room->curr_vegetation < 100 - ch->curr_talent[TAL_EARTH]) { act(AT_GREEN, "There isn't enough vegetatation here.", ch, NULL, NULL, TO_CHAR); 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); } use_magic(ch, TAL_EARTH, 100); return; } /* end entangle */ /* otherwise, a generic hold */ if (lvl > number_range(20,60)) { 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); } use_magic(ch, TAL_TIME, 200); return; } void do_ventriloquate(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; char speaker[MAX_STRING_LENGTH]; CHAR_DATA *vch; if (ch->curr_talent[TAL_SPEECH] < 10) { huh(ch); return; } argument = one_argument(argument, speaker); sprintf(buf, "%s says '%s'\n\r", capitalize(speaker), argument); act(AT_SAY, "You make the words '$t' echo in the room.", ch, argument, NULL, TO_CHAR); use_magic(ch, TAL_SPEECH, 2000 - TALENT(ch, TAL_SPEECH)*10); for ( vch = ch->in_room->first_person; vch; vch = vch->next_in_room ) { set_char_color( AT_SAY, vch ); send_to_char( buf, vch ); } }