/*************************************************************************** * 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 "recycle.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(CHAR_DATA *ch, sh_int sn); void check_ground_stomp(CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam); void check_follow_through(CHAR_DATA *ch, CHAR_DATA *victim, int dam); bool check_dispel( int dis_level, CHAR_DATA *victim, int sn); bool is_safe_quiet(CHAR_DATA * ch, CHAR_DATA * victim); void improve_toughness(CHAR_DATA *ch); char *magtype_name(int id) { switch (id) { case MAGIC_WHITE: return "white"; case MAGIC_RED: return "red"; case MAGIC_BLUE: return "blue"; case MAGIC_GREEN: return "green"; case MAGIC_BLACK: return "black"; case MAGIC_ORANGE: return "orange"; default: return "unknown"; } } /* 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], FALSE, TRUE); } } 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], FALSE, TRUE); } } } /* 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) { BUFFER *buffer; char buf[MAX_STRING_LENGTH]; int classID; if ((classID = class_lookup(argument)) == -1) { send_to_char("That's not a valid class", ch); return; } buffer = new_buf(); sprintf(buf, "Level [ Type ] Name (CP) [ Type ] Name (CP)"); add_buf(buffer, buf); int sn, level, column; for (level = 1; level < LEVEL_HERO; level++) { for (column = 0, sn = 0; sn < MAX_SKILL; sn++) { if (skill_table[sn].skill_level[classID] == level) { if (column % 2 == 0) { if (column == 0) sprintf(buf, "\r\n[%3d] ", level); else strcpy(buf, "\r\n "); add_buf(buffer, buf); } ++column; sprintf(buf, "[%-6s] %-24s (%-2d) ", skill_table[sn].spell_fun != spell_null ? magtype_name(magic_table[sn]) : "skill", skill_table[sn].name, skill_table[sn].rating[classID]); add_buf(buffer, buf); } } } add_buf(buffer, "\r\n"); page_to_char(buffer->string, ch); free_buf(buffer); } void do_showskill(CHAR_DATA *ch, char *argument) { BUFFER *buffer; char buf[MAX_STRING_LENGTH]; int classID, sn; if ((sn = skill_lookup(argument)) == -1) { send_to_char("Thats not a skill or spell.\r\n", ch); return; } buffer = new_buf(); sprintf(buf, "The following classes get '%s':\r\n", skill_table[sn].name); add_buf(buffer, buf); sprintf(buf, "[Level] [CP] Class [Level] [CP] Class [Level] [CP] Class "); add_buf(buffer, buf); int column = 0; for (classID = 0; classID < MAX_CLASS; classID++) { if (skill_table[sn].skill_level[classID] < LEVEL_HERO) { if (column % 3 == 0) add_buf(buffer, "\r\n"); ++column; sprintf(buf, "[ %3d ] [%2d] %-13s", skill_table[sn].skill_level[classID], skill_table[sn].rating[classID], class_table[classID].name); add_buf(buffer, buf); } } add_buf(buffer, "\r\n"); page_to_char(buffer->string, ch); free_buf(buffer); } /* 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; // 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; printf_debug("%s has lost the %s skill.", ch->name, skill_table[skill].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]); printf_debug("%s has gained the %s skill.", ch->name, skill_table[skill].name); } return; } /* Gain a skill into the gain list */ void gain_skill_gain(CHAR_DATA *ch, int skill) { 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); printf_debug("%s can now gain the %s skill.", ch->name, skill_table[skill].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_BARBARIAN) { 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); 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; WAIT_STATE(ch,24); 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) { printf_debug("Problem: Monk :: Purify Body :: Affect remove"); 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]); 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; } */