/**************************************************************************/ // class.cpp - class configuring system, Kal /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with the dawn license * * in licenses.txt... In particular, you may not remove this copyright * * notice. * **************************************************************************/ #include "include.h" // dawn standard includes #include "magic.h" // used for spell_null definition void do_copyclass(char_data *ch, char * argument); int class_lookup(const char *name); char * get_spinfo_data(char_data *ch, int sn); char *tochar_spellfunction(SPELL_FUN *psp); /**************************************************************************/ void do_write_skills(char_data *ch, char *); /**************************************************************************/ /**************************************************************************/ int calc_spell_percent(int clss, int level, int sn); /**************************************************************************/ // Kal bool make_clss_spell_table(int clss) { FILE *fp; char buf[MSL]; char buf2[MSL]; int sp_lev, lev, i, curve_chance; int first_spell = FIRST_SPELL; int last_spell = LAST_SPELL; sprintf (buf, "%s%.8s.csv", CLASSES_DIR, class_table[clss].name); logf ("Generating %s class table into %s", class_table[clss].name,buf); if (!(fp = fopen (buf, "w"))) { bugf ("Could not open file %s in order to generate percentage table for %s.", buf, class_table[clss].name); return false; } fprintf (fp, "Spell percentage table for class %s\n", class_table[clss].name); fprintf (fp,"\n"); // header fprintf (fp, "\"%s\",%s,%s,%s,\"|\",","Spell", "level","prac rating", "low%"); for (i = 1; i <= LEVEL_IMMORTAL; i++) { fprintf (fp,"%d,",i); } fprintf (fp,"\n"); for (sp_lev = 0; sp_lev < MAX_LEVEL+10; sp_lev++) { if (sp_lev == LEVEL_IMMORTAL) { // header fprintf (fp, "\"%s\",%s,%s,%s,\"|\",","Spell", "level","prac rating", "low%"); for (i = 1; i <= LEVEL_IMMORTAL; i++) { fprintf (fp,"%d,",i); } fprintf (fp,"\n"); } for (i = first_spell; i <= last_spell ; i++) { if (skill_table[i].skill_level[clss] == sp_lev) { if (!skill_table[i].name || !skill_table[i].name[0]) continue; fprintf (fp, "\"%s\",%d,%d,%d,\"|\",", skill_table[i].name, skill_table[i].skill_level[clss], skill_table[i].rating[clss], skill_table[i].low_percent_level[clss] ); for (lev = 1; lev <= LEVEL_IMMORTAL && skill_table[i].skill_level[clss]<LEVEL_IMMORTAL; lev++) { curve_chance = calc_spell_percent(clss, lev, i); sprintf(buf2,"%2d.%.2d,", curve_chance/100, curve_chance%100); if (curve_chance==9999) sprintf(buf2, "*,"); if (skill_table[i].rating[clss]<1) sprintf(buf2, "X,"); fprintf (fp,"%s", (skill_table[i].skill_level[clss]<LEVEL_IMMORTAL?buf2:"**imm only**")); } fprintf (fp,"\n"); } } } fclose (fp); return true; } /**************************************************************************/ // Kal void show_class_spell_table(char_data *ch, int clss) { BUFFER *buffer; char buf[MSL]; int sp_lev, i; int first_spell = FIRST_SPELL; int last_spell = LAST_SPELL; buffer = new_buf(); for (sp_lev = 1; sp_lev < MAX_LEVEL+10; sp_lev++) { for (i = first_spell; i <= last_spell ; i++) { if (skill_table[i].skill_level[clss] == sp_lev) { if (!skill_table[i].name || !skill_table[i].name[0]) continue; sprintf(buf,"%s - %-15.15s lvl=%2d, rating=%2d, low%%level=%2d (sn=%d)\r\n", class_table[clss].short_name, skill_table[i].name, skill_table[i].skill_level[clss], skill_table[i].rating[clss], skill_table[i].low_percent_level[clss], i ); add_buf(buffer, buf); } } } for (i = first_spell; i <= last_spell ; i++) { if (skill_table[i].skill_level[clss] == 0) { if (!skill_table[i].name || !skill_table[i].name[0]) continue; sprintf(buf,"%s - %-15.15s unattainable (sn=%d)\r\n", class_table[clss].short_name, skill_table[i].name, i ); add_buf(buffer, buf); } } ch->sendpage(buf_string(buffer)); free_buf(buffer); } /**************************************************************************/ // Kal void show_class_skill_table(char_data *ch, int clss) { BUFFER *buffer; char buf[MSL]; int sp_lev, i; buffer = new_buf(); for (sp_lev = 1; sp_lev < MAX_LEVEL+10; sp_lev++) { for (i = 0; i< MAX_SKILL; i++) { if (IS_NULLSTR(skill_table[i].name)) break; if (skill_table[i].spell_fun != spell_null) continue; if (skill_table[i].skill_level[clss] == sp_lev) { if (!skill_table[i].name || !skill_table[i].name[0]) continue; sprintf(buf,"%s - %-15.15s lvl=%2d, rating=%2d, low%%level=%2d (sn=%d)\r\n", class_table[clss].short_name, skill_table[i].name, skill_table[i].skill_level[clss], skill_table[i].rating[clss], skill_table[i].low_percent_level[clss], i ); add_buf(buffer, buf); } } } for (i = 0; i< MAX_SKILL; i++) { if (IS_NULLSTR(skill_table[i].name)) break; if (skill_table[i].spell_fun != spell_null) continue; if (skill_table[i].skill_level[clss] == 0) { if (!skill_table[i].name || !skill_table[i].name[0]) continue; sprintf(buf,"%s - %-15.15s unattainable (sn=%d)\r\n", class_table[clss].short_name, skill_table[i].name, i ); add_buf(buffer, buf); } } ch->sendpage(buf_string(buffer)); free_buf(buffer); } /**************************************************************************/ // Kal void make_alltables() { int i; log_string ("Generating all classes."); for (i = 0; !IS_NULLSTR(class_table[i].name); i++) { if (make_clss_spell_table(i)) logf("%s percentage table generated and saved to %s%s.csv\r\n", class_table[i].name,CLASSES_DIR, class_table[i].name); else logf("%s percentage table generated and saved to %s%s.csv\r\n", class_table[i].name,CLASSES_DIR, class_table[i].name); } } /**************************************************************************/ // Kal static void display_classrating_info(char_data *ch, int clss_no, int sn) { if(skill_table[sn].skill_level[clss_no]!=0 && skill_table[sn].skill_level[clss_no]<LEVEL_IMMORTAL) { ch->printlnf("%s - %s lvl=%2d, rating=%2d, low%%level=%2d, maxprac=%2d, maxlearn=%2d", class_table[clss_no].short_name, skill_table[sn].name, skill_table[sn].skill_level[clss_no], skill_table[sn].rating[clss_no], skill_table[sn].low_percent_level[clss_no], skill_table[sn].maxprac_percent[clss_no], skill_table[sn].learn_scale_percent[clss_no]); }else{ ch->printlnf("%s - %s (unattainable) - level=%d", class_table[clss_no].short_name, skill_table[sn].name, skill_table[sn].skill_level[clss_no]); } } /****************************************************************************/ // Kal void do_cinfo(char_data *ch, char * argument) { int sn; if(IS_NULLSTR(argument)){ ch->println("Syntax: cinfo <part_of_a_spellname>"); return; } ch->titlebar("CINFO"); ch->println("SINFO: Required realms, spheres, elements & seasons(see help spinfo-key)\r\n" "50%% level on spells with colour codes:\r\n" "`b1`x-`c8`x-`g14`x-`m20`x-`r26`x-`y32" "`x-`S38`x-`w44`x-`W50`x-`Y56`x-`R62`x-`M68`x-`G74" "`x-`C80`x-`B86+`x\r\n" "____________________CLASS____________________________________________"); for(sn=0; sn < MAX_SKILL; sn++ ) { if ( skill_table[sn].name == NULL ) break; if(!str_cmp("reserved", skill_table[sn].name)) continue; if(is_name(argument, skill_table[sn].name)) { int tlevel, clss_no; ch->print( get_spinfo_data(ch, sn)); if(IS_SPELL(sn)){ ch->printlnf("`=rSpell Function: `x%s", tochar_spellfunction(skill_table[sn].spell_fun)); } for (tlevel=1; tlevel<LEVEL_IMMORTAL; tlevel++) { for (clss_no = 0; class_table[clss_no].name; clss_no++) { if (skill_table[sn].skill_level[clss_no]==tlevel && skill_table[sn].rating[clss_no]!=0) { display_classrating_info(ch, clss_no,sn); } } } for (clss_no = 0; class_table[clss_no].name; clss_no++) { if (skill_table[sn].skill_level[clss_no]==0 && skill_table[sn].rating[clss_no]!=0) { display_classrating_info(ch, clss_no,sn); } } } } return; } /**************************************************************************/ // Kal void do_class (char_data *ch ,char * argument) { char clss_name[MIL], skill_name[MIL], level_buf[MIL], rating_buf[MIL], low_percent_level_buf[MIL]; int sn, clss_no, level, rating, low_percent_level, tlevel; bool setting_for_all= false; if (IS_NPC(ch)) { do_huh(ch,""); return; } if (IS_NULLSTR(argument)) { ch->println( "Syntax is: CLASS <class> <skill> [<level> <rating> <low_percent_level>]." ); ch->println( "If you just type CLASS <class> <skill> - it will show you the current settings." ); ch->println( "(use 0 for level, rating and low_percent_level for unchanged." ); ch->println( " or CLASS <class> showspells" ); ch->println( " or CLASS <class> showskills" ); ch->println( " * or CLASS <class> maketable" ); ch->println( " * or CLASS makealltables" ); ch->println( " * or CLASS saveall" ); ch->println( " * or CLASS copy <from> <to>" ); ch->println( " * `YNote: `WSetting the level to the same value as the low_percent_level\r\n" " means the spell can no longer be taught.`x" ); ch->println( " * = restricted commands." ); return; } argument = one_argument (argument, clss_name); argument = one_argument (argument, skill_name); if (IS_TRUSTED(ch,MAX_LEVEL-1) || IS_SET(TRUE_CH(ch)->pcdata->council, COUNCIL_HEADBALANCE) || IS_SET(TRUE_CH(ch)->pcdata->council, COUNCIL_HEADREALM)) {// RESTRICTED COMMANDS BELOW if (!str_cmp(clss_name,"makealltables")) { ch->printlnf("Class percentage tables generated and saved in %s", CLASSES_DIR); ch->println("(Check the system logs if there were any problems)"); make_alltables(); return; } if (!str_cmp(clss_name,"copy")){ char buf[MIL]; sprintf(buf,"'%s' %s", skill_name, argument); do_copyclass(ch, buf); return; } if (!str_cmp(clss_name,"saveall")) { ch->println("Not required."); return; } }// RESTRICTED COMMANDS ABOVE if (!str_cmp(clss_name,"all")) { setting_for_all = true; clss_no = 0; // a default clss, to avoid stupid errors } else { for (clss_no = 0; class_table[clss_no].name; clss_no++){ if (!str_cmp(clss_name, class_table[clss_no].short_name) || !str_prefix(clss_name,class_table[clss_no].name)) break; } if (!class_table[clss_no].name) { ch->printlnf("No class named '%s' exists. Use the 3-letter WHO names (Mag, Cle, Spf etc.)", clss_name); return; } } if (!str_cmp(skill_name,"maketable")) { if (setting_for_all) { ch->printlnf("Class percentage tables generated and saved in %s", CLASSES_DIR); ch->println("(Check the system logs if there were any problems)"); make_alltables(); return; } else { if (make_clss_spell_table(clss_no)) ch->printlnf("Class percentage table generated and saved to %s%s.csv", CLASSES_DIR, class_table[clss_no].name); else ch->printlnf("Class percentage table generated and saved to %s%s.csv", CLASSES_DIR, class_table[clss_no].name); } return; } if (!str_cmp(skill_name,"showspells")) { if (setting_for_all) { ch->wrapln("You can't show all spells of all the class " "tables at the same time."); } else { show_class_spell_table(ch, clss_no); } return; } if (!str_cmp(skill_name,"showskills")) { if (setting_for_all){ ch->wrapln("You can't show all skills of " "all the class tables at the same time."); }else{ show_class_skill_table(ch, clss_no); } return; } if ( (sn = skill_lookup (skill_name)) == -1) { ch->printlnf("There is no such spell/skill as '%s'.", skill_name); return; } if (setting_for_all) { for (tlevel=1; tlevel<MAX_LEVEL; tlevel++) { for (clss_no = 0; class_table[clss_no].name; clss_no++) { if (skill_table[sn].skill_level[clss_no]==tlevel) { display_classrating_info(ch, clss_no,sn); } } } for (clss_no = 0; class_table[clss_no].name; clss_no++) { if (skill_table[sn].skill_level[clss_no]==0) { display_classrating_info(ch, clss_no,sn); } } } else { display_classrating_info(ch, clss_no,sn); } if (IS_NULLSTR(argument)) { return; } if (!IS_ADMIN(ch) && !IS_SET(TRUE_CH(ch)->pcdata->council, COUNCIL_HEADBALANCE) && !IS_SET(TRUE_CH(ch)->pcdata->council, COUNCIL_HEADREALM)) { ch->println("You can't modify anything with your level of access."); return; } argument = one_argument (argument, level_buf); argument = one_argument (argument, rating_buf); if (IS_NULLSTR(argument)) { return; } argument = one_argument (argument, low_percent_level_buf); level = atoi (level_buf); rating = atoi (rating_buf); low_percent_level = atoi (low_percent_level_buf); if (!is_number(level_buf) || level < 0 || level > LEVEL_IMMORTAL) { ch->printlnf("Level range is from 0 to %d.", LEVEL_IMMORTAL); return; } if (!is_number(rating_buf) || rating < 0 || rating > 30) { ch->println("Rating range is from 0 to 30."); return; } if (!is_number(low_percent_level_buf) || low_percent_level < -1 || (level && (low_percent_level > level)) || (!level && (low_percent_level > skill_table[sn].skill_level[clss_no]))) { ch->println("low_percent_level must be between -1 and the level of the spell (inclusive)."); ch->println("-1 will set the low percent to 0, 0 will leave the lowpercent unchanged."); return; } if (setting_for_all) { for (clss_no = 0; class_table[clss_no].name; clss_no++) { if (level) skill_table[sn].skill_level[clss_no] = level; if (rating) skill_table[sn].rating[clss_no] = rating; if (low_percent_level!=0){ if(low_percent_level==-1){ low_percent_level=0; } skill_table[sn].low_percent_level[clss_no] =low_percent_level; } ch->println( "Has been changed to:" ); display_classrating_info(ch,clss_no,sn); } } else { if (level) skill_table[sn].skill_level[clss_no] = level; if (rating) skill_table[sn].rating[clss_no] = rating; if (low_percent_level!=0){ if(low_percent_level==-1){ low_percent_level=0; } skill_table[sn].low_percent_level[clss_no] =low_percent_level; } ch->println( "Has been changed to:" ); display_classrating_info(ch,clss_no,sn); } do_write_skills(NULL,""); } /**************************************************************************/ // Kal void do_copyclass(char_data *ch, char * argument) { char fromClassBuf[MIL], toClassBuf[MIL]; int fromClassIndex, toClassIndex; int i; argument = one_argument (argument, fromClassBuf); fromClassIndex=class_lookup(fromClassBuf); if(fromClassIndex<0){ ch->printlnf("Couldn't find the class '%s' to copy from!", fromClassBuf); return; } argument = one_argument (argument, toClassBuf); toClassIndex=class_lookup(toClassBuf); if(toClassIndex<0){ ch->printlnf("Couldn't find the class '%s' to copy from!", toClassBuf); return; } if(class_table[toClassIndex].creation_selectable){ ch->wraplnf("The '%s' class is creation selectable... you can only copy over a class that is not creation selectable.", class_table[toClassIndex].name); return; } for (i = 0; i< MAX_SKILL; i++){ skill_table[i].skill_level[toClassIndex] =skill_table[i].skill_level[fromClassIndex]; skill_table[i].rating[toClassIndex] =skill_table[i].rating[fromClassIndex]; skill_table[i].low_percent_level[toClassIndex] = skill_table[i].low_percent_level[fromClassIndex]; } ch->printlnf("Skill & Spell copy from '%s' to '%s' completed... use write_skills to save the copy.", fromClassBuf, toClassBuf); } /**************************************************************************/ /**************************************************************************/