/*************************************************************************** * 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. * * * * 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. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ /*************************************************************************** * ROT 1.4 is copyright 1996-1997 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file doc/rot.license * ***************************************************************************/ #if defined(macintosh) #include <types.h> #include <time.h> #else #include <sys/types.h> #include <sys/time.h> #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include "merc.h" #include "magic.h" /* command procedures needed */ DECLARE_DO_FUN(do_help ); DECLARE_DO_FUN(do_say ); DECLARE_DO_FUN(do_handle ); DECLARE_DO_FUN(do_side_kick ); DECLARE_DO_FUN(do_spin_kick ); DECLARE_DO_FUN(do_blindness_dust); DECLARE_DO_FUN(do_will_of_iron ); //DECLARE_DO_FUN(do_spinkick ); DECLARE_DO_FUN(do_purify_body ); DECLARE_DO_FUN(do_healing_trance ); DECLARE_DO_FUN(do_yell ); DECLARE_DO_FUN(do_rest ); DECLARE_DO_FUN(do_sleep ); int handling_improve args((CHAR_DATA *ch, sh_int sn)); void check_ground_stomp args((CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam)); void check_follow_through args((CHAR_DATA *ch, CHAR_DATA *victim, int dam)); bool check_dispel args(( int dis_level, CHAR_DATA *victim, int sn)); bool is_safe_quiet args ((CHAR_DATA * ch, CHAR_DATA * victim)); void improve_toughness args ((CHAR_DATA *ch)); /* used to get new skills */ void do_gain(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; CHAR_DATA *trainer; int sn = 0; if (IS_NPC(ch)) return; /* find a trainer */ for ( trainer = ch->in_room->people; trainer != NULL; trainer = trainer->next_in_room) if (IS_NPC(trainer) && IS_SET(trainer->act,ACT_GAIN)) break; if (trainer == NULL || !can_see(ch,trainer)) { send_to_char("You can't do that here.\n\r",ch); return; } strcpy(arg2,argument); argument = one_argument(argument,arg); strcpy(arg1,argument); if (arg[0] == '\0') { do_say(trainer,"{_Pardon me?{x"); return; } if (!str_prefix(arg,"list")) { int col; col = 0; sprintf(buf, "%-18s %-5s %-18s %-5s %-18s %-5s\n\r", "skill","cost","skill","cost","skill","cost"); send_to_char(buf,ch); for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL) break; if (!ch->pcdata->learned[sn] && skill_table[sn].skill_level[ch->class] <= LEVEL_HERO) { sprintf(buf,"{&%-18s {8%-5d{x ", skill_table[sn].name,skill_table[sn].rating[ch->class]); send_to_char(buf,ch); if (++col % 3 == 0) send_to_char("\n\r",ch); } } if (col % 3 != 0) send_to_char("\n\r",ch); return; } if (!str_prefix(arg,"convert")) { if (ch->practice < 6) { act("$N tells you 'You are not yet ready.{x'", ch,NULL,trainer,TO_CHAR); return; } if (!str_cmp(arg1,"all")) { act("$N converts all your practices to trains.",ch,NULL,trainer,TO_CHAR); while(ch->practice >= 6) { //Do it. All your practice are belong to train. ch->practice -= 6; ch->train += 1; } return; } else { act("$N helps you apply your practice to training", ch,NULL,trainer,TO_CHAR); ch->practice -= 6; ch->train +=1 ; return; } } if (!str_prefix(arg,"study")) { if (ch->train < 1) { act("$N tells you 'You are not yet ready.{x'", ch,NULL,trainer,TO_CHAR); return; } if (!str_cmp(arg1,"all")) { act("$N converts all your trains to practices.",ch,NULL,trainer,TO_CHAR); while(ch->train > 0) { //Do it. All your trains are belong to practice. ch->practice += 6; ch->train -= 1; } return; } else { act("$N helps you apply your training to practice", ch,NULL,trainer,TO_CHAR); ch->train -= 1; ch->practice += 6; return; } } if (!str_prefix(arg,"points")) { if (ch->train < 2) { act("$N tells you '{_You are not yet ready.{x'", ch,NULL,trainer,TO_CHAR); return; } if (ch->pcdata->points <= 40) { act("$N tells you '{_There would be no point in that.{x'", ch,NULL,trainer,TO_CHAR); return; } act("$N trains you, and you feel more at ease with your skills.", ch,NULL,trainer,TO_CHAR); ch->train -= 2; ch->pcdata->points -= 1; ch->exp = (long)exp_per_level(ch,ch->pcdata->points) * ch->level; return; } /* else add a group/skill */ sn = skill_lookup(arg2); if (sn == skill_lookup("conceal")) { send_to_char("You cannot gain that.\n\r",ch); return; } if (sn > -1) { if (ch->pcdata->learned[sn]) { act("$N tells you '{_You already know that skill!{x'", ch,NULL,trainer,TO_CHAR); return; } if (skill_table[sn].skill_level[ch->class] > LEVEL_HERO) { act("$N tells you '{_That skill is beyond your powers.{x'", ch,NULL,trainer,TO_CHAR); return; } if (ch->train < skill_table[sn].rating[ch->class]) { act("$N tells you '{_You are not yet ready for that skill.{x'", ch,NULL,trainer,TO_CHAR); return; } /* add the skill */ ch->pcdata->learned[sn] = 1; ch->pcdata->learnlvl[sn] = skill_table[sn].skill_level[ch->class]; act("$N trains you in the art of $t", ch,skill_table[sn].name,trainer,TO_CHAR); ch->train -= skill_table[sn].rating[ch->class]; return; } act("$N tells you '{_I do not understand...{x'",ch,NULL,trainer,TO_CHAR); } /* RT spells and skills show the players spells (or skills) */ void do_garrote( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance; one_argument( argument, arg ); if ( (chance = get_skill(ch,gsn_garrote)) == 0 || (!IS_NPC(ch) && ch->level < skill_table[gsn_garrote].skill_level[ch->class])) { send_to_char("Garrote? What's that?{x\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Garrote whom?\n\r",ch); return; } if (ch->fighting != NULL) { send_to_char("{hYou're facing the wrong end.{x\n\r",ch); return; } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if ( victim == ch ) { send_to_char( "How can you sneak up on yourself?\n\r", ch ); return; } if ( is_safe( ch, victim ) ) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch,victim->fighting) && !IS_SET(victim->in_room->room_flags, ROOM_ARENA)) { send_to_char("Kill stealing is not permitted.\n\r",ch); return; } if ( victim->hit < victim->max_hit / 4) { act( "$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR ); return; } if ( ( ch->fighting == NULL ) && ( !IS_NPC( ch ) ) && ( !IS_NPC( victim ) ) ) { ch->attacker = TRUE; victim->attacker = FALSE; } /* dexterity */ chance += get_curr_stat(ch,STAT_DEX); chance -= get_curr_stat(victim,STAT_DEX)/2; /* speed */ if (IS_SET(ch->off_flags,OFF_FAST) || IS_AFFECTED(ch,AFF_HASTE)) chance += 25; if (IS_SET(victim->off_flags,OFF_FAST) || IS_AFFECTED(victim,AFF_HASTE)) chance -= 10; /* level */ chance += (ch->level - victim->level) * 4; /* sloppy hack to prevent false zeroes */ if (chance % 5 == 0) chance += 1; /* now the attack */ if (number_percent() * 2 < chance) { AFFECT_DATA af; act("{k$n is choked by a wire around the neck!{x",victim,NULL,NULL,TO_ROOM); act("{i$n slips a wire around your neck!{x",ch,NULL,victim,TO_VICT); multi_hit (ch, victim, gsn_garrote); send_to_char("{7You choke and gag!{x\n\r",victim); check_improve(ch,gsn_garrote,TRUE,2); WAIT_STATE(ch,skill_table[gsn_garrote].beats); /* Leave the garrote on the choke the shit out of em */ af.where = TO_AFFECTS2; af.type = gsn_garrote; af.level = ch->level; af.duration = 3; af.location = APPLY_HITROLL; af.modifier = -150; af.bitvector = AFF2_GARROTE; affect_to_char(victim,&af); } else { damage(ch,victim,0,gsn_garrote,DAM_NONE,TRUE, 0); check_improve(ch,gsn_garrote,FALSE,2); WAIT_STATE(ch,skill_table[gsn_garrote].beats); } } void do_spells(CHAR_DATA *ch, char *argument) { char spell_list[LEVEL_HERO][MAX_STRING_LENGTH]; char spell_columns[LEVEL_HERO]; int sn,lev,mana; bool found = FALSE; char buf[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; bool ShowColors = TRUE; bool fWhite = FALSE; bool fRed = FALSE; bool fBlue = FALSE; bool fGreen = FALSE; bool fOrange = FALSE; bool fBlack = FALSE; if (IS_NPC(ch)) return; argument = one_argument(argument,arg); if(arg[0] != '\0') { if(!str_cmp(arg,"white")) { fWhite = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {7White{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_WHITE]); } if(!str_cmp(arg,"red")) { fRed = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {!Red{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_RED]); } if(!str_cmp(arg,"blue")) { fBlue = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {$Blue{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_BLUE]); } if(!str_cmp(arg,"green")) { fGreen = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {@Green{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_GREEN]); } if(!str_cmp(arg,"black")) { fBlack = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {8Black{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_BLACK]); } if(!str_cmp(arg,"orange")) { fOrange = TRUE; ShowColors = FALSE; printf_to_char(ch,"Proficiecy in {3Orange{x Magic: {&%d{x.\n\r",ch->magic[MAGIC_ORANGE]); } } /* initilize data */ for (lev = 0; lev < LEVEL_HERO; lev++) { spell_columns[lev] = 0; spell_list[lev][0] = '\0'; } for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL) break; /* if (skill_table[sn].skill_level[ch->class] < LEVEL_HERO && skill_table[sn].spell_fun != spell_null && ch->pcdata->learned[sn] > 0) { found = TRUE; lev = skill_table[sn].skill_level[ch->class]; */ lev = ch->pcdata->learnlvl[sn]; if (lev < LEVEL_HERO && skill_table[sn].spell_fun != spell_null && ch->pcdata->learned[sn] > 0) { found = TRUE; if (ch->level < lev) { if(!ShowColors) { if(fWhite && !IS_SPELL_WHITE(sn)) continue; else if(fRed && !IS_SPELL_RED(sn)) continue; else if(fBlue && !IS_SPELL_BLUE(sn)) continue; else if(fGreen && !IS_SPELL_GREEN(sn)) continue; else if(fOrange && !IS_SPELL_ORANGE(sn)) continue; else if(fBlack && !IS_SPELL_BLACK(sn)) continue; } if(IS_SPELL_WHITE(sn)) sprintf(buf,"{&%-18s{x {#n/a{x ", skill_table[sn].name); else if(IS_SPELL_RED(sn)) sprintf(buf,"{!%-18s{x {#n/a{x ", skill_table[sn].name); else if(IS_SPELL_BLUE(sn)) sprintf(buf,"{$%-18s{x {#n/a{x ", skill_table[sn].name); else if(IS_SPELL_GREEN(sn)) sprintf(buf,"{@%-18s{x {#n/a{x ", skill_table[sn].name); else if(IS_SPELL_ORANGE(sn)) sprintf(buf,"{3%-18s{x {#n/a{x ", skill_table[sn].name); else if(IS_SPELL_BLACK(sn)) sprintf(buf,"{8%-18s{x {#n/a{x ", skill_table[sn].name); else sprintf(buf,"{C%-18s{x {#n/a{x ", skill_table[sn].name); } else { if(!ShowColors) { if(fWhite && !IS_SPELL_WHITE(sn)) continue; else if(fRed && !IS_SPELL_RED(sn)) continue; else if(fBlue && !IS_SPELL_BLUE(sn)) continue; else if(fGreen && !IS_SPELL_GREEN(sn)) continue; else if(fOrange && !IS_SPELL_ORANGE(sn)) continue; else if(fBlack && !IS_SPELL_BLACK(sn)) continue; } mana = UMAX(skill_table[sn].min_mana, 100/(2 + ch->level - lev)); if(IS_SPELL_WHITE(sn))//maybe put * 3 or 2 after [sn] --bree learned sprintf(buf,"{&%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else if(IS_SPELL_BLUE(sn)) sprintf(buf,"{$%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else if(IS_SPELL_RED(sn)) sprintf(buf,"{!%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else if(IS_SPELL_GREEN(sn)) sprintf(buf,"{@%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else if(IS_SPELL_ORANGE(sn)) sprintf(buf,"{3%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else if(IS_SPELL_BLACK(sn)) sprintf(buf,"{8%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); else sprintf(buf,"{C%-18s {#%3d{x mana {@({&%d{@){x ",skill_table[sn].name,mana,ch->pcdata->learned[sn]); } if (spell_list[lev][0] == '\0') sprintf(spell_list[lev],"\n\r{BLevel{x {&%2d{x: %s",lev,buf); else /* append */ { if ( ++spell_columns[lev] % 2 == 0) strcat(spell_list[lev],"\n\r "); strcat(spell_list[lev],buf); } } } /* return results */ if (!found) { send_to_char("You know no spells.\n\r",ch); return; } for (lev = 0; lev < LEVEL_HERO; lev++) if (spell_list[lev][0] != '\0') send_to_char(spell_list[lev],ch); send_to_char("\n\r",ch); } void do_skills(CHAR_DATA *ch, char *argument) { char skill_list[LEVEL_HERO][MAX_STRING_LENGTH]; char skill_columns[LEVEL_HERO]; int sn,lev; bool found = FALSE; char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch)) return; /* initilize data */ for (lev = 0; lev < LEVEL_HERO; lev++) { skill_columns[lev] = 0; skill_list[lev][0] = '\0'; } for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL ) break; lev = ch->pcdata->learnlvl[sn]; /* if (skill_table[sn].skill_level[ch->class] < LEVEL_HERO && */ if (lev < LEVEL_HERO && skill_table[sn].spell_fun == spell_null && ch->pcdata->learned[sn] > 0) { found = TRUE; // lev = skill_table[sn].skill_level[ch->class]; if (ch->level < lev) sprintf(buf,"{R%-18s{x {@n/a{x ", skill_table[sn].name); else sprintf(buf,"{R%-18s{x {@%3d%%{x ",skill_table[sn].name, ch->pcdata->learned[sn]); if (skill_list[lev][0] == '\0') sprintf(skill_list[lev],"\n\r{yLevel {&%2d{x: %s",lev,buf); else /* append */ { if ( ++skill_columns[lev] % 2 == 0) strcat(skill_list[lev],"\n\r "); strcat(skill_list[lev],buf); } } } /* return results */ if (!found) { send_to_char("You know no skills.\n\r",ch); return; } for (lev = 0; lev < LEVEL_HERO; lev++) if (skill_list[lev][0] != '\0') send_to_char(skill_list[lev],ch); send_to_char("\n\r",ch); } /* shows skills, groups and costs (only if not bought) */ void list_group_costs(CHAR_DATA *ch) { char buf[100]; int sn,col; if (IS_NPC(ch)) return; col = 0; sprintf(buf,"%-18s %-5s %-18s %-5s %-18s %-5s\n\r","skill","cp","skill","cp","skill","cp"); send_to_char(buf,ch); for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL) break; if (!ch->gen_data->skill_chosen[sn] && ch->pcdata->learned[sn] < 1 && skill_table[sn].skill_level[ch->class] < LEVEL_HERO ) { sprintf(buf,"%-18s %-5d ",skill_table[sn].name, skill_table[sn].rating[ch->class]); send_to_char(buf,ch); if (++col % 3 == 0) send_to_char("\n\r",ch); /* Bad Hack but should work * Sets class gainable skills to 0 * leaves ungainables at -1 */ ch->pcdata->learned[sn] = 0; } } if ( col % 3 != 0 ) send_to_char( "\n\r", ch ); send_to_char("\n\r",ch); sprintf(buf,"Creation points: %d\n\r",ch->pcdata->points); send_to_char(buf,ch); sprintf(buf,"Experience per level: %ld\n\r", exp_per_level(ch,ch->gen_data->points_chosen)); send_to_char(buf,ch); return; } void list_group_chosen(CHAR_DATA *ch) { char buf[100]; int sn,col; if (IS_NPC(ch)) return; col = 0; sprintf(buf,"%-18s %-5s %-18s %-5s %-18s %-5s","skill","cp","skill","cp","skill","cp\n\r"); send_to_char(buf,ch); for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL) break; if (ch->gen_data->skill_chosen[sn] && skill_table[sn].skill_level[ch->class] <= LEVEL_HERO) { sprintf(buf,"%-18s %-5d ",skill_table[sn].name, skill_table[sn].rating[ch->class]); send_to_char(buf,ch); if (++col % 3 == 0) send_to_char("\n\r",ch); } } if ( col % 3 != 0 ) send_to_char( "\n\r", ch ); send_to_char("\n\r",ch); sprintf(buf,"Creation points: %d\n\r",ch->gen_data->points_chosen); send_to_char(buf,ch); sprintf(buf,"Experience per level: %ld\n\r", exp_per_level(ch,ch->gen_data->points_chosen)); send_to_char(buf,ch); return; } long exp_per_level(CHAR_DATA *ch, int points) { long expl,inc,epl; if (IS_NPC(ch)) return 1000; expl = 1000; inc = 500; if (points < 40) return 1000 * pc_race_table[ch->race].class_mult[ch->class]/100; /* processing */ points -= 40; while (points > 9) { expl += (long)inc; points -= 10; if (points > 9) { expl += (long)inc; inc *= 2; points -= 10; } } expl += (long)points * (long)inc / 10; epl = (long)expl * (long)pc_race_table[ch->race].class_mult[ch->class]/100; if(ch->pcdata->tier > 2) { /* Temporary check */ if(epl < 3000) epl += (long)(epl * 8 / 100); else if(epl < 6000) epl += (long)(epl * 4 / 100); else epl += (long)(epl * 2 / 200); } else if(ch->pcdata->tier > 1) { epl += (long)(epl * 4 / 100); } return epl; } /* this procedure handles the input parsing for the skill generator */ bool parse_gen_groups(CHAR_DATA *ch,char *argument) { char arg[MAX_INPUT_LENGTH]; char buf[100]; int sn; if (argument[0] == '\0') return FALSE; argument = one_argument(argument,arg); if (!str_prefix(arg,"help")) { if (argument[0] == '\0') { do_help(ch,"group help"); return TRUE; } do_help(ch,argument); return TRUE; } if (!str_prefix(arg,"add")) { if (argument[0] == '\0') { send_to_char("You must provide a skill name.\n\r",ch); return TRUE; } sn = skill_lookup(argument); if (sn != -1) { if (ch->gen_data->skill_chosen[sn] || ch->pcdata->learned[sn] > 0) { send_to_char("You already know that skill!\n\r",ch); return TRUE; } if (skill_table[sn].skill_level[ch->class] > LEVEL_HERO) { send_to_char("That skill is not available.\n\r",ch); return TRUE; } sprintf(buf, "%s skill added\n\r",skill_table[sn].name); send_to_char(buf,ch); ch->gen_data->skill_chosen[sn] = TRUE; ch->gen_data->points_chosen += skill_table[sn].rating[ch->class]; ch->pcdata->learned[sn] = 1; ch->pcdata->points += skill_table[sn].rating[ch->class]; return TRUE; } send_to_char("No skills or groups by that name...\n\r",ch); return TRUE; } if (!strcmp(arg,"drop")) { if (argument[0] == '\0') { send_to_char("You must provide a skill to drop.\n\r",ch); return TRUE; } sn = skill_lookup(argument); if (sn != -1 && ch->gen_data->skill_chosen[sn]) { send_to_char("Skill dropped.\n\r",ch); ch->gen_data->skill_chosen[sn] = FALSE; ch->gen_data->points_chosen -= skill_table[sn].rating[ch->class]; ch->pcdata->learned[sn] = 0; ch->pcdata->points -= skill_table[sn].rating[ch->class]; return TRUE; } send_to_char("You haven't bought any such skill or group.\n\r",ch); return TRUE; } if (!str_prefix(arg,"premise")) { do_help(ch,"premise"); return TRUE; } if (!str_prefix(arg,"list")) { list_group_costs(ch); return TRUE; } if (!str_prefix(arg,"learned")) { list_group_chosen(ch); return TRUE; } return FALSE; } int spell_avail( CHAR_DATA *ch, const char *name ) { /* checks to see if a spell is available to a class */ int sn, found = -1; if (IS_NPC(ch)) return skill_lookup(name); for ( sn = 0; sn < MAX_SKILL; sn++ ) { if (skill_table[sn].name == NULL) break; if (LOWER(name[0]) == LOWER(skill_table[sn].name[0]) && !str_prefix(name,skill_table[sn].name)) { if (skill_table[sn].skill_level[ch->class] <= LEVEL_HERO) return sn; } } return found; } /* checks for skill improvement */ void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier ) { int chance; char buf[100]; if (IS_NPC(ch)) return; sn = handling_improve(ch,sn); if (ch->level < skill_table[sn].skill_level[ch->class] || skill_table[sn].skill_level[ch->class] > LEVEL_HERO || ch->pcdata->learned[sn] == 0 || ch->pcdata->learned[sn] == 100) return; /* skill is not known */ /* check to see if the character has a chance to learn */ chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn; chance /= ( multiplier * skill_table[sn].rating[ch->class] * 4)+1; chance += ch->level; if (number_range(1,1000) > chance) return; /* now that the character has a CHANCE to learn, see if they really have */ if (success) { chance = URANGE(5,100 - ch->pcdata->learned[sn], 95); if (number_percent() < chance) { ch->pcdata->learned[sn]++; sprintf(buf,"{GYou have become better at {R%s{G! ({R%d{G%%){x\n\r", skill_table[sn].name, ch->pcdata->learned[sn]); send_to_char(buf,ch); gain_exp(ch,2 * skill_table[sn].rating[ch->class]); } } else { chance = URANGE(5,ch->pcdata->learned[sn]/2,30); if (number_percent() < chance) { ch->pcdata->learned[sn] += number_range(1,3); ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100); sprintf(buf, "{GYou learn from your mistakes, and your {R%s {Gskill improves. ({R%d{G%%){x\n\r", skill_table[sn].name, ch->pcdata->learned[sn]); send_to_char(buf,ch); gain_exp(ch,2 * skill_table[sn].rating[ch->class]); } } } /* use for processing a skill or group for addition */ void group_add( CHAR_DATA *ch, const char *name, bool deduct) { int sn; if (IS_NPC(ch)) /* NPCs do not have skills */ return; sn = skill_lookup(name); if (sn != -1) { if (ch->pcdata->learned[sn] == 0) /* i.e. not known */ { ch->pcdata->learned[sn] = 1; if (deduct) ch->pcdata->points += skill_table[sn].rating[ch->class]; } return; } } /* used for processing a skill or group for deletion -- no points back! */ void group_remove(CHAR_DATA *ch, const char *name) { int sn; sn = skill_lookup(name); if (sn != -1) { ch->pcdata->learned[sn] = 0; return; } } void do_showclass(CHAR_DATA *ch, char* argument) { char buf[100]; int sn,col,class; if (IS_NPC(ch)) return; if ( (class = class_lookup(argument)) == -1) { send_to_char("That's not a valid class",ch); return; } col = 0; sprintf(buf,"%-18s %-5s %-18s %-5s %-18s %-5s\n\r","skill","cp","skill","cp","skill","cp"); send_to_char(buf,ch); for (sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].name == NULL) break; if ( skill_table[sn].skill_level[class] < LEVEL_HERO ) { sprintf(buf,"%-18s %-2d(%-3d) ",skill_table[sn].name, skill_table[sn].rating[class],skill_table[sn].skill_level[class]); send_to_char(buf,ch); if (++col % 3 == 0) send_to_char("\n\r",ch); } } if ( col % 3 != 0 ) send_to_char( "\n\r", ch ); send_to_char("\n\r", ch ); return; } void do_showskill(CHAR_DATA *ch, char* argument) { int class; int skill; char buf[MAX_STRING_LENGTH]; skill = skill_lookup(argument); if ( skill == -1 ) { send_to_char("That's not a skill or spell.\n\r",ch); return; } sprintf(buf,"The following classes get '%s':\n\r",argument); for ( class = 0; class < MAX_CLASS; class++ ) { if(skill_table[skill].skill_level[class] < LEVEL_HERO) { if ( class > 0 ) strcat( buf, " " ); strcat( buf, class_table[class].name ); } } strcat( buf, ".\n\r" ); send_to_char(buf,ch); return; } /* Monk Stuff -- Skyntil */ void do_open_palming(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_palm)) == 0 || ch->pcdata->learned[gsn_palm] < 1) { send_to_char("You don't have the ability to use open palm striking martial arts.\n\r",ch); return; } if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM)) return; if (is_affected(ch,gsn_palm)) { send_to_char("Your palms are already tense.\n\r",ch); return; } if (get_eq_char(ch,WEAR_WIELD) != NULL || get_eq_char(ch,WEAR_SECONDARY) != NULL) { send_to_char("You can't start using open palm striking while using weapons.\n\r",ch); return; } if (number_percent() >= chance) { send_to_char("Your try to tense the nerves in your hands, but fail.\n\r",ch); check_improve(ch,gsn_palm,FALSE,2); return; } act("$n goes into a trance and $s hands become deadly weapons.",ch,0,0,TO_ROOM); send_to_char("You feel your mind relax as the nerves in your hands tense.\n\r",ch); af.where = TO_AFFECTS; af.type = gsn_palm; af.location = 0; af.modifier = 0; af.duration = (ch->level/4); af.level = ch->level; af.bitvector = 0; affect_to_char(ch,&af); check_improve(ch,gsn_palm,TRUE,2); WAIT_STATE(ch,6); return; } void do_martial_arts(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_martial_arts)) == 0 || ch->pcdata->learned[gsn_martial_arts] < 1 ) { send_to_char("You don't know any martial arts.\n\r",ch); return; } if (ch->class == CLASS_MONK) { if (is_affected(ch,gsn_martial_arts)) { if (ch->fighting == NULL) { send_to_char("You stop focusing on the art of combat and find inner peace.\n\r",ch); affect_strip(ch,gsn_martial_arts); WAIT_STATE(ch,18); return; } else { send_to_char("You are too busy fighting to do that!\n\r",ch); return; } } } else if (is_affected(ch,gsn_martial_arts)) { send_to_char("You are already focused on combat.\n\r",ch); return; } if ((get_eq_char(ch,WEAR_WIELD) != NULL || get_eq_char(ch,WEAR_SECONDARY) != NULL) && ch->class == CLASS_MONK) { send_to_char("You cannot practice this skill using weapons.\n\r",ch); return; } if (number_percent() >= chance) { send_to_char("You build up intense focus but lose concentration.\n\r",ch); check_improve(ch,gsn_martial_arts,FALSE,2); return; } act("$n's face clouds with a look of deadly concentration.",ch,0,0,TO_ROOM); send_to_char("You feel your body's focus increase toward mastery.\n\r",ch); af.where = TO_AFFECTS; af.type = gsn_martial_arts; af.location = 0; af.modifier = 0; if (ch->class == CLASS_MONK) { af.duration = -1; } else { af.duration = ch->level/5; } af.level = ch->level; af.bitvector = 0; affect_to_char(ch,&af); WAIT_STATE(ch,6); return; } void lose_skill(CHAR_DATA *ch, int skill) { int gain = 0; /* Gain from losing */ int prac_gain = 0; char log_name[MSL]; char log_buf[100]; // If your class loses a skill if(!IS_IMMORTAL(ch) && !class_has_skill(ch->class, skill)) { gain = skill_table[skill].rating[ch->class]; if(ch->pcdata->learned[skill] >= 75) prac_gain = 3; else if(ch->pcdata->learned[skill] >= 50) prac_gain = 2; else if(ch->pcdata->learned[skill] >= 25) prac_gain = 1; else prac_gain = 0; ch->train += gain; ch->practice += prac_gain; printf_to_char(ch,"You lose the %s skill and gain %d trains.\n\r", skill_table[skill].name,gain); ch->pcdata->learned[skill] = -1; ch->pcdata->learnlvl[skill] = 102; sprintf(log_name,"%s",ch->name); sprintf(log_buf," has lost the %s skill.", skill_table[skill].name); strcat(log_name, log_buf); log_string(log_name); } return; } void gain_skill(CHAR_DATA *ch, int skill) { // You figure it out if(class_has_skill(ch->class, skill) && ch->pcdata->learned[skill] < 1) { if(ch->level > skill_table[skill].skill_level[ch->class]) { ch->pcdata->learned[skill] = 75; ch->pcdata->learnlvl[skill] = skill_table[skill].skill_level[ch->class]; } else { ch->pcdata->learned[skill] = 1; ch->pcdata->learnlvl[skill] = skill_table[skill].skill_level[ch->class]; } printf_to_char(ch,"You gain the %s skill at %d percent.\n\r", skill_table[skill].name,ch->pcdata->learned[skill]); } return; } /* Gain a skill into the gain list */ void gain_skill_gain(CHAR_DATA *ch, int skill) { char log_name[MSL]; char log_buf[100]; if(class_has_skill(ch->class, skill) && ch->pcdata->learned[skill] < 0) { ch->pcdata->learned[skill] = 0; printf_to_char(ch,"You are now able to gain the %s skill.\n\r", skill_table[skill].name); sprintf(log_name,"%s",ch->name); sprintf(log_buf," can now gain the %s skill.", skill_table[skill].name); strcat(log_name, log_buf); log_string(log_name); } return; } bool has_skill(CHAR_DATA *ch,int skill) { return IS_NPC(ch) ? TRUE : (ch->level >= ch->pcdata->learnlvl[skill]); } bool class_has_skill(int class, int skill) { return (skill_table[skill].skill_level[class] < 102); } bool has_learned_skill(CHAR_DATA *ch,int skill) { return IS_NPC(ch) ? TRUE : (ch->pcdata->learned[skill] > 0); } bool has_gain(CHAR_DATA *ch,int skill) { if(ch->pcdata->learned[skill] == 0) return TRUE; else return FALSE; } int handling_improve(CHAR_DATA *ch, sh_int sn) { sh_int wsn = -1; if(ch->pcdata->learned[sn] < 100) return sn; if(sn == gsn_sword) wsn = gsn_sword2; else if(sn == gsn_axe) wsn = gsn_axe2; else if(sn == gsn_hand_to_hand) wsn = gsn_hand2; else if(sn == gsn_dagger) wsn = gsn_dagger2; else if(sn == gsn_polearm) wsn = gsn_polearm2; else if(sn == gsn_whip) wsn = gsn_whip2; else if(sn == gsn_spear) wsn = gsn_spear2; else if(sn == gsn_mace) wsn = gsn_mace2; else if(sn == gsn_flail) wsn = gsn_flail2; else if(sn == gsn_dual_wield) wsn = gsn_dual_wield2; if(wsn == -1) return sn; return wsn; } void do_handle(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *trainer; sh_int sn,wsn = -1; if (IS_NPC(ch)) return; /* find a trainer */ for ( trainer = ch->in_room->people; trainer != NULL; trainer = trainer->next_in_room) if (IS_NPC(trainer) && (IS_SET(trainer->act,ACT_GAIN) || IS_SET(trainer->act,ACT_TRAIN)) ) break; if (trainer == NULL || !can_see(ch,trainer)) { send_to_char("You can't do that here.\n\r",ch); return; } one_argument(argument,arg); if (arg[0] == '\0') { do_say(trainer,"What do you wish to learn?"); do_say(trainer,"I can teach you how to handle your weapon better perhaps?"); return; } if(str_cmp(arg,"sword") && str_cmp(arg,"dagger") && str_cmp(arg,"polearm") && str_cmp(arg,"spear") && str_cmp(arg,"flail") && str_cmp(arg,"mace") && str_cmp(arg,"whip") && str_cmp(arg,"axe") && str_cmp(arg,"dual wield") ) { do_say(trainer,"Pardon me?"); return; } sn = skill_lookup(arg); if (ch->pcdata->learned[sn] < 100 && sn != gsn_dual_wield) { act("$N tells you 'You are not yet ready to learn with that weapon.'",ch,NULL,trainer,TO_CHAR); return; } else if(ch->pcdata->learned[sn] < 100 && sn == gsn_dual_wield) { act("$N tells you 'You are not yet ready to learn dual weapon mastery.'",ch,NULL,trainer,TO_CHAR); return; } if(sn == gsn_sword) wsn = gsn_sword2; else if(sn == gsn_axe) wsn = gsn_axe2; else if(sn == gsn_dagger) wsn = gsn_dagger2; else if(sn == gsn_polearm) wsn = gsn_polearm2; else if(sn == gsn_whip) wsn = gsn_whip2; else if(sn == gsn_spear) wsn = gsn_spear2; else if(sn == gsn_mace) wsn = gsn_mace2; else if(sn == gsn_flail) wsn = gsn_flail2; else if(sn == gsn_dual_wield) wsn = gsn_dual_wield2; if(wsn == -1) return; if(wsn == gsn_dual_wield2) { ch->pcdata->learned[wsn] = 1; ch->pcdata->learnlvl[wsn] = skill_table[wsn].skill_level[ch->class]; act("$N teaches how to better handle your weapon!",ch,NULL,trainer,TO_CHAR); return; } if(ch->class == CLASS_ASSASSIN && !IS_IMMORTAL(ch) && wsn == gsn_dagger2) { ch->pcdata->learned[wsn] = 1; act("$N teaches how to better handle your weapon!",ch,NULL,trainer,TO_CHAR); return; } if(ch->class != CLASS_CRUSADER && !IS_IMMORTAL(ch)) { do_say(trainer,"You cannot learn to better handle that weapon."); return; } ch->pcdata->learned[wsn] = 1; act("$N teaches how to better handle your weapon!",ch,NULL,trainer,TO_CHAR); /*if(ch->level == LEVEL_HERO) ch->practice += 2;*/ return; } // New Stuff 01/2005 -- Skyn. // Ground Stomp void check_ground_stomp(CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam) { if (chance < 10) return; if (dam == 0) return; chance = get_skill(ch,gsn_ground_stomp); chance /= 2; chance -= number_range(5,15); chance = URANGE(5,chance,50); if (!has_skill(ch,gsn_ground_stomp)) return; if (number_percent() > chance) { check_improve(ch,gsn_ground_stomp,FALSE,3); return; } act("You land your foot hard on $N's body.",ch,0,victim,TO_CHAR); act("$n stomps $N's body with brutal force.",ch,0,victim,TO_NOTVICT); act("$n lands his foot hard against your body.",ch,0,victim,TO_VICT); check_improve(ch,gsn_ground_stomp,TRUE,2); dam = dam * 4; dam = dam / 5; if(number_percent() < 10) { act("You hit $N critically!",ch,0,victim,TO_CHAR); dam *= 3/2; } damage(ch,victim,dam,gsn_ground_stomp,DAM_BASH,TRUE, 0); return; } // Side Kick void do_side_kick( CHAR_DATA *ch, char *argument ) { int dam; CHAR_DATA *victim; if(IS_NPC(ch)) return; if ( !IS_NPC(ch) && !has_skill(ch,gsn_sidekick)) { send_to_char("Huh?\n\r", ch ); return; } if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if( ch->stunned ) { send_to_char("You're still a bit woozy.\n\r",ch); return; } if ( get_skill(ch,gsn_sidekick) > number_percent()) { dam = number_range (1, ch->level); dam += number_range(0,(ch->level)/3); dam += number_range(0,(ch->level)/3); dam += number_range(0,(ch->level)/3); dam += number_range(0,(ch->level)/4); dam += number_range(0,(ch->level)/4); dam += number_range(0,(ch->level)/4); dam += number_range(0,(ch->level)/4); dam += number_range(ch->level/3,ch->level/2); act("You kick $N brutally in the side!",ch,0,victim,TO_CHAR); act("$n kicks you brutally in the side!",ch,0,victim,TO_VICT); if(has_skill(ch,gsn_vital_hit)) { if( (get_skill(ch,gsn_vital_hit) / 12) > number_percent( )) { check_improve(ch,gsn_vital_hit,TRUE, 3); dam = (dam * 8) / 5; } } damage(ch,victim,dam, gsn_sidekick,DAM_BASH,TRUE, 0); check_improve(ch,gsn_sidekick,TRUE,1); check_follow_through(ch,victim,dam); } else { damage( ch, victim, 0, gsn_sidekick,DAM_BASH,TRUE, 0); check_improve(ch,gsn_sidekick,FALSE,1); } WAIT_STATE( ch, skill_table[gsn_sidekick].beats ); return; } // Spin Kick void do_spin_kick( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; int dam; int skill; if (((get_skill(ch,gsn_spin_kick)) <= 0) || !has_skill(ch,gsn_spin_kick)) { send_to_char( "Huh?\n\r", ch ); return; } if (!is_affected(ch,gsn_martial_arts)) { send_to_char("You must be focused on the martial arts to use this skill.\n\r",ch); return; } if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if( ch->stunned ) { send_to_char("You're still a bit woozy.\n\r",ch); return; } if (number_percent() > get_skill(ch,gsn_spin_kick)) { send_to_char("You slip and fail your kick.\n\r",ch); check_improve(ch,gsn_spin_kick, FALSE,1); WAIT_STATE(ch, skill_table[gsn_spin_kick].beats); return; } act("You deftly spin around and kick $N in the chest!",ch,NULL,victim,TO_CHAR); act("$n spins around and kicks you in the chest!",ch,NULL,victim,TO_VICT); act("$n spins around deftly and kicks $N hard!",ch,NULL,victim,TO_NOTVICT); skill = get_skill(ch,gsn_spin_kick); if(ch->level <= 80) dam = ch->level * 2 + (number_range(0, skill)) * 3 / 2; else if(ch->level <= 90) dam = ch->level * 3 + (number_range((skill/3), skill)) * 3 / 2; else if(ch->level <= 100) dam = ch->level * 3 + (number_range((skill/2), skill)) * 9 / 5; else dam = ch->level * 3 + (number_range((skill*3/4), skill)) * 9 / 4; dam += -2*(dex_app[get_curr_stat(ch,STAT_DEX)].defensive); if (number_percent() < get_skill(ch,gsn_spin_kick) / 8) { act("Your kick knocks $N's breath away!",ch,NULL,victim,TO_CHAR); act("$n's kick knocks your breath away!",ch,NULL,victim,TO_VICT); act("$n's kick sends $N sprawling!",ch,NULL,victim,TO_NOTVICT); WAIT_STATE(victim,2*PULSE_VIOLENCE); } if(has_skill(ch,gsn_vital_hit)) { if( (get_skill(ch,gsn_vital_hit) / 12) > number_percent( )) { check_improve(ch,gsn_vital_hit,TRUE, 3); dam = (dam * 8) / 5; } } WAIT_STATE(ch, skill_table[gsn_spin_kick].beats); damage(ch,victim,dam, gsn_spin_kick,DAM_SLASH,TRUE, 0); check_improve(ch,gsn_spin_kick, TRUE,1); check_follow_through(ch,victim,dam); return; } // Follow through void check_follow_through(CHAR_DATA *ch, CHAR_DATA *victim, int dam) { int chance; OBJ_DATA *wield; wield = get_eq_char(ch,WEAR_WIELD); chance = get_skill(ch,gsn_follow_through); if (wield != NULL && IS_WEAPON_STAT(wield,WEAPON_TWO_HANDS)) { chance=chance*(get_curr_stat(ch,STAT_DEX)/12); } chance=chance/2; chance -= number_range(0,7); if (!has_skill(ch,gsn_follow_through)) return; if (number_percent() < chance) { if (ch->class == CLASS_HIGHLANDER) { if (wield != NULL && IS_WEAPON_STAT(wield,WEAPON_TWO_HANDS)) { act("The momentum of $n's weapon brings them around for another attack!",ch,0,0,TO_ROOM); act("The momentum of your swing brings your two-handed weapon around for another attack!",ch,0,0,TO_CHAR); dam = dam * 7/4; damage(ch, victim, dam, gsn_follow_through, DAM_SLASH, TRUE, 0); check_improve(ch,gsn_follow_through,TRUE,2); } else { act("The momentum of $n's weapon brings them around for another attack!",ch,0,0,TO_ROOM); act("The momentum of your swing brings your weapon around for another attack!",ch,0,0,TO_CHAR); dam = dam * 2/3; damage(ch, victim, dam, gsn_follow_through, DAM_SLASH, TRUE, 0); check_improve(ch,gsn_follow_through,TRUE,2); } } else if (is_affected(ch,gsn_martial_arts)) { act("$n's leg sweeps around and strikes with a follow through!",ch,0,0,TO_ROOM); act("Your leg sweeps around to land a follow through kick!",ch,0,0,TO_CHAR); dam = dam * 4; dam = dam / 5; damage(ch, victim, dam, gsn_follow_through, DAM_BASH, TRUE, 0); check_improve(ch,gsn_follow_through,TRUE,2); } } else check_improve(ch,gsn_follow_through,FALSE,3); return; } // Blindness dust void do_blindness_dust(CHAR_DATA *ch,char *argument) { CHAR_DATA *vch; CHAR_DATA *vch_next; AFFECT_DATA af; int chance; bool fighting = FALSE; char buf[MAX_STRING_LENGTH]; if ( (chance = get_skill(ch,gsn_blindness_dust)) == 0 || !has_skill(ch,gsn_blindness_dust)) { send_to_char("You don't know how to make blindness dust to throw.\n\r",ch); return; } if( ch->stunned ) { send_to_char("You're still a bit woozy.\n\r",ch); return; } if (ch->mana < 36) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() + 10 > chance) { act("$n hurls some dust into the air but it is blown away.",ch,0,0,TO_ROOM); send_to_char("You throw out some dust but it is blown away.\n\r",ch); ch->mana -= 18; check_improve(ch,gsn_blindness_dust,FALSE,2); WAIT_STATE(ch,12); return; } act("$n hurls a handful of dust into the room!",ch,0,0,TO_ROOM); send_to_char("You throw a handful of blindness dust into the room!\n\r",ch); check_improve(ch,gsn_blindness_dust,TRUE,2); if (ch->fighting != NULL) fighting = TRUE; af.where = TO_AFFECTS; af.type = gsn_blindness_dust; af.level = ch->level; af.duration = (ch->level)/25; af.bitvector = AFF_BLIND; af.location = APPLY_HITROLL; af.modifier = -4; ch->mana -= 36; WAIT_STATE(ch,12); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_quiet(ch,vch)) continue; if (is_same_group(ch,vch)) continue; if (!IS_AFFECTED(vch,AFF_BLIND) && !saves_spell( ch->level,vch,DAM_OTHER)) { act("$n appears blinded.",vch,0,0,TO_ROOM); send_to_char("You get dust in your eyes.\n\r",vch); affect_to_char(vch,&af); } if (!IS_NPC(vch) && !IS_NPC(ch) && (vch->fighting == NULL || (!fighting))) { sprintf(buf,"Help! %s just threw dust in my eyes!",PERS(ch,vch)); do_yell(vch,buf); } if (vch->fighting == NULL) multi_hit(vch,ch,TYPE_UNDEFINED); } return; } void do_will_of_iron(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; // int counter; if (((get_skill(ch,gsn_will_of_iron)) <= 0) || !has_skill(ch,gsn_will_of_iron) || IS_NPC(ch)) { send_to_char( "Huh?\n\r", ch ); return; } if (is_affected(ch,gsn_will_of_iron)) { send_to_char("You are already focusing your will!\n\r",ch); return; } send_to_char("You focus your energy, and your will becomes strong as steel.\n\r",ch); //check_improve(ch,gsn_will_of_iron,TRUE,1); af.where = TO_AFFECTS; af.type = gsn_will_of_iron; af.level = ch->level; af.duration = ch->level/5 + 5; af.location = APPLY_AC; af.modifier = -1*(ch->level*5/8); af.bitvector = 0; affect_to_char( ch, &af ); af.modifier = -25; af.location = APPLY_HITROLL; affect_to_char( ch, &af ); af.location = APPLY_REGEN; af.modifier = 100; affect_to_char( ch, &af ); // for(counter = 0; counter < 3250; counter++) improve_toughness(ch); check_improve(ch,gsn_will_of_iron,TRUE,1); return; } void do_healing_trance(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; if (((get_skill(ch,gsn_healing_trance)) <= 0) || !has_skill(ch,gsn_healing_trance) || IS_NPC(ch)) { send_to_char( "Huh?\n\r", ch ); return; } if (ch->fighting != NULL) { send_to_char("You are too busy fighting to meditate.\n\r",ch); return; } if (is_affected(ch,gsn_healing_trance)) { send_to_char("You are already at an inner peace.\n\r",ch); return; } do_rest(ch,""); send_to_char("You relax and concentrate on healing your wounds.\n\r",ch); check_improve(ch,gsn_healing_trance,TRUE,1); af.where = TO_AFFECTS; af.level = ch->level; af.type = gsn_healing_trance; af.location = APPLY_REGEN; af.modifier = (ch->level-1)*2.0; af.bitvector = 0; af.duration = 4; affect_to_char(ch,&af); af.location = APPLY_MANA_REGEN; af.modifier = (ch->level-1)*.1; affect_to_char(ch,&af); ch->stunned = 4; return; } void do_trance(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; if(((get_skill(ch,gsn_meditation)) <= 0) || !has_skill(ch,gsn_meditation) || IS_NPC(ch)) { send_to_char( "Huh?\n\r",ch); return; } if(ch->fighting != NULL) { send_to_char("You are too busy fighting to meditate.\n\r",ch); return; } if (is_affected(ch,gsn_meditation)) { send_to_char("You are already meditating.\n\r",ch); return; } do_rest(ch,""); send_to_char("You relax and focus your mind within.\n\r",ch); check_improve(ch,gsn_meditation,TRUE,1); af.where = TO_AFFECTS; af.level = ch->level; af.type = gsn_meditation; af.location = APPLY_REGEN; af.modifier = (ch->level-1)*1; af.bitvector = 0; af.duration = 10; affect_to_char(ch,&af); af.location = APPLY_MANA_REGEN; af.modifier = (ch->level-1)*2.5; affect_to_char(ch,&af); //ch->stunned = 4; return; } void do_purify_body(CHAR_DATA *ch,char *argument) { AFFECT_DATA *af; sh_int af_type; sh_int sn; sn = gsn_purify_body; if (((get_skill(ch,gsn_purify_body)) <= 0) || !has_skill(ch,gsn_purify_body) || IS_NPC(ch)) { send_to_char( "Huh?\n\r", ch ); return; } if (is_affected(ch,gsn_martial_arts)) { send_to_char( "Not while your mind focuses on the art of war.\n\r",ch); return; } send_to_char("You go into a deep trance and purify your body.\n\r",ch); check_improve(ch,gsn_purify_body,TRUE,1); for ( af = ch->affected; af != NULL; af = af->next ) { af_type = af->type; if( af_type < 0 || af_type > MAX_SKILL) { bug("Problem: Monk :: Purify Body :: Affect remove",0); return; } if( af_type != gsn_healing_trance && skill_table[af_type].slot != 999 ) check_dispel(ch->level+35,ch,af->type); } do_sleep(ch,""); ch->stunned = 2; WAIT_STATE(ch,24); return; } /*void do_spinkick(CHAR_DATA *ch, char *argument) { ROOM_INDEX_DATA *was_in; CHAR_DATA *victim,*vch,*vch_next; int attempt, chance, dam, level; char arg1[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; one_argument(argument,arg1); if(IS_NPC(ch)) return; if ( (chance = get_skill(ch,gsn_spinkick)) == 0 || !has_skill(ch,gsn_spinkick)) { send_to_char("Huh?\n\r",ch); return; } if(ch->fighting != NULL) victim = ch->fighting; else { if( (victim = get_char_room(ch,arg1)) == NULL ) { send_to_char("They're not here.\n\r",ch); return; } } if(victim == ch) { send_to_char("Kicking yourself? get real.\n\r",ch); return; } if (!IS_NPC(victim) && !can_pkill(ch,victim)) { send_to_char("You can't seem to kick them.",ch); return; } if (IS_AFFECTED(ch,AFF_FEAR) && (number_percent() <= 25)) { act("You attempt to spin kick, but begin crying instead.",ch,NULL,NULL,TO_CHAR); act("$n attempts to spin kick, but begins crying instead.",ch,NULL,NULL,TO_ROOM); WAIT_STATE(ch,DEF_FEAR_WAIT); return; } if(ch->stunned) { send_to_char("You are still a bit woozy.\n\r",ch); return; } level = ch->level + 5; // chance = (ch->level - victim->level) * 2; chance += number_range(20,50); chance -= get_curr_stat(victim,STAT_DEX)/2; chance -= get_curr_stat(victim,STAT_STR)/3; chance += get_curr_stat(ch,STAT_STR)/3; chance += get_curr_stat(ch,STAT_DEX); if (IS_AFFECTED(victim,AFF_HASTE)) chance -= 30; if (IS_AFFECTED(ch,AFF_HASTE)) chance += 25; if (IS_AFFECTED(victim,AFF_SLOW)) chance += 20; if (IS_AFFECTED(ch,AFF_SLOW)) chance -= 30; if (IS_AFFECTED(victim,AFF_FLYING)) chance += 5; chance += (ch->size - victim->size)*10; if (!IS_NPC(victim) && !IS_NPC(ch) && (victim->hit > 1)) { sprintf(buf,"Help! %s just tried to kick me out of the room!",PERS(ch,victim)); if(ch->fighting == NULL) { do_yell(victim,buf); } } if (number_percent() > chance) { act("You spin your leg around but miss $N.",ch,0,victim,TO_CHAR); act("$n spins his leg around but misses you.",ch,0,victim,TO_VICT); act("$n spins his leg visciously at $N but misses.",ch,0,victim,TO_NOTVICT); check_improve(ch,gsn_spinkick,FALSE,3); WAIT_STATE(ch,10); if(victim->fighting == NULL) multi_hit(victim,ch,TYPE_UNDEFINED); return; } was_in = victim->in_room; dam = dice(level,8); // Stance modifier if (!IS_NPC(ch) && ch->stance[0] > 0 && number_percent() < 3) { int stance = ch->stance[0]; if (ch->stance[stance] >= 200) dam += dice(ch->stance[stance],2); else if(ch->stance[stance] > 0) dam += dice(ch->stance[stance],1); } if(number_percent() < 25) { for ( attempt = 0; attempt < 6; attempt++ ) { EXIT_DATA *pexit; int door; char dir[MAX_STRING_LENGTH/4]; door = number_door( ); if (door == 0) (strcpy(dir,"north")); else if (door == 1) (strcpy(dir,"east")); else if (door == 2) (strcpy(dir,"south")); else if (door == 3) (strcpy(dir,"west")); else if (door == 4) (strcpy(dir,"up")); else if (door == 5) (strcpy(dir,"down")); else strcpy(dir,"none"); if ( ( pexit = was_in->exit[door] ) == 0 || pexit->u1.to_room == NULL || ( IS_SET(pexit->exit_info, EX_CLOSED) ) || ( IS_NPC(victim) && IS_SET(pexit->u1.to_room->room_flags, ROOM_NO_MOB) ) ) continue; if ( ( was_in->sector_type == SECT_AIR) || ( (pexit->u1.to_room->sector_type == SECT_AIR ) && ( !IS_AFFECTED(victim, AFF_FLYING) ) ) ) continue; if (IS_SET(pexit->exit_info,EX_CLOSED)) { act("You spin around and kick $N through the door with incredible force!",ch,0,victim,TO_CHAR); act("$n's spin kick sends $N crashing through the door with incredible force!",ch,0,victim,TO_NOTVICT); act("$n spins around and kicks you through the door with incredible force!",ch,0,victim,TO_VICT); } else { act("You spin your leg visciously at $N and kick $M from the room!",ch,0,victim,TO_CHAR); act("$n spins his leg visciously at $N and kicks $M from the room!",ch,NULL,victim,TO_NOTVICT); act("$n spins his leg visciously at you and kicks you from the room!",ch,0,victim,TO_VICT); dam = dice(level,5); } for(vch = victim->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if(IS_IMMORTAL(vch)) { sprintf(buf,"\n\r%s is kicked %s.",victim->name,dir); send_to_char(buf,vch); } } char_from_room(victim); char_to_room(victim, pexit->u1.to_room); do_look(victim,"auto"); if (IS_SET(pexit->exit_info,EX_CLOSED)) { REMOVE_BIT(pexit->exit_info,EX_CLOSED); act("With a deafening crash the door explodes open and $n comes flying into the room!",victim,0,0,TO_ROOM); } else { act("$n comes flying into the room with incredible force!",victim,0,0,TO_ROOM); } if (saves_spell(ch->level,victim,DAM_BASH)) dam /= 2; damage(ch,victim,dam,gsn_spinkick,DAM_BASH,TRUE,0); WAIT_STATE(victim,36); WAIT_STATE(ch,24); stop_fighting( ch, TRUE ); return; } if( attempt == 6 ) { dam += dice(level,4); act("You spin your leg viscously at $N and kick $M brutally into a wall!",ch,0,victim,TO_CHAR); act("$n spins his leg viscously at $N and kicks $M brutally into a wall!",ch,0,victim,TO_NOTVICT); act("$n spins his leg viscously at you and kicks you brutally into a wall!",ch,0,victim,TO_VICT); if (saves_spell(ch->level,victim,DAM_BASH)) dam /= 2; damage(ch,victim,dam,gsn_spinkick,DAM_BASH,TRUE,0); WAIT_STATE(ch,24); WAIT_STATE(victim,24); } } else { act("You spin your leg viscously at $N and kick $M brutally!",ch,0,victim,TO_CHAR); act("$n spins his leg viscously at $N and kicks $M brutally!",ch,0,victim,TO_NOTVICT); act("$n spins his leg viscously at you and kicks you brutally!",ch,0,victim,TO_VICT); if (saves_spell(ch->level-4,victim,DAM_BASH)) dam /= 2; damage(ch,victim,dam,gsn_spinkick,DAM_BASH,TRUE,0); if(number_range(1,2) == 2) WAIT_STATE(victim,24); else WAIT_STATE(victim,12); WAIT_STATE(ch,12); } return; }*/ /*void do_chop( CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int chance, dam; char arg[MAX_INPUT_LENGTH]; OBJ_DATA *wield,*second; int multiplier; bool DUAL = FALSE; dam = 0; one_argument(argument,arg); if ((chance = get_skill(ch,gsn_chop) ) == 0 || !has_skill(ch,gsn_chop) ) { send_to_char("Chopping? What's that?\n\r",ch); return; } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r",ch); return; } } else if ( (victim = get_char_room(ch,arg)) == NULL ) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't chop at yourself!\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_FEAR) && (number_percent() <= 25)) { act("You attempt to chop, but begin crying instead.",ch,NULL,NULL,TO_CHAR); act("$n attempts to chop, but begins crying instead.",ch,NULL,NULL,TO_ROOM); WAIT_STATE(ch,DEF_FEAR_WAIT); return; } if(ch->stunned) { send_to_char("You are still a bit woozy.\n\r",ch); return; } wield = get_eq_char(ch,WEAR_WIELD); second = get_eq_char(ch,WEAR_SECONDARY); if ((wield == NULL) || (( wield->value[0] != WEAPON_SWORD) && ( wield->value[0] != WEAPON_AXE) && ( wield->value[0] != WEAPON_DAGGER) )) { if ((second == NULL) || (( second->value[0] != WEAPON_SWORD) && ( second->value[0] != WEAPON_AXE) && ( second->value[0] != WEAPON_DAGGER) )) { send_to_char("You must be wielding a sword or axe to chop.\n\r",ch); return; } else { DUAL = TRUE; } } if (is_safe(ch,victim) ) return; chance += ch->carry_weight/25; chance -= victim->carry_weight/20; chance += (ch->size - victim->size)*20; chance -= get_curr_stat(victim,STAT_DEX); chance += get_curr_stat(ch,STAT_STR)/3; chance += get_curr_stat(ch,STAT_DEX)/2; if (IS_AFFECTED(ch,AFF_HASTE) ) chance += 10; if (IS_AFFECTED(victim,AFF_HASTE) ) chance -= 10; chance += (ch->level - victim->level); act("$n attempts to split open $N with a quick chop!",ch,0,victim,TO_NOTVICT); act("You attempt to split open $N with a quick chop!",ch,0,victim,TO_CHAR); act("$n attempts to split you open with a quick chop!",ch,0,victim,TO_VICT); if (number_percent() < chance) { check_improve(ch,gsn_lunge,TRUE,1); WAIT_STATE(ch,skill_table[gsn_chop].beats); if(DUAL) wield = second; if (wield->pIndexData->new_format) dam = dice(wield->value[1],wield->value[2]); else dam = number_range(wield->value[1],wield->value[2]); if (get_skill(ch,gsn_enhanced_damage) > 0 ) { if (number_percent() <= get_skill(ch,gsn_enhanced_damage) ) { check_improve(ch,gsn_enhanced_damage,TRUE,1); dam += dam * (number_range(50,100)/100) * ch->pcdata->learned[gsn_enhanced_damage]/100; } } dam += GET_DAMROLL(ch); dam *= ch->pcdata->learned[gsn_chop]; dam /= 100; multiplier = number_range(ch->level/8, ch->level/4); multiplier /= 10; multiplier += 5/4; dam *= multiplier; if(!DUAL && IS_WEAPON_STAT(wield,WEAPON_TWO_HANDS)) dam *= 1.5; if (dam <= 0) dam = 1; damage(ch,victim,dam,gsn_chop,DAM_PIERCE,TRUE,0); } else { damage(ch,victim,dam,gsn_chop,DAM_PIERCE,TRUE,0); check_improve(ch,gsn_chop,FALSE,1); WAIT_STATE(ch,skill_table[gsn_chop].beats); } return; } */