/***************************************************************************** * All the racial skills * * -- Hannibal * *****************************************************************************/ #define unix 1 #if defined( macintosh ) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include "merc.h" /* * External functions. */ extern void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); extern void forge_obj args( ( CHAR_DATA *ch, OBJ_DATA *to_forge ) ); void do_headbutt( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; char arg [ MAX_INPUT_LENGTH ]; int timer = 24; int mod; int dmg; if ( ch->race != RACE_MINOTAUR ) { send_to_char( AT_GREY, "Wham! Ouch! You sure are no minotaur\n\r", ch ); return; } if ( ch->race_wait > 0 ) return; if ( !ch->fighting ) { send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch ); return; } one_argument( argument, arg ); victim = ch->fighting; if ( arg[0] != '\0' ) if ( !( victim = get_char_room( ch, arg ) ) ) { send_to_char(C_DEFAULT, "They aren't here.\n\r", ch ); return; } switch ( prime_class(ch) ) { case CLASS_MAGE: case CLASS_CLERIC: timer = 240; break; case CLASS_THIEF: timer = 180; break; case CLASS_WARRIOR: timer = 120; break; case CLASS_PSIONICIST: case CLASS_DRUID: timer = 240; break; case CLASS_RANGER: case CLASS_PALADIN: case CLASS_BARD: case CLASS_VAMPIRE: timer = 180; break; case CLASS_NECROMANCER: timer = 240; break; case CLASS_WEREWOLF: timer = 180; break; } mod = ch->level / 5; mod = UMAX( 1, mod ); timer = timer / mod; timer = ( timer < 24 ) ? 24 : timer; ch->race_wait = timer; act( AT_YELLOW, "You slam your head into $N's!", ch, NULL, victim, TO_CHAR ); act( AT_YELLOW, "$n slams his head into yours!", ch, NULL, victim, TO_VICT ); act( AT_YELLOW, "$n slams his head into $N's!", ch, NULL, victim, TO_NOTVICT ); dmg = number_range( ch->level, ch->level * 5 ); damage( ch, victim, dmg, gsn_headbutt ); STUN_CHAR( ch, 2, STUN_MAGIC ); if ( victim->position == POS_DEAD || ch->in_room != victim->in_room ) return; if ( number_percent() < 15 && victim->position != POS_STUNNED ) { act( AT_WHITE, "$N reels from the blow...", ch, NULL, victim, TO_CHAR ); act( AT_WHITE, "$N reels from the blow...", ch, NULL, victim, TO_NOTVICT ); act( AT_WHITE, "You real from the blow and feel disoriented.", ch, NULL, victim, TO_VICT ); STUN_CHAR( victim, 2, STUN_TOTAL ); victim->position = POS_STUNNED; } return; } void do_drowfire( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; CHAR_DATA *victim; if ( ch->race != RACE_DROW ) { send_to_char( AT_GREY, "Drowfire by a non-drow?\n\r", ch ); return; } if(argument[0] != '\0') { if(!(victim = get_char_room(ch, argument))) { send_to_char(C_DEFAULT, "They aren't here.\n\r", ch); return; } } else { if(!(victim = ch->fighting)) { send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch); return; } } if ( is_affected( victim, gsn_drowfire ) ) return; WAIT_STATE( ch, skill_table[gsn_drowfire].beats ); af.type = gsn_drowfire; af.level = ch->level; af.duration = ch->level / 10; af.location = APPLY_AC; af.modifier = 5 * ch->level; af.bitvector = 0; affect_to_char( victim, &af ); af.location = APPLY_HITROLL; af.modifier = 0 - ch->level / 5; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char(AT_PINK, "You are surrounded by a purple outline.\n\r", victim ); act(AT_PINK, "$n is surrounded by a purple outline.", victim, NULL, NULL, TO_ROOM ); if ( !victim->fighting ) set_fighting( victim, ch ); return; } void do_globedarkness( CHAR_DATA *ch, char *argument ) { ROOM_AFFECT_DATA raf; POWERED_DATA *pd; OBJ_DATA *globe; char buf[MAX_STRING_LENGTH]; bool found = FALSE; if ( ch->race != RACE_DROW ) { send_to_char(AT_GREY, "Huh?\n\r", ch ); return; } if ( argument[0] == '\0' ) { send_to_char( AT_DGREY, "Syntax: globe <create|dissipate|locate>\n\r", ch ); return; } if ( !str_cmp( argument, "locate" ) ) { for ( pd = ch->powered; pd; pd = pd->next ) { if ( pd->type == gsn_globedark ) { sprintf( buf, "Globe of Darkness&w, &W%s&w; &cCost&w: &R%d&w.\n\r", pd->room->name, pd->cost ); send_to_char( AT_DGREY, buf, ch ); found = TRUE; } } if ( !found ) send_to_char( AT_CYAN, "You are not sustaining any &zGlobes&w.\n\r", ch ); return; } if ( !str_cmp( argument, "dissipate" ) ) { if ( !is_raffected( ch->in_room, gsn_globedark ) ) { send_to_char( AT_CYAN, "There is no &zGlobe &cin this room&w.\n\r", ch ); return; } for ( pd = ch->powered; pd; pd = pd->next ) { if ( !pd ) break; if ( pd->type == gsn_globedark ) { found = TRUE; if ( pd->room == ch->in_room ) { send_to_char( AT_DGREY, "You wave your hand and the globe dissipates.\n\r", ch ); act( AT_DGREY, "The globe of darkness dissipates.", ch, NULL, NULL, TO_ROOM ); raffect_remove( ch->in_room, ch, pd->raf ); return; } } } if ( !found ) { send_to_char( AT_CYAN, "You are not sustaining any &zGlobes&w.\n\r", ch ); return; } send_to_char( AT_CYAN, "You are not powering the &zGlobe&c in this room.\n\r", ch ); return; } if ( !str_cmp( argument, "create" ) ) { if ( is_raffected( ch->in_room, gsn_globedark ) ) { send_to_char(AT_GREY, "A globe of darkness already sits in this room.\n\r", ch ); return; } globe = create_object( get_obj_index( OBJ_VNUM_WARD_PHYS ), 1 ); free_string( globe->name ); free_string( globe->short_descr ); free_string( globe->description ); globe->name = str_dup( "globe darkness" ); globe->short_descr = str_dup( "&za Globe of Darkness" ); globe->description = str_dup( "A &zGlobe of Darkness &Xsits upon the room." ); raf.type = gsn_globedark; raf.location = ROOM_NONE; raf.room = ch->in_room; raf.material = globe; raf.powered_by = ch; raffect_to_room( ch->in_room, ch, &raf ); send_to_char( AT_DGREY, "You raise your hand and place of globe of darkness upon the area!\n\r", ch ); act( AT_DGREY, "$n raises his hand and everything goes pitch black!", ch, NULL, NULL, TO_ROOM ); return; } do_globedarkness( ch, "" ); } void do_forge( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char buf[ MAX_INPUT_LENGTH ]; OBJ_DATA *obj, *hammer; int wear, lvl; long group1 = ITEM_ANTI_HUMAN + ITEM_ANTI_DROW + ITEM_ANTI_ELF + ITEM_ANTI_ELDER; long group2 = ITEM_ANTI_OGRE + ITEM_ANTI_TROLL + ITEM_ANTI_DEMON + ITEM_ANTI_MINOTAUR; long group3 = ITEM_ANTI_DWARF + ITEM_ANTI_HALFLING + ITEM_ANTI_SHADOW; long group4 = ITEM_ANTI_ILLITHID + ITEM_ANTI_GHOUL; long group5 = ITEM_ANTI_PIXIE; long group6 = ITEM_ANTI_LIZARDMAN; long antirace = 0; wear = 0; if ( ch->race != RACE_DWARF ) { send_to_char( AT_GREY, "You aren't a dwarf!\n\r", ch ); return; } if ( argument[0] == '\0' ) { send_to_char( AT_WHITE, "Syntax: Forge <obj> <race> <lvl>\n\r", ch ); send_to_char( AT_WHITE, " obj = ring necklace armor helm\n\r", ch ); send_to_char( AT_WHITE, " mask leggings boots gauntlets\n\r", ch ); send_to_char( AT_WHITE, " gauntlets armplates shield\n\r", ch ); send_to_char( AT_WHITE, " belt bracer anklet weapon\n\r", ch ); send_to_char( AT_WHITE, " race= any valid race. HELP FORGE RACES\n\r", ch ); send_to_char( AT_WHITE, " to see race groupings.\n\r", ch ); sprintf( buf, " lvl = minimum 30, maximum %d.\n\r", ch->level ); send_to_char( AT_WHITE, buf, ch ); send_to_char( AT_WHITE, " BASE cost to make item is: 100 gold * lvl\n\r", ch ); return; } if ( ch->in_room->vnum != ROOM_VNUM_SMITHY ) { send_to_char( AT_GREY, "You cannot forge equipment here.\n\r", ch ); return; } for ( hammer = ch->carrying; hammer; hammer = hammer->next ) { if ( hammer->pIndexData->vnum == OBJ_VNUM_SMITHY_HAMMER && hammer->wear_loc == WEAR_HOLD ) break; } if ( !hammer ) { send_to_char( AT_GREY, "You must hold a smithy hammer to forge something.\n\r", ch ); return; } argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); if ( !str_prefix( arg, "ring" ) ) wear = ITEM_WEAR_FINGER; if ( !str_prefix( arg, "necklace" ) ) wear = ITEM_WEAR_NECK; if ( !str_prefix( arg, "armor" ) ) wear = ITEM_WEAR_BODY; if ( !str_prefix( arg, "helm" ) ) wear = ITEM_WEAR_HEAD; if ( !str_prefix( arg, "mask" ) ) wear = ITEM_WEAR_FACE; if ( !str_prefix( arg, "leggings" ) ) wear = ITEM_WEAR_LEGS; if ( !str_prefix( arg, "boots" ) ) wear = ITEM_WEAR_FEET; if ( !str_prefix( arg, "gauntlets" ) ) wear = ITEM_WEAR_HANDS; if ( !str_prefix( arg, "armplates" ) ) wear = ITEM_WEAR_ARMS; if ( !str_prefix( arg, "shield" ) ) wear = ITEM_WEAR_SHIELD; if ( !str_prefix( arg, "belt" ) ) wear = ITEM_WEAR_WAIST; if ( !str_prefix( arg, "bracer" ) ) wear = ITEM_WEAR_WRIST; if ( !str_prefix( arg, "anklet" ) ) wear = ITEM_WEAR_ANKLE; if ( !str_prefix( arg, "weapon" ) ) wear = ITEM_WIELD; if ( !str_prefix( arg2, "elf" ) || !str_prefix( arg2, "drow" ) || !str_prefix( arg2, "elder" ) || !str_prefix( arg2, "human" ) ) antirace = group2 + group3 + group4 + group5 + group6; if ( !str_prefix( arg2, "ogre" ) || !str_prefix( arg2, "demon" ) || !str_prefix( arg2, "troll" ) || !str_prefix( arg2, "minotaur" ) ) antirace = group1 + group3 + group4 + group5 + group6; if ( !str_prefix( arg2, "dwarf" ) || !str_prefix( arg2, "halfling" ) || !str_prefix( arg2, "shadow" ) ) antirace = group1 + group2 + group4 + group5 + group6; if ( !str_prefix( arg2, "illithid" ) || !str_prefix( arg2, "ghoul" ) ) antirace = group1 + group2 + group3 + group5 + group6; if ( !str_prefix( arg2, "pixie" ) ) antirace = group1 + group2 + group3 + group4 + group6; if ( !str_prefix( arg2, "lizardman" ) ) antirace = group1 + group2 + group3 + group4 + group5; if ( is_number( argument ) ) lvl = atoi( argument ); else lvl = 0; if ( wear && antirace && ( lvl < 30 || lvl > ch->level ) ) { sprintf( buf, "Illegal level. Valid levels are 30 to %d.\n\r", ch->level ); send_to_char( AT_GREY, buf, ch ); return; } if ( wear && antirace == 0 ) { send_to_char( AT_GREY, "Illegal race. Help RACE for valid race list.\n\r", ch ); return; } if ( wear ) { #ifdef NEW_MONEY if ( (ch->money.gold + (ch->money.silver/SILVER_PER_GOLD) + (ch->money.copper/COPPER_PER_GOLD) ) < (lvl * 100) ) { #else if ( ch->gold < lvl * 10000 ) { #endif send_to_char( AT_GREY, "You do not have enough money to create the base item of this level.\n\r", ch ); return; } else if ( wear == ITEM_WIELD ) obj = create_object( get_obj_index( OBJ_VNUM_TO_FORGE_W ), lvl ); else obj = create_object( get_obj_index( OBJ_VNUM_TO_FORGE_A ), lvl ); #ifdef NEW_MONEY obj->cost.silver = obj->cost.copper = 0; obj->cost.gold = lvl * 100; #else obj->cost = lvl * 10000; #endif obj->weight = lvl * 0.15; obj->level = lvl; obj->anti_race_flags = antirace; if ( obj->level >= 101 ) obj->extra_flags += ITEM_NO_DAMAGE; obj->wear_flags += wear; forge_obj( ch, obj ); } else do_forge( ch, "" ); return; } void do_spit( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; CHAR_DATA *victim; char arg[ MAX_INPUT_LENGTH ]; int dam; if ( ch->race != RACE_LIZARDMAN ) { send_to_char( AT_GREY, "Huh?\n\r", ch ); return; } if ( ch->race_wait > 0 ) return; if ( !ch->fighting ) { send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch ); return; } one_argument( argument, arg ); victim = ch->fighting; if ( arg[0] != '\0' ) if ( !( victim = get_char_room( ch, arg ) ) ) { send_to_char(C_DEFAULT, "They aren't here.\n\r", ch ); return; } dam = ch->level + number_range( ch->level, ch->level * 4 ); damage( ch, victim, dam, gsn_spit ); ch->race_wait = 36; if ( !victim || victim->position == POS_DEAD || !victim->in_room || victim->in_room != ch->in_room ) return; if ( number_percent( ) < 25 ) { int location = number_range( 0, 1 ); switch( location ) { case 0: if ( victim->race != RACE_ILLITHID ) { act( AT_DGREEN, "You spit right in $S eyes!", ch, NULL, victim, TO_CHAR ); act( AT_DGREEN, "$n spit into $N's eyes!", ch, NULL, victim, TO_NOTVICT ); act( AT_DGREEN, "$n spit into your eyes!", ch, NULL, victim, TO_VICT ); if ( !IS_AFFECTED( victim, AFF_BLIND ) ) { send_to_char( AT_WHITE, "You are blinded!", victim ); act( AT_WHITE, "$n is blinded!", victim, NULL, NULL, TO_ROOM ); af.type = gsn_spit; af.level = ch->level; af.duration = 0; af.location = APPLY_HITROLL; af.modifier = -10; af.bitvector = AFF_BLIND; affect_to_char( victim, &af ); af.location = APPLY_AC; af.modifier = 50; affect_to_char( victim, &af ); } } break; case 1: act( AT_DGREEN, "You spit right in $S mouth!", ch, NULL, victim, TO_CHAR ); act( AT_DGREEN, "$n spit into $N's mouth! Gross!", ch, NULL, victim, TO_NOTVICT ); act( AT_DGREEN, "$n spit into your mouth!", ch, NULL, victim, TO_VICT ); send_to_char( AT_WHITE, "The acidic spit burns your mouth and throat.\n\r", victim ); STUN_CHAR( victim, 2, STUN_MAGIC ); break; } } if ( !saves_spell( ch->level, victim ) && victim->race != RACE_GHOUL ) { af.type = gsn_poison; af.level = ch->level; af.duration = 2; af.location = APPLY_STR; af.modifier = -3; af.bitvector = 0; affect_join( victim, &af ); } return; }