/*************************************************************************** * ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR * * ANATOLIA has been brought to you by ANATOLIA consortium * * Serdar BULUT {Chronos} bulut@rorqual.cc.metu.edu.tr * * Ibrahim Canpunar {Asena} canpunar@rorqual.cc.metu.edu.tr * * Murat BICER {KIO} mbicer@rorqual.cc.metu.edu.tr * * D.Baris ACAR {Powerman} dbacar@rorqual.cc.metu.edu.tr * * By using this code, you have agreed to follow the terms of the * * ANATOLIA license, in the file Anatolia/anatolia.licence * ***************************************************************************/ /*************************************************************************** * 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 * ***************************************************************************/ #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 ); /* used to converter of prac and train */ void do_gain(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *trainer; 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_PRACTICE) || IS_SET(trainer->act,ACT_TRAIN) || 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; } one_argument(argument,arg); if (arg[0] == '\0') { do_say(trainer,"You may convert 10 practices into 1 train."); do_say(trainer,"You may revert 1 train into 10 practices."); do_say(trainer,"Simply type 'gain convert' or 'gain revert'."); return; } if (!str_prefix(arg,"revert")) { if (ch->train < 1) { act("$N tells you 'You are not yet ready.'", ch,NULL,trainer,TO_CHAR); return; } act("$N helps you apply your training to practice", ch,NULL,trainer,TO_CHAR); ch->practice += 10; ch->train -=1 ; return; } if (!str_prefix(arg,"convert")) { if (ch->practice < 10) { act("$N tells you 'You are not yet ready.'", ch,NULL,trainer,TO_CHAR); return; } act("$N helps you apply your practice to training", ch,NULL,trainer,TO_CHAR); ch->practice -= 10; ch->train +=1 ; return; } act("$N tells you 'I do not understand...'",ch,NULL,trainer,TO_CHAR); } /* RT spells and skills show the players spells (or skills) */ 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 output[4*MAX_STRING_LENGTH]; if (IS_NPC(ch)) return; /* initilize data */ output[0] = '\0'; 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 && RACE_OK(ch,sn) && (skill_table[sn].cabal == ch->cabal || skill_table[sn].cabal == CABAL_NONE) ) { found = TRUE; lev = skill_table[sn].skill_level[ch->class]; if (ch->level < lev) sprintf(buf,"%-18s n/a ", skill_table[sn].name); else { mana = UMAX(skill_table[sn].min_mana, 100/(2 + ch->level - lev)); sprintf(buf,"%-18s %3d mana ",skill_table[sn].name,mana); } if (spell_list[lev][0] == '\0') sprintf(spell_list[lev],"\n\rLevel %2d: %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') strcat(output,spell_list[lev]); strcat(output,"\n\r"); page_to_char(output,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; if (skill_table[sn].skill_level[ch->class] < LEVEL_HERO && skill_table[sn].spell_fun == spell_null && RACE_OK(ch,sn) && (skill_table[sn].cabal == ch->cabal || skill_table[sn].cabal == CABAL_NONE) ) { found = TRUE; lev = skill_table[sn].skill_level[ch->class]; if (ch->level < lev) sprintf(buf,"%-18s n/a ", skill_table[sn].name); else sprintf(buf,"%-18s %3d%% ",skill_table[sn].name, ch->pcdata->learned[sn]); if (skill_list[lev][0] == '\0') sprintf(skill_list[lev],"\n\rLevel %2d: %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); } int base_exp(CHAR_DATA *ch, int points) { int expl; if (IS_NPC(ch)) return 1500; expl = 1000 + pc_race_table[ORG_RACE(ch)].points + class_table[ch->class].points; return (expl * pc_race_table[ORG_RACE(ch)].class_mult[ch->class]/100); } int exp_to_level(CHAR_DATA *ch, int points) { int base; base = base_exp(ch,points); return ( base - exp_this_level(ch,ch->level,points) ); } int exp_this_level(CHAR_DATA *ch, int level, int points) { int base; base = base_exp(ch,points); return (ch->exp - (ch->level * base ) ); } int exp_per_level(CHAR_DATA *ch, int points) { int expl; if (IS_NPC(ch)) return 1000; expl = 1000 + pc_race_table[ORG_RACE(ch)].points + class_table[ch->class].points; return expl * pc_race_table[ORG_RACE(ch)].class_mult[ch->class]/100; } /* 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; if (ch->level < skill_table[sn].skill_level[ch->class] || skill_table[sn].rating[ch->class] == 0 || 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); 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) { sprintf(buf,"$CYou have become better at %s!$c", skill_table[sn].name); act_color(buf,ch,NULL,NULL,TO_CHAR,POS_DEAD, CLR_GREEN); ch->pcdata->learned[sn]++; gain_exp(ch,2 * skill_table[sn].rating[ch->class]); } } else { chance = URANGE(5,ch->pcdata->learned[sn]/2,30); if (number_percent() < chance) { sprintf(buf, "$CYou learn from your mistakes, and your %s skill improves.$c", skill_table[sn].name); act_color(buf,ch,NULL,NULL,TO_CHAR,POS_DEAD,CLR_GREEN); ch->pcdata->learned[sn] += number_range(1,3); ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100); gain_exp(ch,2 * skill_table[sn].rating[ch->class]); } } } /* use for adding all skills available for that ch */ void group_add( CHAR_DATA *ch ) { int sn; if (IS_NPC(ch)) /* NPCs do not have skills */ return; for (sn = 0; sn < MAX_SKILL; sn++) if (skill_table[sn].cabal == 0 && RACE_OK(ch,sn) && ch->pcdata->learned[sn] < 1 && skill_table[sn].skill_level[ch->class] < LEVEL_IMMORTAL) ch->pcdata->learned[sn] = 1; return; } void do_slist(CHAR_DATA *ch, char *argument) { char skill_list[LEVEL_HERO][MAX_STRING_LENGTH]; char skill_columns[LEVEL_HERO]; int sn,lev,class; bool found = FALSE; char output[4*MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; if (IS_NPC(ch)) return; output[0] = '\0'; argument = one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("syntax: slist <class name>.\n\r",ch); return; } class = class_lookup(arg); if (class == -1) { send_to_char("That is not a valid class.\n\r",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; if (skill_table[sn].skill_level[class] < LEVEL_HERO && skill_table[sn].cabal == CABAL_NONE && skill_table[sn].race == RACE_NONE ) { found = TRUE; lev = skill_table[sn].skill_level[class]; sprintf(buf,"%-18s ",skill_table[sn].name); if (skill_list[lev][0] == '\0') sprintf(skill_list[lev],"\n\rLevel %2d: %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("That class know no skills.\n\r",ch); return; } for (lev = 0; lev < LEVEL_HERO; lev++) if (skill_list[lev][0] != '\0') strcat(output,skill_list[lev]); strcat(output,"\n\r"); page_to_char(output,ch); } /* returns group number */ int group_lookup (const char *name) { int gr; for ( gr = 0; prac_table[gr].sh_name != NULL; gr++) { if (LOWER(name[0]) == LOWER(prac_table[gr].sh_name[0]) && !str_prefix( name,prac_table[gr].sh_name)) return gr; } return -1; } void do_glist( CHAR_DATA *ch , char *argument) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; int group,count; one_argument(argument,arg); if (arg[0] == '\0') { send_to_char("Syntax : glist <group>\n\r",ch); return; } if ((group = group_lookup(arg) ) == -1) { send_to_char("That is not a valid group.\n\r",ch); return; } sprintf(buf,"Now listing group %s :\n\r",prac_table[group].sh_name); send_to_char(buf,ch); buf[0] = '\0'; for(count = 0 ; count < MAX_SKILL; count++) { if ( (group == GROUP_NONE && !CLEVEL_OK(ch,count) && skill_table[count].group == GROUP_NONE ) || (group != skill_table[count].group) || !CABAL_OK(ch,count) ) continue; if ( buf[0] != '\0') { sprintf(buf , "%-18s%-18s\n\r", buf,skill_table[count].name); send_to_char(buf,ch); buf[0] = '\0'; } else sprintf(buf, "%-18s",skill_table[count].name); } } void do_slook( CHAR_DATA *ch, char *argument) { int sn; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; one_argument(argument,arg); if (arg[0] == '\0') { send_to_char("Syntax : slook <skill or spell name>.\n\r",ch); return; } if ( (sn = skill_lookup(arg)) == -1 ) { send_to_char("That is not a spell or skill.\n\r",ch); return; } sprintf(buf,"Skill :%s in group %s.\n\r", skill_table[sn].name,prac_table[skill_table[sn].group].sh_name); send_to_char(buf,ch); return; } #define PC_PRACTICER 123 void do_learn( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; int sn; CHAR_DATA *mob; int adept; if ( IS_NPC(ch) ) return; if ( !IS_AWAKE(ch) ) { send_to_char( "In your dreams, or what?\n\r", ch ); return; } if ( argument[0] == '\0') { send_to_char( "Syntax: learn <skill | spell> <player>.\n\r", ch ); return; } if ( ch->practice <= 0 ) { send_to_char( "You have no practice sessions left.\n\r", ch ); return; } argument = one_argument(argument,arg); if ( ( sn = find_spell( ch,arg ) ) < 0 || ( !IS_NPC(ch) && (ch->level < skill_table[sn].skill_level[ch->class] || !RACE_OK(ch,sn) || (skill_table[sn].cabal != ch->cabal && skill_table[sn].cabal != CABAL_NONE) ))) { send_to_char( "You can't practice that.\n\r", ch ); return; } if ( sn == gsn_vampire ) { send_to_char( "You can't practice that, only available at questor.\n\r",ch); return; } argument = one_argument(argument,arg); if ( (mob = get_char_room(ch,arg) ) == NULL) { send_to_char( "Your hero is not here.\n\r", ch ); return; } if ( IS_NPC(mob) || mob->level != HERO ) { send_to_char("You must find a hero , not an ordinary one.\n\r",ch); return; } if ( mob->status != PC_PRACTICER ) { send_to_char("Your hero doesn't want to teach you anything.\n\r",ch); return; } if (get_skill(mob,sn) < 100) { send_to_char("Your hero doesn't know that skill enough to teach you.\n\r",ch); return; } adept = class_table[ch->class].skill_adept; if ( ch->pcdata->learned[sn] >= adept ) { sprintf( buf, "You are already learned at %s.\n\r", skill_table[sn].name ); send_to_char( buf, ch ); } else { if (!ch->pcdata->learned[sn]) ch->pcdata->learned[sn] = 1; ch->practice--; ch->pcdata->learned[sn] += int_app[get_curr_stat(ch,STAT_INT)].learn / UMAX(skill_table[sn].rating[ch->class],1); mob->status = 0; act( "You teach $T.", mob, NULL, skill_table[sn].name, TO_CHAR ); act( "$n teachs $T.", mob, NULL, skill_table[sn].name, TO_ROOM ); if ( ch->pcdata->learned[sn] < adept ) { act( "You learn $T.", ch, NULL, skill_table[sn].name, TO_CHAR ); act( "$n learn $T.", ch, NULL, skill_table[sn].name, TO_ROOM ); } else { ch->pcdata->learned[sn] = adept; act( "You are now learned at $T.", ch, NULL, skill_table[sn].name, TO_CHAR ); act( "$n is now learned at $T.", ch, NULL, skill_table[sn].name, TO_ROOM ); } } return; } void do_teach( CHAR_DATA *ch, char *argument) { if (IS_NPC(ch) || ch->level != LEVEL_HERO) { send_to_char("You must be a hero.\n\r",ch); return; } ch->status = PC_PRACTICER; send_to_char("Now , you can teach youngsters your 100% skills.\n\r",ch); return; }