/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * _/ _/ * * _/_/_/ _/_/ _/_/_/ _/ _/_/ _/ _/ _/_/_/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/_/_/ _/ _/_/ _/_/_/ _/_/_/ * *************************************************************************** * Mindcloud Copyright 2001-2003 by Jeff Boschee (Zarius), * * Additional credits are in the help file CODECREDITS * * All Rights Reserved. * ***************************************************************************/ /* Daemons Ala Dunkirk? */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "interp.h" void frost_breath args((CHAR_DATA * ch, CHAR_DATA * victim, bool all)); void do_deathsense(CHAR_DATA * ch, char *argument) { if (ch->power[DISC_DAEM_NETH] < 2) { stc("You need level 2 Nether to use DeathSense.\n\r", ch); return; } if (IS_SET(ch->act, PLR_HOLYLIGHT)) { TOGGLE_BIT(ch->act, PLR_HOLYLIGHT); stc("Your unholy sight fades.\n\r", ch); return; } if (!IS_SET(ch->act, PLR_HOLYLIGHT)) { TOGGLE_BIT(ch->act, PLR_HOLYLIGHT); stc("Your eyes glow with unholy sight.\n\r", ch); return; } return; } void do_leech(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim = NULL; char buf[MAX_STRING_LENGTH]; if (ch->power[DISC_DAEM_NETH] < 4) { if (!IS_DEMPOWER(ch, DEM_LEECH)) { stc("You do not have that power.\n\r", ch); return; } } if (argument[0] == '\0') { stc("Who's life do you wish to leech off of?\n\r", ch); return; } if ((victim = get_char_room(ch, NULL, argument)) == NULL) { stc("They aren't here.\n\r", ch); return; } if (is_safe(ch, victim)) return; WAIT_STATE(ch, 10); act("$n stares intently at $N.", ch, NULL, victim, TO_NOTVICT); act("You stare intently at $N.", ch, NULL, victim, TO_CHAR); act("$n stares intently at you.", ch, NULL, victim, TO_VICT); if (victim->hit >= 1000) { sh_int power; sh_int dam; power = 20; dam = dice(power, power * 2); if (dam > 300) dam = 300 + (dam / 10); hurt_person(ch, victim, dam); ch->hit += dam; if (ch->hit >= ch->max_hit + 500) ch->hit = ch->max_hit + 500; xprintf(buf, "#RYou absorb %d hitpoints.#n\n\r", dam); stc(buf, ch); xprintf(buf, "#R%s absorbed %d of your hitpoints!#n\n\r", ch->name, dam); stc(buf, victim); } else stc("Nothing seemed to happen.\n\r", ch); return; } /* you really must take a look at this Jobo */ void do_entomb(CHAR_DATA * ch, char *argument) { char buf[MAX_STRING_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *objc; if (!IS_DEMPOWER(ch, DEM_ENTOMB) && ch->power[DISC_DAEM_GELU] < 6) { stc("You have not been granted that power.\n\r", ch); return; } if (ch->in_room->sector_type == SECT_AIR) { send_to_char("This ability cannot be used in the air.\n\r", ch); return; } if (!TIME_UP(ch, TIMER_ENTOMB) && ch->level < 12) { send_to_char ("This ability can only be used once every 12 hours.\n\r", ch); return; } if ((objc = get_obj_list(ch, "walln", ch->in_room->contents)) != NULL) objc = NULL; else { obj = create_object(get_obj_index(30043), 0); xprintf(buf, "A wall of ice is here, blocking your exit north."); free_string(obj->description); obj->description = str_dup(buf); obj_to_room(obj, ch->in_room); obj->timer = 5; obj->item_type = ITEM_WALL; } if ((objc = get_obj_list(ch, "walls", ch->in_room->contents)) != NULL) objc = NULL; else { obj = create_object(get_obj_index(30044), 0); xprintf(buf, "A wall of ice is here, blocking your exit south."); free_string(obj->description); obj->description = str_dup(buf); obj_to_room(obj, ch->in_room); obj->timer = 5; obj->item_type = ITEM_WALL; } if ((objc = get_obj_list(ch, "walle", ch->in_room->contents)) != NULL) objc = NULL; else { obj = create_object(get_obj_index(30045), 0); xprintf(buf, "A wall of ice is here, blocking your exit east."); free_string(obj->description); obj->description = str_dup(buf); obj_to_room(obj, ch->in_room); obj->timer = 5; obj->item_type = ITEM_WALL; } if ((objc = get_obj_list(ch, "wallw", ch->in_room->contents)) != NULL) objc = NULL; else { obj = create_object(get_obj_index(30046), 0); xprintf(buf, "A wall of ice is here, blocking your exit west."); free_string(obj->description); obj->description = str_dup(buf); obj_to_room(obj, ch->in_room); obj->timer = 5; obj->item_type = ITEM_WALL; } ch->hit += ch->max_hit * 0.1; if (ch->hit > ch->max_hit) ch->hit = ch->max_hit; SET_TIMER(ch, TIMER_ENTOMB, 12); act("$n calls forth sheets of ice, blocking your path in every direction.", ch, NULL, NULL, TO_ROOM); send_to_char("You call forth sheets of ice to entrap your prey.\n\r", ch); send_to_char("You grin wickedly.\n\r", ch); do_say(ch, "Prepare to die! Muahahahaha."); WAIT_STATE(ch, 10); return; } void do_gust(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; ROOM_INDEX_DATA *to_room = NULL; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; char buf[MAX_INPUT_LENGTH]; char direction[MAX_INPUT_LENGTH]; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int door; int rdir; int dam; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (ch->power[DISC_DAEM_GELU] < 7) { stc("You must achieve a level seven mastery of Geluge to use Gust.\n\r", ch); return; } if (!TIME_UP(ch, TIMER_CAN_GUST) && ch->level < 120) { send_to_char("You are out of breath.\n\r", ch); return; } if (arg1[0] == '\0') { send_to_char("Who do you wish to blow a gust of wind at?\n\r", ch); return; } if ((victim = get_char_room(ch, NULL, arg1)) == NULL) { send_to_char("They are not here.\n\r", ch); return; } if (victim == ch) { send_to_char("Not on yourself!\n\r", ch); return; } if (is_safe(ch, victim)) return; if (victim->size > ch->size) { send_to_char("They are too large to affect.\n\r", ch); return; } WAIT_STATE(ch, 12); if (!IS_NPC(ch) && number_percent() / 2 > ch->power[DISC_DAEM_GELU] + ch->generation) { send_to_char("You huff and puff but they do not budge.\n\r", ch); act("$n blows a gust of cold air into the room.", ch, NULL, NULL, TO_ROOM); return; } SET_TIMER(ch, TIMER_CAN_GUST, dice(1, 3) + 1); act("You breathe a gust of cold air at $N.", ch, NULL, victim, TO_CHAR); act("$n breathes a gust of cold air at $N.", ch, NULL, victim, TO_NOTVICT); act("$n breathes a gust of cold air at you.", ch, NULL, victim, TO_VICT); rdir = 0; if (arg2[0] == '\0') door = number_range(0, 3); else { if (!str_prefix(arg2, "north")) door = 0; else if (!str_prefix(arg2, "east")) door = 1; else if (!str_prefix(arg2, "south")) door = 2; else if (!str_prefix(arg2, "west")) door = 3; else { send_to_char ("You can only blow people north, south, east or west.\n\r", ch); return; } } if (door == 0) { xprintf(direction, "north"); rdir = 2; } if (door == 1) { xprintf(direction, "east"); rdir = 3; } if (door == 2) { xprintf(direction, "south"); rdir = 0; } if (door == 3) { xprintf(direction, "west"); rdir = 1; } if ((pexit = ch->in_room->exit[door]) == NULL) { xprintf(buf, "$N flies into the %s wall.", direction); act(buf, ch, NULL, victim, TO_NOTVICT); xprintf(buf, "$N flies into the %s wall.", direction); act(buf, ch, NULL, victim, TO_CHAR); xprintf(buf, "You smash into the %s wall.", direction); act(buf, ch, NULL, victim, TO_VICT); dam = dice(victim->size * 3 + 1, ch->power[DISC_DAEM_GELU] * 3); damage(ch, victim, dam, 0); return; } pexit = victim->in_room->exit[door]; if (IS_SET(pexit->exit_info, EX_CLOSED)) { if (IS_SET(pexit->exit_info, EX_LOCKED)) REMOVE_BIT(pexit->exit_info, EX_LOCKED); if (IS_SET(pexit->exit_info, EX_CLOSED)) REMOVE_BIT(pexit->exit_info, EX_CLOSED); xprintf(buf, "$N is blown into the air and flies %s.", direction); act(buf, ch, NULL, victim, TO_NOTVICT); xprintf(buf, "$N is blown into the air and flies %s.", direction); act(buf, ch, NULL, victim, TO_CHAR); xprintf(buf, "You are blown into the air and fly %s.", direction); act(buf, ch, NULL, victim, TO_VICT); xprintf(buf, "There is a loud crash as $n smashes through the $d."); act(buf, victim, NULL, pexit->keyword, TO_ROOM); if ((to_room = pexit->to_room) != NULL && (pexit_rev = to_room->exit[rdir]) != NULL && pexit_rev->to_room == ch->in_room && pexit_rev->keyword != NULL) { if (IS_SET(pexit_rev->exit_info, EX_LOCKED)) REMOVE_BIT(pexit_rev->exit_info, EX_LOCKED); if (IS_SET(pexit_rev->exit_info, EX_CLOSED)) REMOVE_BIT(pexit_rev->exit_info, EX_CLOSED); if (door == 0) xprintf(direction, "south"); if (door == 1) xprintf(direction, "west"); if (door == 2) xprintf(direction, "north"); if (door == 3) xprintf(direction, "east"); char_from_room(victim); char_to_room(victim, to_room); xprintf(buf, "$n comes smashing in through the %s $d.", direction); act(buf, victim, NULL, pexit->keyword, TO_ROOM); dam = dice(victim->size * 3 + 1, ch->power[DISC_DAEM_GELU] * 7); damage(ch, victim, dam, 0); } } else { xprintf(buf, "$N flies %s.", direction); act(buf, ch, NULL, victim, TO_NOTVICT); xprintf(buf, "$N flies %s.", direction); act(buf, ch, NULL, victim, TO_CHAR); xprintf(buf, "You fly %s.", direction); act(buf, ch, NULL, victim, TO_VICT); if (door == 0) xprintf(direction, "south"); if (door == 1) xprintf(direction, "west"); if (door == 2) xprintf(direction, "north"); if (door == 3) xprintf(direction, "east"); char_from_room(victim); char_to_room(victim, pexit->to_room); xprintf(buf, "$n comes flying in from the %s.", direction); act(buf, victim, NULL, NULL, TO_ROOM); dam = dice(victim->size * 3 + 1, ch->power[DISC_DAEM_GELU] * 5); damage(ch, victim, dam, 0); } return; } void do_caust(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; if (!IS_DEMPOWER(ch, DEM_CAUST) && ch->power[DISC_DAEM_CORR] < 4) { stc("You have not been granted that power.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Which item do you wish to caust?\n\r", ch); return; } if ((obj = get_obj_carry(ch, argument, ch)) == NULL) { send_to_char("You are not carrying that item.\n\r", ch); return; } if (obj->item_type != ITEM_WEAPON) { send_to_char("That is not a weapon!\n\r", ch); return; } if (dice(1, 100) == 1) { act("$p is disintegrated by $n's poison.", ch, obj, NULL, TO_ROOM); act("Your poison eats through $p.", ch, obj, NULL, TO_CHAR); extract_obj(obj); return; } if (IS_WEAP(obj, WEAPON_POISON)) { act("$p is already coated with deadly poison.", ch, obj, NULL, TO_CHAR); return; } act("You run your tongue along $p, coating it with a sickly venom.", ch, obj, NULL, TO_CHAR); act("$n runs $m tongue along $p, coating it with a sickly venom.", ch, obj, NULL, TO_ROOM); WAIT_STATE(ch, 8); SET_BIT(obj->weapflags, WEAPON_POISON); obj->value[1] += 10 - ch->generation; obj->value[2] += 10 - ch->generation; } void do_chaosport(CHAR_DATA * ch, char *argument) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; if (ch->fighting != NULL) { victim = ch->fighting; } else { return; } if (ch->power[DISC_DAEM_DISC] < 4) { stc("You need at least level 4 in Discord to use Chaos Portal\n\r", ch); return; } if (ch->in_room != NULL) { if (IS_SET(ch->in_room->room_flags, ROOM_ARENA)) { send_to_char("Your in the arena.\n\r", ch); return; } } if (in_fortress(ch)) { send_to_char("Your in The Forbidden Fortress.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_WEBBED)) { send_to_char ("You are unable to move with all this sticky webbing on.\n\r", ch); return; } if (ch->fighting && IS_CLASS(ch->fighting, CLASS_MONK) && IS_SET(ch->fighting->newbits, NEW_JAWLOCK) && number_percent() > 30) { xprintf(buf, "Not with god holding you!"); send_to_char(buf, ch); act("$n cant escape god's mighty hold!", ch, NULL, victim, TO_ROOM); return; } if (ch->fighting && IS_CLASS(ch->fighting, CLASS_WEREWOLF) && IS_SET(ch->fighting->newbits, NEW_JAWLOCK) && number_percent() > 10) { xprintf(buf, "Not with %s's jaws clamped on your neck!", ch->fighting->name); send_to_char(buf, ch); act("$n cant escape $N's clamped jaws!", ch, NULL, ch->fighting, TO_ROOM); return; } if (ch->fighting != NULL) { if (number_range(1, 3) == 2) { stc("The powers of Chaos fail you.\n\r", ch); act("$n tries in vain to summon a chaos portal.", ch, NULL, NULL, TO_ROOM); SET_TIMER(ch, TIMER_CHAOSPORT, 3); WAIT_STATE(ch, 24); return; } } act("$n disappears through a rift in time.", ch, NULL, NULL, TO_ROOM); stc("You are swept away through a rift in time.\n\r", ch); if (ch->fighting != NULL) stop_fighting(ch, TRUE); char_from_room(ch); char_to_room(ch, get_random_room(ch)); stc("You reappear in a swirling storm of chaos.\n\r", ch); act("$n appears in a swirling wind of Chaos.", ch, NULL, NULL, TO_ROOM); do_look(ch, "auto"); WAIT_STATE(ch, 24); return; } void do_unnerve(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; if (!IS_CLASS(ch, CLASS_DEMON) && !IS_CLASS(ch, CLASS_ELEMENTAL)) { send_to_char("Huh.\n\r", ch); return; } if (IS_CLASS(ch, CLASS_DEMON) && !IS_DEMPOWER(ch, DEM_UNNERVE) && ch->power[DISC_DAEM_DISC] < 1) { stc("You have not been granted that power.\n\r", ch); return; } if (IS_CLASS(ch, CLASS_ELEMENTAL) && ch->pcdata->powers[ELEMENTAL_WATER] < 3 ) { send_to_char("You need level 3 in WATER to use unnerve.\n\r",ch); return; } if (argument[0] == '\0') { stc("Who do you wish to unnerve?\n\r", ch); return; } if ((victim = get_char_room(ch, NULL, argument)) == NULL) { stc("They aren't here.\n\r", ch); return; } if (number_range(1, 3) == 2) { do_say(ch, "#1Xeus Dominus Mortai!#n"); do_stance(victim, ""); WAIT_STATE(victim, 8); } WAIT_STATE(ch, 8); return; } void do_wfreeze(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; if (!IS_DEMPOWER(ch, DEM_FREEZEWEAPON) && ch->power[DISC_DAEM_GELU] < 1) { stc("You have not been granted that power.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Which item do you wish to freeze?\n\r", ch); return; } if ((obj = get_obj_carry(ch, argument, ch)) == NULL) { send_to_char("You are not carrying that item.\n\r", ch); return; } if (obj->item_type != ITEM_WEAPON) { send_to_char("That is not a weapon!\n\r", ch); return; } if (dice(1, 100) == 1) { act("$p freezes and shatters.", ch, obj, NULL, TO_ROOM); act("$p freezes and shatters.", ch, obj, NULL, TO_CHAR); extract_obj(obj); return; } if (IS_WEAP(obj, WEAPON_FROST)) { act("$p is already frozen.", ch, obj, NULL, TO_CHAR); return; } act("$p is surrounded by ice crystals.", ch, obj, NULL, TO_CHAR); act("$p, carried by $n is surrounded by ice crystals.", ch, obj, NULL, TO_ROOM); WAIT_STATE(ch, 8); SET_BIT(obj->weapflags, WEAPON_FROST); } int get_polymorph_power(CHAR_DATA * ch) { if (ch->class == CLASS_DEMON) return ch->power[DISC_DAEM_MORP] - 1; if (ch->level == 12) return 100; return 0; } void do_hellfire(CHAR_DATA * ch, char *argument) { int door; if (ch->power[DISC_DAEM_HELL] < 8) return; if (ch->in_room->sector_type == SECT_AIR) { send_to_char("This ability cannot be used in the air.\n\r", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { stc("You cannot desecrate this Holy Place.\n\r", ch); return; } if (!TIME_UP(ch, TIMER_HELLFIRE_SUMMON) && ch->level < 12) { send_to_char ("This ability can only be used once every 12 hours.\n\r", ch); return; } for (door = 0; door < 4; door++) { if (ch->in_room->exit[door] != NULL) make_wall(ch->in_room, door, EX_FIRE_WALL); } SET_TIMER(ch, TIMER_HELLFIRE_SUMMON, 12); stc("You summon the fires of hell!\n\r", ch); act("$n summons the Abyssal fires of Hell!", ch, NULL, NULL, TO_ROOM); } const sh_int revdir[6] = { 2, 3, 0, 1, 5, 4 }; void put_wall(ROOM_INDEX_DATA * room, int dir, int wall) { int timer; timer = dice(2, 2); switch (dir) { case DIR_NORTH: SET_RTIMER(room, RTIMER_WALL_NORTH, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_SOUTH, timer); break; case DIR_EAST: SET_RTIMER(room, RTIMER_WALL_EAST, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_WEST, timer); break; case DIR_SOUTH: SET_RTIMER(room, RTIMER_WALL_SOUTH, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_NORTH, timer); break; case DIR_WEST: SET_RTIMER(room, RTIMER_WALL_WEST, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_EAST, timer); break; case DIR_UP: SET_RTIMER(room, RTIMER_WALL_UP, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_DOWN, timer); break; case DIR_DOWN: SET_RTIMER(room, RTIMER_WALL_DOWN, timer); SET_RTIMER(room->exit[dir]->to_room, RTIMER_WALL_UP, timer); break; } room->exit[dir]->exit_info = wall; } void make_wall(ROOM_INDEX_DATA * room, int dir, int wall) { int was; bool makewall = TRUE; if (dir < 0 || dir > 5) { bug("Invalid direction (create wall)", 0); return; } if (room->exit[dir] == NULL) { bug("Cant make wall!!!!", 0); return; } was = room->exit[dir]->exit_info; if (was == EX_ICE_WALL && wall == EX_FIRE_WALL) { room_message(room, "The wall of ice bursts into flames."); room_message(room->exit[dir]->to_room, "The wall of ice bursts into flames."); } if (was == EX_FIRE_WALL && wall == EX_ICE_WALL) { room_message(room, "The wall of flames flickers blue for a second."); room_message(room->exit[dir]->to_room, "The wall of flames flickers blue for a second."); makewall = FALSE; } if (makewall) put_wall(room, dir, wall); if (room->exit[dir]->to_room == NULL) { bug("Exit doesnt lead anywhere (create wall).", 0); return; } if (room->exit[dir]->to_room->exit[revdir[dir]] == NULL) { bug("Reverse Exit doesnt lead anywhere (create wall).", 0); return; } if (makewall) put_wall(room->exit[dir]->to_room, revdir[dir], wall); } ROOM_INDEX_DATA *locate_obj(OBJ_DATA * obj) { if (obj->in_obj != NULL) return locate_obj(obj->in_obj); if (obj->carried_by != NULL) return obj->carried_by->in_room; return obj->in_room; } void do_seed(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; if (ch->power[DISC_DAEM_HELL] < 7) { stc("You must obtain a level seven Mastery of the Hellfire Discipline.\n\r", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { stc("You cannot desecrate this Holy Place!\n\r", ch); return; } if (argument[0] == '\0') { send_to_char ("Which item do you wish to plant with Deamonseed?\n\r", ch); return; } if ((obj = get_obj_carry(ch, argument, ch)) == NULL) { send_to_char ("You do not have that item in your inventory.\n\r", ch); return; } if (IS_OBJ_STAT2(obj, ITEM_DAEMONSEED)) { send_to_char("That item is already set to explode.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_BLESS) || IS_OBJ_STAT(obj, ITEM_ANTI_EVIL)) { send_to_char("You cannot affect such a holy item.\n\r", ch); return; } if (IS_SET(obj->quest, QUEST_ARTIFACT) || IS_SET(obj->quest, QUEST_RELIC)) { send_to_char("You cannot affect such a powerful item.\n\r", ch); return; } act("$p starts to shudder and vibrate in your hands.", ch, obj, NULL, TO_CHAR); act("$n lays $s hands on $p.", ch, obj, NULL, TO_ROOM); WAIT_STATE(ch, 12); SET_BIT(obj->extra_flags2, ITEM_DAEMONSEED); obj->timer = ch->generation / 2 + dice(1, 3); } void do_immolate(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; if (ch->power[DISC_DAEM_HELL] < 2) { if (!IS_DEMPOWER(ch, DEM_IMMOLATE)) { stc("You have not been granted that power.\n\r", ch); return; } } if (argument[0] == '\0') { send_to_char("Which item do you wish to immolate?\n\r", ch); return; } if ((obj = get_obj_carry(ch, argument, ch)) == NULL) { send_to_char("You are not carrying that item.\n\r", ch); return; } if (obj->item_type != ITEM_WEAPON) { send_to_char("That is not a weapon!\n\r", ch); return; } if (dice(1, 100) == 1) { act("$p explodes in a burst of flames.", ch, obj, NULL, TO_ROOM); act("$p explodes in a burst of flames.", ch, obj, NULL, TO_CHAR); damage(ch, ch, 500, gsn_inferno); extract_obj(obj); return; } if (IS_WEAP(obj, WEAPON_FLAMING)) { act("$p is already flaming.", ch, obj, NULL, TO_CHAR); return; } act("$p bursts into flames.", ch, obj, NULL, TO_CHAR); act("$p, carried by $n bursts into flames.", ch, obj, NULL, TO_ROOM); WAIT_STATE(ch, 8); SET_BIT(obj->weapflags, WEAPON_FLAMING); } void do_dinferno(CHAR_DATA * ch, char *argument) { CHAR_DATA *vch, *vch_next; char buf[MAX_STRING_LENGTH]; if (!IS_DEMPOWER(ch, DEM_INFERNO) && ch->power[DISC_DAEM_HELL] < 3) { send_to_char("You have not been granted that power.\n\r", ch); return; } if (!TIME_UP(ch, TIMER_INFERNO)) { xprintf(buf, "You cannot use Inferno for another %d hours.\n\r", ch->tick_timer[TIMER_INFERNO]); stc(buf, ch); return; } if (ch->hit > 0) { send_to_char("This is only used as a last resort.\n\r", ch); return; } act("$n explodes, sending forth a massive fireballs in all directions.", ch, NULL, NULL, TO_ROOM); send_to_char("You explode in a huge blast of abyssal flame.\n\r", ch); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch != ch) { damage(vch, ch, number_range(1500, 2000), gsn_inferno); damage(ch, ch, number_range(1500, 2000), gsn_inferno); fire_effect(vch, ch->level, 2000, TARGET_CHAR); } } WAIT_STATE(ch, 56); ch->hit = 10; update_pos(ch); SET_TIMER(ch, TIMER_INFERNO, 80); } void acid_effect(void *vo, int level, int dam, int target) { if (target == TARGET_ROOM) /* nail objects on the floor */ { ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo; OBJ_DATA *obj, *obj_next; for (obj = room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; acid_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_CHAR) /* do the effect on a victim */ { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj, *obj_next; /* * let's toast some gear */ for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; acid_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_OBJ) /* toast an object */ { OBJ_DATA *obj = (OBJ_DATA *) vo; OBJ_DATA *t_obj, *n_obj; int chance; char *msg; chance = level / 4 + dam / 10; if (chance > 25) chance = (chance - 25) / 2 + 25; if (chance > 50) chance = (chance - 50) / 2 + 50; if (IS_OBJ_STAT(obj, ITEM_BLESS)) chance -= 5; chance -= obj->level * 2; switch (obj->item_type) { default: return; case ITEM_CONTAINER: case ITEM_CORPSE_PC: case ITEM_CORPSE_NPC: msg = "$p fumes and dissolves."; break; case ITEM_STAFF: case ITEM_WAND: chance -= 10; msg = "$p corrodes and breaks."; break; case ITEM_SCROLL: chance += 10; msg = "$p is burned into waste."; break; } chance = URANGE(5, chance, 95); if (number_percent() > chance) return; if (IS_SET(obj->quest, QUEST_SPELLPROOF)) return; if (obj->carried_by != NULL) act(msg, obj->carried_by, obj, NULL, TO_ALL); else if (obj->in_room != NULL && obj->in_room->people != NULL) act(msg, obj->in_room->people, obj, NULL, TO_ALL); /* * get rid of the object */ if (obj->contains) /* dump contents */ { for (t_obj = obj->contains; t_obj != NULL; t_obj = n_obj) { n_obj = t_obj->next_content; obj_from_obj(t_obj); if (obj->in_room != NULL) obj_to_room(t_obj, obj->in_room); else if (obj->carried_by != NULL) obj_to_room(t_obj, obj->carried_by->in_room); else { extract_obj(t_obj); continue; } acid_effect(t_obj, level / 2, dam / 2, TARGET_OBJ); } } extract_obj(obj); return; } } void shock_effect(void *vo, int level, int dam, int target) { if (target == TARGET_ROOM) { ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo; OBJ_DATA *obj, *obj_next; for (obj = room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; shock_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_CHAR) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj, *obj_next; /* * toast some gear */ for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; shock_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_OBJ) { OBJ_DATA *obj = (OBJ_DATA *) vo; int chance; char *msg; chance = level / 4 + dam / 10; if (chance > 25) chance = (chance - 25) / 2 + 25; if (chance > 50) chance = (chance - 50) / 2 + 50; if (IS_OBJ_STAT(obj, ITEM_BLESS)) chance -= 5; chance -= obj->level * 2; switch (obj->item_type) { default: return; case ITEM_WAND: case ITEM_STAFF: chance += 10; msg = "$p overloads and explodes!"; break; } chance = URANGE(5, chance, 95); if (number_percent() > chance) return; if (IS_SET(obj->quest, QUEST_SPELLPROOF)) return; if (obj->carried_by != NULL) act(msg, obj->carried_by, obj, NULL, TO_ALL); else if (obj->in_room != NULL && obj->in_room->people != NULL) act(msg, obj->in_room->people, obj, NULL, TO_ALL); extract_obj(obj); return; } } void fire_effect(void *vo, int level, int dam, int target) { if (target == TARGET_ROOM) /* nail objects on the floor */ { ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo; OBJ_DATA *obj, *obj_next; for (obj = room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; fire_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_CHAR) /* do the effect on a victim */ { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj, *obj_next; /* * chance of blindness */ if (!IS_AFFECTED(victim, AFF_BLIND)) { AFFECT_DATA af; act("$n is blinded by smoke!", victim, NULL, NULL, TO_ROOM); act("Your eyes tear up from smoke...you can't see a thing!", victim, NULL, NULL, TO_CHAR); af.type = skill_lookup("fire breath"); af.duration = number_range(0, level / 10); af.location = APPLY_HITROLL; af.modifier = -20; af.bitvector = AFF_BLIND; affect_to_char(victim, &af); } /* * let's toast some gear! */ for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; fire_effect(obj, level, dam, TARGET_OBJ); } return; } if (target == TARGET_OBJ) /* toast an object */ { OBJ_DATA *obj = (OBJ_DATA *) vo; OBJ_DATA *t_obj, *n_obj; int chance; char *msg; chance = level / 4 + dam / 10; if (chance > 25) chance = (chance - 25) / 2 + 25; if (chance > 50) chance = (chance - 50) / 2 + 50; if (IS_OBJ_STAT(obj, ITEM_BLESS)) chance -= 5; chance -= obj->level * 2; switch (obj->item_type) { default: return; case ITEM_CONTAINER: msg = "$p ignites and burns!"; break; case ITEM_POTION: chance += 25; msg = "$p bubbles and boils!"; break; case ITEM_SCROLL: chance += 50; msg = "$p crackles and burns!"; break; case ITEM_STAFF: chance += 10; msg = "$p smokes and chars!"; break; case ITEM_WAND: msg = "$p sparks and sputters!"; break; case ITEM_FOOD: msg = "$p blackens and crisps!"; break; case ITEM_PILL: msg = "$p melts and drips!"; break; } chance = URANGE(5, chance, 95); if (number_percent() > chance) return; if (IS_SET(obj->quest, QUEST_SPELLPROOF)) return; if (obj->carried_by != NULL) act(msg, obj->carried_by, obj, NULL, TO_ALL); else if (obj->in_room != NULL && obj->in_room->people != NULL) act(msg, obj->in_room->people, obj, NULL, TO_ALL); if (obj->contains) { /* * dump the contents */ for (t_obj = obj->contains; t_obj != NULL; t_obj = n_obj) { n_obj = t_obj->next_content; obj_from_obj(t_obj); if (obj->in_room != NULL) obj_to_room(t_obj, obj->in_room); else if (obj->carried_by != NULL) obj_to_room(t_obj, obj->carried_by->in_room); else { extract_obj(t_obj); continue; } fire_effect(t_obj, level / 2, dam / 2, TARGET_OBJ); } } extract_obj(obj); return; } } void do_blink(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; if (IS_NPC(ch)) return; if (!IS_CLASS(ch, CLASS_DEMON)) { send_to_char("Huh?\n\r", ch); return; } if (ch->power[DISC_DAEM_ATTA] < 7) { if (!IS_DEMPOWER(ch, DEM_BLINK) && IS_CLASS(ch, CLASS_DEMON)) { stc("You need to get blink first.\n\r", ch); return; } } if (ch->fighting == NULL && argument[0] == '\0') { stc("Who do you wish to blink into combat with?\n\r", ch); return; } if (ch->fighting == NULL) { if ((victim = get_char_room(ch, NULL, argument)) == NULL) { stc("They aren't here.\n\r", ch); return; } if (ch == victim) { stc("not on yourself.\n\r", ch); return; } WAIT_STATE(ch, 40); SET_BIT(ch->flag3, AFF3_BLINK_1ST_RD); stop_fighting(ch, TRUE); stc("You pop out of existance.\n\r", ch); act("$n pops out of existance.", ch, NULL, NULL, TO_ROOM); ch->blinkykill = victim; SET_BIT(ch->affected_by2, EXTRA_BLINKY); return; } WAIT_STATE(ch, 40); victim = ch->fighting; SET_BIT(ch->flag3, AFF3_BLINK_2ND_RD); stop_fighting(ch, TRUE); stc("You pop out of existance.\n\r", ch); act("$n pops out of existance.", ch, NULL, NULL, TO_ROOM); ch->blinkykill = victim; } void do_graft(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; char arg[MAX_INPUT_LENGTH]; argument = one_argument(argument, arg); if (IS_NPC(ch)) return; if (!IS_CLASS(ch, CLASS_DEMON)) { send_to_char("Huh?\n\r", ch); return; } if (ch->power[DISC_DAEM_ATTA] < 5) { if (!IS_DEMPOWER(ch, DEM_GRAFT) && IS_CLASS(ch, CLASS_DEMON)) { stc("You need to get graft first.\n\r", ch); return; } } if (arg[0] == '\0') { stc("Which limb do you wish to graft on to yourself?\n\r", ch); return; } if ((obj = get_obj_carry(ch, arg, ch)) == NULL) { stc("You do not have that limb.\n\r", ch); return; } if (!IS_SET(obj->extra_flags2, ITEM_ARM)) { stc("That's not even an arm!\n\r", ch); return; } if (IS_SET(ch->newbits, THIRD_HAND) && IS_SET(ch->newbits, FOURTH_HAND)) { stc("You already have four arms!\n\r", ch); return; } if (!IS_SET(ch->newbits, FOURTH_HAND)) { act("You graft an arm onto your body.", ch, NULL, obj, TO_CHAR); act("$n grafts an arm onto $m body.", ch, NULL, obj, TO_ROOM); SET_BIT(ch->newbits, FOURTH_HAND); SET_TIMER(ch, TIMER_FOURTH_ARM_GOING, dice(ch->generation, 6)); WAIT_STATE(ch, 18); extract_obj(obj); return; } if (!IS_SET(ch->newbits, THIRD_HAND)) { act("You graft an arm onto your body.", ch, NULL, obj, TO_CHAR); act("$n grafts an arm onto $m body.", ch, NULL, obj, TO_ROOM); SET_BIT(ch->newbits, THIRD_HAND); SET_TIMER(ch, TIMER_THIRD_ARM_GOING, dice(ch->generation, 6)); WAIT_STATE(ch, 18); extract_obj(obj); return; } return; } void do_dgate(CHAR_DATA * ch, char *argument) { char arg1[MAX_INPUT_LENGTH]; DESCRIPTOR_DATA *d; CHAR_DATA *victim; argument = one_argument(argument, arg1); if (!IS_CLASS(ch, CLASS_DEMON)) { stc("Huh?\n\r", ch); return; } if (arg1[0] == '\0') { send_to_char("Gate whom?\n\r", ch); return; } if (!str_cmp(arg1, "all")) { if (ch->generation > 2) { send_to_char ("You do not yet have the power to gate all demons.\n\r", ch); } else { for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected == CON_PLAYING && d->character != ch && d->character->in_room != NULL && can_see(ch, d->character) && d->character->generation > ch->generation && d->character->class == CLASS_DEMON) { if (d->character->fighting != NULL) stop_fighting(d->character, TRUE); act("A scaly hand reaches down and drags $n away.", d->character, NULL, NULL, TO_ROOM); char_from_room(d->character); char_to_room(d->character, ch->in_room); act("You have successfully gated $N.", ch, NULL, d->character, TO_CHAR); act("$n has successfully gated $N.", ch, NULL, d->character, TO_NOTVICT); if (ch != d->character) act("$n has pulled you through the demonic void.", ch, NULL, d->character, TO_VICT); do_look(d->character, "auto"); send_to_char("Ok.\n\r", ch); } } } return; } if ((victim = get_char_world(ch, arg1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim->class != CLASS_DEMON) { send_to_char("You may only gate in demons.\n\r", ch); return; } if (victim->in_room == NULL) { send_to_char("They are in limbo.\n\r", ch); return; } if (victim->generation <= ch->generation) { send_to_char ("You may only gate one of lesser power than yourself.\n\r", ch); return; } if (!IS_NPC(victim) && !IS_IMMUNE(victim, IMM_SUMMON)) { send_to_char("Your powers seem to have failed you.\n\r", ch); return; } if (number_range(1, 10 - ch->generation) == 1) { send_to_char("Your powers seem to have failed you.\n\r", ch); send_to_char("You hear demonic chanting in the distance.\n\r", victim); return; } if (victim->fighting != NULL) stop_fighting(victim, TRUE); act("A scaly hand reaches down and drags $n away.", victim, NULL, NULL, TO_ROOM); char_from_room(victim); char_to_room(victim, ch->in_room); act("You have successfully gated $N.", ch, NULL, victim, TO_CHAR); act("$n has successfully gated $N.", ch, NULL, victim, TO_NOTVICT); if (ch != victim) act("$n has pulled you through the demonic void.", ch, NULL, victim, TO_VICT); do_look(victim, "auto"); send_to_char("Ok.\n\r", ch); } void do_frostbreath(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; argument = one_argument(argument, arg); if (ch->power[DISC_DAEM_GELU] < 2) { stc("You must obtain level two in Geluge to use Frostbreath.\n\r", ch); return; } if (!TIME_UP(ch, TIMER_CAN_BREATHE_FROST) && ch->level < 12) { send_to_char("You are out of breath.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Who do you wish to breathe on?\n\r", ch); return; } if (!str_cmp(arg, "all")) { CHAR_DATA *vch, *vch_next; for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch == ch) continue; if (is_safe(ch, vch) && (ch->fighting != vch || vch->fighting != ch)) continue; WAIT_STATE(ch, 24); SET_TIMER(ch, TIMER_CAN_BREATHE_FROST, 11 - ch->generation / 2); frost_breath(ch, vch, TRUE); } } if ((victim = get_char_room(ch, NULL, arg)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } WAIT_STATE(ch, 12); SET_TIMER(ch, TIMER_CAN_BREATHE_FROST, 9 - ch->generation / 2); frost_breath(ch, victim, FALSE); } void cold_effect(void *vo, int level, int dam, int target) { if (target == TARGET_ROOM) /* nail objects on the floor */ { ROOM_INDEX_DATA *room = (ROOM_INDEX_DATA *) vo; OBJ_DATA *obj, *obj_next; for (obj = room->contents; obj != NULL; obj = obj_next) { obj_next = obj->next_content; cold_effect(obj, level, dam, TARGET_OBJ); } return; } else if (target == TARGET_CHAR) /* whack a character */ { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj, *obj_next; /* * chill touch effect */ AFFECT_DATA af; int sn = skill_lookup("chill touch"); if (is_affected(victim, sn)) return; af.type = sn; af.duration = 6; af.location = APPLY_STR; af.modifier = -3; af.bitvector = 0; affect_to_char(victim, &af); /* * let's toast some gear */ for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; cold_effect(obj, level, dam, TARGET_OBJ); } return; } else if (target == TARGET_OBJ) /* toast an object */ { OBJ_DATA *obj = (OBJ_DATA *) vo; int chance; char *msg; chance = level / 4 + dam / 10; if (chance > 25) chance = (chance - 25) / 2 + 25; if (chance > 50) chance = (chance - 50) / 2 + 50; if (IS_OBJ_STAT(obj, ITEM_BLESS)) chance -= 5; chance -= obj->level * 2; switch (obj->item_type) { default: return; case ITEM_POTION: msg = "$p freezes and shatters!"; chance += 25; break; case ITEM_DRINK_CON: msg = "$p freezes and shatters!"; chance += 5; break; } chance = URANGE(5, chance, 95); if (number_percent() > chance) return; if (IS_SET(obj->quest, QUEST_SPELLPROOF)) return; if (obj->carried_by != NULL) act(msg, obj->carried_by, obj, NULL, TO_ALL); else if (obj->in_room != NULL && obj->in_room->people != NULL) act(msg, obj->in_room->people, obj, NULL, TO_ALL); extract_obj(obj); return; } } void frost_breath(CHAR_DATA * ch, CHAR_DATA * victim, bool all) { CHAR_DATA *vch, *vch_next; int dam; int power; if (IS_CLASS(ch, CLASS_DEMON)) power = ch->power[DISC_DAEM_GELU]; else power = 0; if (all) { dam = (ch->generation + 5 * power + 5) * 8; act("$n breathes forth a stream of frost over you.", ch, NULL, NULL, TO_ROOM); act("You breath forth a stream of frost.", ch, NULL, NULL, TO_CHAR); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch == ch) continue; if (is_safe(ch, vch) && (ch->fighting != vch || vch->fighting != ch)) continue; cold_effect(vch, ch->explevel, dam, TARGET_CHAR); damage(ch, vch, dam, skill_lookup("frost breath")); } return; } if (is_safe(ch, victim)) return; dam = ((10 - ch->generation + 3) * power + 3) * 20; act("$n breathes forth a stream of frost over $N.", ch, NULL, victim, TO_NOTVICT); act("$n breathes a stream of frost over you!", ch, NULL, victim, TO_VICT); act("You breath forth a stream of frost over $N.", ch, NULL, victim, TO_CHAR); damage(ch, victim, dam, skill_lookup("frost breath")); cold_effect(victim, ch->explevel, dam, TARGET_CHAR); }