00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if defined(macintosh)
00029 #include <types.h>
00030 #include <time.h>
00031 #else
00032 #include <sys/types.h>
00033 #include <sys/time.h>
00034 #endif
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include "merc.h"
00039 #include "interp.h"
00040 #include "magic.h"
00041 #include "recycle.h"
00042
00043
00044 void do_gain (CHAR_DATA * ch, char *argument)
00045 {
00046 char buf[MAX_STRING_LENGTH];
00047 char arg[MAX_INPUT_LENGTH];
00048 CHAR_DATA *trainer;
00049 int gn = 0, sn = 0;
00050
00051 if (IS_NPC (ch))
00052 return;
00053
00054
00055 for (trainer = ch->in_room->people;
00056 trainer != NULL; trainer = trainer->next_in_room)
00057 if (IS_NPC (trainer) && IS_SET (trainer->act, ACT_GAIN))
00058 break;
00059
00060 if (trainer == NULL || !can_see (ch, trainer))
00061 {
00062 send_to_char ("You can't do that here.\n\r", ch);
00063 return;
00064 }
00065
00066 one_argument (argument, arg);
00067
00068 if (arg[0] == '\0')
00069 {
00070 do_function (trainer, &do_say, "Pardon me?");
00071 return;
00072 }
00073
00074 if (!str_prefix (arg, "list"))
00075 {
00076 int col;
00077
00078 col = 0;
00079
00080 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s\n\r",
00081 "group", "cost", "group", "cost", "group", "cost");
00082 send_to_char (buf, ch);
00083
00084 for (gn = 0; gn < MAX_GROUP; gn++)
00085 {
00086 if (group_table[gn].name == NULL)
00087 break;
00088
00089 if (!ch->pcdata->group_known[gn]
00090 && group_table[gn].rating[ch->class] > 0)
00091 {
00092 sprintf (buf, "%-18s %-5d ",
00093 group_table[gn].name,
00094 group_table[gn].rating[ch->class]);
00095 send_to_char (buf, ch);
00096 if (++col % 3 == 0)
00097 send_to_char ("\n\r", ch);
00098 }
00099 }
00100 if (col % 3 != 0)
00101 send_to_char ("\n\r", ch);
00102
00103 send_to_char ("\n\r", ch);
00104
00105 col = 0;
00106
00107 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s\n\r",
00108 "skill", "cost", "skill", "cost", "skill", "cost");
00109 send_to_char (buf, ch);
00110
00111 for (sn = 0; sn < MAX_SKILL; sn++)
00112 {
00113 if (skill_table[sn].name == NULL)
00114 break;
00115
00116 if (!ch->pcdata->learned[sn]
00117 && skill_table[sn].rating[ch->class] > 0
00118 && skill_table[sn].spell_fun == spell_null)
00119 {
00120 sprintf (buf, "%-18s %-5d ",
00121 skill_table[sn].name,
00122 skill_table[sn].rating[ch->class]);
00123 send_to_char (buf, ch);
00124 if (++col % 3 == 0)
00125 send_to_char ("\n\r", ch);
00126 }
00127 }
00128 if (col % 3 != 0)
00129 send_to_char ("\n\r", ch);
00130 return;
00131 }
00132
00133 if (!str_prefix (arg, "practice") || !str_prefix (arg, "prac"))
00134 {
00135 if (ch->train < 1)
00136 {
00137 act ("$N tells you 'You are not read yet.'",
00138 ch,NULL,trainer, TO_CHAR);
00139 return;
00140 }
00141 act ("$N helps you apply your training to practice.",
00142 ch,NULL,trainer, TO_CHAR);
00143 ch->train -=1;
00144 ch->practice +=5;
00145 return;
00146 }
00147
00148
00149 if (!str_prefix (arg, "convert")|| !str_prefix (arg, "conv"))
00150 {
00151 if (ch->practice < 5)
00152 {
00153 act ("$N tells you 'You are not yet ready.'",
00154 ch, NULL, trainer, TO_CHAR);
00155 return;
00156 }
00157
00158 act ("$N helps you apply your practice to training",
00159 ch, NULL, trainer, TO_CHAR);
00160 ch->practice -= 5;
00161 ch->train += 1;
00162 return;
00163 }
00164
00165 if (!str_prefix (arg, "points"))
00166 {
00167 if (ch->train < 2)
00168 {
00169 act ("$N tells you 'You are not yet ready.'",
00170 ch, NULL, trainer, TO_CHAR);
00171 return;
00172 }
00173
00174 if (ch->pcdata->points <= 40)
00175 {
00176 act ("$N tells you 'There would be no point in that.'",
00177 ch, NULL, trainer, TO_CHAR);
00178 return;
00179 }
00180
00181 act ("$N trains you, and you feel more at ease with your skills.",
00182 ch, NULL, trainer, TO_CHAR);
00183
00184 ch->train -= 2;
00185 ch->pcdata->points -= 1;
00186 ch->exp = exp_per_level (ch, ch->pcdata->points) * ch->level;
00187 return;
00188 }
00189
00190
00191
00192 gn = group_lookup (argument);
00193 if (gn > 0)
00194 {
00195 if (ch->pcdata->group_known[gn])
00196 {
00197 act ("$N tells you 'You already know that group!'",
00198 ch, NULL, trainer, TO_CHAR);
00199 return;
00200 }
00201
00202 if (group_table[gn].rating[ch->class] <= 0)
00203 {
00204 act ("$N tells you 'That group is beyond your powers.'",
00205 ch, NULL, trainer, TO_CHAR);
00206 return;
00207 }
00208
00209 if (ch->train < group_table[gn].rating[ch->class])
00210 {
00211 act ("$N tells you 'You are not yet ready for that group.'",
00212 ch, NULL, trainer, TO_CHAR);
00213 return;
00214 }
00215
00216
00217 gn_add (ch, gn);
00218 act ("$N trains you in the art of $t",
00219 ch, group_table[gn].name, trainer, TO_CHAR);
00220 ch->train -= group_table[gn].rating[ch->class];
00221 return;
00222 }
00223
00224 sn = skill_lookup (argument);
00225 if (sn > -1)
00226 {
00227 if (skill_table[sn].spell_fun != spell_null)
00228 {
00229 act ("$N tells you 'You must learn the full group.'",
00230 ch, NULL, trainer, TO_CHAR);
00231 return;
00232 }
00233
00234
00235 if (ch->pcdata->learned[sn])
00236 {
00237 act ("$N tells you 'You already know that skill!'",
00238 ch, NULL, trainer, TO_CHAR);
00239 return;
00240 }
00241
00242 if (skill_table[sn].rating[ch->class] <= 0)
00243 {
00244 act ("$N tells you 'That skill is beyond your powers.'",
00245 ch, NULL, trainer, TO_CHAR);
00246 return;
00247 }
00248
00249 if (ch->train < skill_table[sn].rating[ch->class])
00250 {
00251 act ("$N tells you 'You are not yet ready for that skill.'",
00252 ch, NULL, trainer, TO_CHAR);
00253 return;
00254 }
00255
00256
00257 ch->pcdata->learned[sn] = 1;
00258 act ("$N trains you in the art of $t",
00259 ch, skill_table[sn].name, trainer, TO_CHAR);
00260 ch->train -= skill_table[sn].rating[ch->class];
00261 return;
00262 }
00263
00264 act ("$N tells you 'I do not understand...'", ch, NULL, trainer, TO_CHAR);
00265 }
00266
00267
00268
00269
00270
00271
00272 void do_spells (CHAR_DATA * ch, char *argument)
00273 {
00274 BUFFER *buffer;
00275 char arg[MAX_INPUT_LENGTH];
00276 char spell_list[LEVEL_HERO + 1][MAX_STRING_LENGTH];
00277 char spell_columns[LEVEL_HERO + 1];
00278 int sn, level, min_lev = 1, max_lev = LEVEL_HERO, mana;
00279 bool fAll = FALSE, found = FALSE;
00280 char buf[MAX_STRING_LENGTH];
00281
00282 if (IS_NPC (ch))
00283 return;
00284
00285 if (argument[0] != '\0')
00286 {
00287 fAll = TRUE;
00288
00289 if (str_prefix (argument, "all"))
00290 {
00291 argument = one_argument (argument, arg);
00292 if (!is_number (arg))
00293 {
00294 send_to_char ("Arguments must be numerical or all.\n\r", ch);
00295 return;
00296 }
00297 max_lev = atoi (arg);
00298
00299 if (max_lev < 1 || max_lev > LEVEL_HERO)
00300 {
00301 sprintf (buf, "Levels must be between 1 and %d.\n\r",
00302 LEVEL_HERO);
00303 send_to_char (buf, ch);
00304 return;
00305 }
00306
00307 if (argument[0] != '\0')
00308 {
00309 argument = one_argument (argument, arg);
00310 if (!is_number (arg))
00311 {
00312 send_to_char ("Arguments must be numerical or all.\n\r",
00313 ch);
00314 return;
00315 }
00316 min_lev = max_lev;
00317 max_lev = atoi (arg);
00318
00319 if (max_lev < 1 || max_lev > LEVEL_HERO)
00320 {
00321 sprintf (buf,
00322 "Levels must be between 1 and %d.\n\r",
00323 LEVEL_HERO);
00324 send_to_char (buf, ch);
00325 return;
00326 }
00327
00328 if (min_lev > max_lev)
00329 {
00330 send_to_char ("That would be silly.\n\r", ch);
00331 return;
00332 }
00333 }
00334 }
00335 }
00336
00337
00338
00339 for (level = 0; level < LEVEL_HERO + 1; level++)
00340 {
00341 spell_columns[level] = 0;
00342 spell_list[level][0] = '\0';
00343 }
00344
00345 for (sn = 0; sn < MAX_SKILL; sn++)
00346 {
00347 if (skill_table[sn].name == NULL)
00348 break;
00349
00350 if ((level = skill_table[sn].skill_level[ch->class]) < LEVEL_HERO + 1
00351 && (fAll || level <= ch->level)
00352 && level >= min_lev && level <= max_lev
00353 && skill_table[sn].spell_fun != spell_null
00354 && ch->pcdata->learned[sn] > 0)
00355 {
00356 found = TRUE;
00357 level = skill_table[sn].skill_level[ch->class];
00358 if (ch->level < level)
00359 sprintf (buf, "%-18s n/a ", skill_table[sn].name);
00360 else
00361 {
00362 mana = UMAX (skill_table[sn].min_mana,
00363 100 / (2 + ch->level - level));
00364 sprintf (buf, "%-18s %3d mana (%3d%%) ", skill_table[sn].name,
00365 mana,ch->pcdata->learned[sn]);
00366 }
00367
00368 if (spell_list[level][0] == '\0')
00369 sprintf (spell_list[level], "\n\rLevel %2d: %s", level, buf);
00370 else
00371 {
00372
00373 if (++spell_columns[level] % 2 == 0)
00374 strcat (spell_list[level], "\n\r ");
00375 strcat (spell_list[level], buf);
00376 }
00377 }
00378 }
00379
00380
00381
00382 if (!found)
00383 {
00384 send_to_char ("No spells found.\n\r", ch);
00385 return;
00386 }
00387
00388 buffer = new_buf ();
00389 for (level = 0; level < LEVEL_HERO + 1; level++)
00390 if (spell_list[level][0] != '\0')
00391 add_buf (buffer, spell_list[level]);
00392 add_buf (buffer, "\n\r");
00393 page_to_char (buf_string (buffer), ch);
00394 free_buf (buffer);
00395 }
00396
00397 void do_skills (CHAR_DATA * ch, char *argument)
00398 {
00399 BUFFER *buffer;
00400 char arg[MAX_INPUT_LENGTH];
00401 char skill_list[LEVEL_HERO + 1][MAX_STRING_LENGTH];
00402 char skill_columns[LEVEL_HERO + 1];
00403 int sn, level, min_lev = 1, max_lev = LEVEL_HERO;
00404 bool fAll = FALSE, found = FALSE;
00405 char buf[MAX_STRING_LENGTH];
00406
00407 if (IS_NPC (ch))
00408 return;
00409
00410 if (argument[0] != '\0')
00411 {
00412 fAll = TRUE;
00413
00414 if (str_prefix (argument, "all"))
00415 {
00416 argument = one_argument (argument, arg);
00417 if (!is_number (arg))
00418 {
00419 send_to_char ("Arguments must be numerical or all.\n\r", ch);
00420 return;
00421 }
00422 max_lev = atoi (arg);
00423
00424 if (max_lev < 1 || max_lev > LEVEL_HERO)
00425 {
00426 sprintf (buf, "Levels must be between 1 and %d.\n\r",
00427 LEVEL_HERO);
00428 send_to_char (buf, ch);
00429 return;
00430 }
00431
00432 if (argument[0] != '\0')
00433 {
00434 argument = one_argument (argument, arg);
00435 if (!is_number (arg))
00436 {
00437 send_to_char ("Arguments must be numerical or all.\n\r",
00438 ch);
00439 return;
00440 }
00441 min_lev = max_lev;
00442 max_lev = atoi (arg);
00443
00444 if (max_lev < 1 || max_lev > LEVEL_HERO)
00445 {
00446 sprintf (buf,
00447 "Levels must be between 1 and %d.\n\r",
00448 LEVEL_HERO);
00449 send_to_char (buf, ch);
00450 return;
00451 }
00452
00453 if (min_lev > max_lev)
00454 {
00455 send_to_char ("That would be silly.\n\r", ch);
00456 return;
00457 }
00458 }
00459 }
00460 }
00461
00462
00463
00464 for (level = 0; level < LEVEL_HERO + 1; level++)
00465 {
00466 skill_columns[level] = 0;
00467 skill_list[level][0] = '\0';
00468 }
00469
00470 for (sn = 0; sn < MAX_SKILL; sn++)
00471 {
00472 if (skill_table[sn].name == NULL)
00473 break;
00474
00475 if ((level = skill_table[sn].skill_level[ch->class]) < LEVEL_HERO + 1
00476 && (fAll || level <= ch->level)
00477 && level >= min_lev && level <= max_lev
00478 && skill_table[sn].spell_fun == spell_null
00479 && ch->pcdata->learned[sn] > 0)
00480 {
00481 found = TRUE;
00482 level = skill_table[sn].skill_level[ch->class];
00483 if (ch->level < level)
00484 sprintf (buf, "%-18s n/a ", skill_table[sn].name);
00485 else
00486 sprintf (buf, "%-18s %3d%% ", skill_table[sn].name,
00487 ch->pcdata->learned[sn]);
00488
00489 if (skill_list[level][0] == '\0')
00490 sprintf (skill_list[level], "\n\rLevel %2d: %s", level, buf);
00491 else
00492 {
00493
00494 if (++skill_columns[level] % 2 == 0)
00495 strcat (skill_list[level], "\n\r ");
00496 strcat (skill_list[level], buf);
00497 }
00498 }
00499 }
00500
00501
00502
00503 if (!found)
00504 {
00505 send_to_char ("No skills found.\n\r", ch);
00506 return;
00507 }
00508
00509 buffer = new_buf ();
00510 for (level = 0; level < LEVEL_HERO + 1; level++)
00511 if (skill_list[level][0] != '\0')
00512 add_buf (buffer, skill_list[level]);
00513 add_buf (buffer, "\n\r");
00514 page_to_char (buf_string (buffer), ch);
00515 free_buf (buffer);
00516 }
00517
00518
00519 void list_group_costs (CHAR_DATA * ch)
00520 {
00521 char buf[100];
00522 int gn, sn, col;
00523
00524 if (IS_NPC (ch))
00525 return;
00526
00527 col = 0;
00528
00529 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s\n\r", "group", "cp",
00530 "group", "cp", "group", "cp");
00531 send_to_char (buf, ch);
00532
00533 for (gn = 0; gn < MAX_GROUP; gn++)
00534 {
00535 if (group_table[gn].name == NULL)
00536 break;
00537
00538 if (!ch->gen_data->group_chosen[gn]
00539 && !ch->pcdata->group_known[gn]
00540 && group_table[gn].rating[ch->class] > 0)
00541 {
00542 sprintf (buf, "%-18s %-5d ", group_table[gn].name,
00543 group_table[gn].rating[ch->class]);
00544 send_to_char (buf, ch);
00545 if (++col % 3 == 0)
00546 send_to_char ("\n\r", ch);
00547 }
00548 }
00549 if (col % 3 != 0)
00550 send_to_char ("\n\r", ch);
00551 send_to_char ("\n\r", ch);
00552
00553 col = 0;
00554
00555 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s\n\r", "skill", "cp",
00556 "skill", "cp", "skill", "cp");
00557 send_to_char (buf, ch);
00558
00559 for (sn = 0; sn < MAX_SKILL; sn++)
00560 {
00561 if (skill_table[sn].name == NULL)
00562 break;
00563
00564 if (!ch->gen_data->skill_chosen[sn]
00565 && ch->pcdata->learned[sn] == 0
00566 && skill_table[sn].spell_fun == spell_null
00567 && skill_table[sn].rating[ch->class] > 0)
00568 {
00569 sprintf (buf, "%-18s %-5d ", skill_table[sn].name,
00570 skill_table[sn].rating[ch->class]);
00571 send_to_char (buf, ch);
00572 if (++col % 3 == 0)
00573 send_to_char ("\n\r", ch);
00574 }
00575 }
00576 if (col % 3 != 0)
00577 send_to_char ("\n\r", ch);
00578 send_to_char ("\n\r", ch);
00579
00580 sprintf (buf, "Creation points: %d\n\r", ch->pcdata->points);
00581 send_to_char (buf, ch);
00582 sprintf (buf, "Experience per level: %d\n\r",
00583 exp_per_level (ch, ch->gen_data->points_chosen));
00584 send_to_char (buf, ch);
00585 return;
00586 }
00587
00588
00589 void list_group_chosen (CHAR_DATA * ch)
00590 {
00591 char buf[100];
00592 int gn, sn, col;
00593
00594 if (IS_NPC (ch))
00595 return;
00596
00597 col = 0;
00598
00599 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s", "group", "cp", "group",
00600 "cp", "group", "cp\n\r");
00601 send_to_char (buf, ch);
00602
00603 for (gn = 0; gn < MAX_GROUP; gn++)
00604 {
00605 if (group_table[gn].name == NULL)
00606 break;
00607
00608 if (ch->gen_data->group_chosen[gn]
00609 && group_table[gn].rating[ch->class] > 0)
00610 {
00611 sprintf (buf, "%-18s %-5d ", group_table[gn].name,
00612 group_table[gn].rating[ch->class]);
00613 send_to_char (buf, ch);
00614 if (++col % 3 == 0)
00615 send_to_char ("\n\r", ch);
00616 }
00617 }
00618 if (col % 3 != 0)
00619 send_to_char ("\n\r", ch);
00620 send_to_char ("\n\r", ch);
00621
00622 col = 0;
00623
00624 sprintf (buf, "%-18s %-5s %-18s %-5s %-18s %-5s", "skill", "cp", "skill",
00625 "cp", "skill", "cp\n\r");
00626 send_to_char (buf, ch);
00627
00628 for (sn = 0; sn < MAX_SKILL; sn++)
00629 {
00630 if (skill_table[sn].name == NULL)
00631 break;
00632
00633 if (ch->gen_data->skill_chosen[sn]
00634 && skill_table[sn].rating[ch->class] > 0)
00635 {
00636 sprintf (buf, "%-18s %-5d ", skill_table[sn].name,
00637 skill_table[sn].rating[ch->class]);
00638 send_to_char (buf, ch);
00639 if (++col % 3 == 0)
00640 send_to_char ("\n\r", ch);
00641 }
00642 }
00643 if (col % 3 != 0)
00644 send_to_char ("\n\r", ch);
00645 send_to_char ("\n\r", ch);
00646
00647 sprintf (buf, "Creation points: %d\n\r", ch->gen_data->points_chosen);
00648 send_to_char (buf, ch);
00649 sprintf (buf, "Experience per level: %d\n\r",
00650 exp_per_level (ch, ch->gen_data->points_chosen));
00651 send_to_char (buf, ch);
00652 return;
00653 }
00654
00655 int exp_per_level (CHAR_DATA * ch, int points)
00656 {
00657 int expl, inc;
00658
00659 if (IS_NPC (ch))
00660 return 1000;
00661
00662 expl = 1000;
00663 inc = 500;
00664
00665 if (points < 40)
00666 return 1000 * (pc_race_table[ch->race].class_mult[ch->class] ?
00667 pc_race_table[ch->race].class_mult[ch->class] /
00668 100 : 1);
00669
00670
00671 points -= 40;
00672
00673 while (points > 9)
00674 {
00675 expl += inc;
00676 points -= 10;
00677 if (points > 9)
00678 {
00679 expl += inc;
00680 inc *= 2;
00681 points -= 10;
00682 }
00683 }
00684
00685 expl += points * inc / 10;
00686
00687 return expl * pc_race_table[ch->race].class_mult[ch->class] / 100;
00688 }
00689
00690
00691 bool parse_gen_groups (CHAR_DATA * ch, char *argument)
00692 {
00693 char arg[MAX_INPUT_LENGTH];
00694 char buf[100];
00695 int gn, sn, i;
00696
00697 if (argument[0] == '\0')
00698 return FALSE;
00699
00700 argument = one_argument (argument, arg);
00701
00702 if (!str_prefix (arg, "help"))
00703 {
00704 if (argument[0] == '\0')
00705 {
00706 do_function (ch, &do_help, "group help");
00707 return TRUE;
00708 }
00709
00710 do_function (ch, &do_help, argument);
00711 return TRUE;
00712 }
00713
00714 if (!str_prefix (arg, "add"))
00715 {
00716 if (argument[0] == '\0')
00717 {
00718 send_to_char ("You must provide a skill name.\n\r", ch);
00719 return TRUE;
00720 }
00721
00722 gn = group_lookup (argument);
00723 if (gn != -1)
00724 {
00725 if (ch->gen_data->group_chosen[gn] || ch->pcdata->group_known[gn])
00726 {
00727 send_to_char ("You already know that group!\n\r", ch);
00728 return TRUE;
00729 }
00730
00731 if (group_table[gn].rating[ch->class] < 1)
00732 {
00733 send_to_char ("That group is not available.\n\r", ch);
00734 return TRUE;
00735 }
00736
00737
00738 if (ch->gen_data->points_chosen +
00739 group_table[gn].rating[ch->class] > 300)
00740 {
00741 send_to_char
00742 ("You cannot take more than 300 creation points.\n\r",
00743 ch);
00744 return TRUE;
00745 }
00746
00747 sprintf (buf, "%s group added\n\r", group_table[gn].name);
00748 send_to_char (buf, ch);
00749 ch->gen_data->group_chosen[gn] = TRUE;
00750 ch->gen_data->points_chosen += group_table[gn].rating[ch->class];
00751 gn_add (ch, gn);
00752 ch->pcdata->points += group_table[gn].rating[ch->class];
00753 return TRUE;
00754 }
00755
00756 sn = skill_lookup (argument);
00757 if (sn != -1)
00758 {
00759 if (ch->gen_data->skill_chosen[sn] || ch->pcdata->learned[sn] > 0)
00760 {
00761 send_to_char ("You already know that skill!\n\r", ch);
00762 return TRUE;
00763 }
00764
00765 if (skill_table[sn].rating[ch->class] < 1
00766 || skill_table[sn].spell_fun != spell_null)
00767 {
00768 send_to_char ("That skill is not available.\n\r", ch);
00769 return TRUE;
00770 }
00771
00772
00773 if (ch->gen_data->points_chosen +
00774 skill_table[sn].rating[ch->class] > 300)
00775 {
00776 send_to_char
00777 ("You cannot take more than 300 creation points.\n\r",
00778 ch);
00779 return TRUE;
00780 }
00781 sprintf (buf, "%s skill added\n\r", skill_table[sn].name);
00782 send_to_char (buf, ch);
00783 ch->gen_data->skill_chosen[sn] = TRUE;
00784 ch->gen_data->points_chosen += skill_table[sn].rating[ch->class];
00785 ch->pcdata->learned[sn] = 1;
00786 ch->pcdata->points += skill_table[sn].rating[ch->class];
00787 return TRUE;
00788 }
00789
00790 send_to_char ("No skills or groups by that name...\n\r", ch);
00791 return TRUE;
00792 }
00793
00794 if (!strcmp (arg, "drop"))
00795 {
00796 if (argument[0] == '\0')
00797 {
00798 send_to_char ("You must provide a skill to drop.\n\r", ch);
00799 return TRUE;
00800 }
00801
00802 gn = group_lookup (argument);
00803 if (gn != -1 && ch->gen_data->group_chosen[gn])
00804 {
00805 send_to_char ("Group dropped.\n\r", ch);
00806 ch->gen_data->group_chosen[gn] = FALSE;
00807 ch->gen_data->points_chosen -= group_table[gn].rating[ch->class];
00808 gn_remove (ch, gn);
00809 for (i = 0; i < MAX_GROUP; i++)
00810 {
00811 if (ch->gen_data->group_chosen[gn])
00812 gn_add (ch, gn);
00813 }
00814 ch->pcdata->points -= group_table[gn].rating[ch->class];
00815 return TRUE;
00816 }
00817
00818 sn = skill_lookup (argument);
00819 if (sn != -1 && ch->gen_data->skill_chosen[sn])
00820 {
00821 send_to_char ("Skill dropped.\n\r", ch);
00822 ch->gen_data->skill_chosen[sn] = FALSE;
00823 ch->gen_data->points_chosen -= skill_table[sn].rating[ch->class];
00824 ch->pcdata->learned[sn] = 0;
00825 ch->pcdata->points -= skill_table[sn].rating[ch->class];
00826 return TRUE;
00827 }
00828
00829 send_to_char ("You haven't bought any such skill or group.\n\r", ch);
00830 return TRUE;
00831 }
00832
00833 if (!str_prefix (arg, "premise"))
00834 {
00835 do_function (ch, &do_help, "premise");
00836 return TRUE;
00837 }
00838
00839 if (!str_prefix (arg, "list"))
00840 {
00841 list_group_costs (ch);
00842 return TRUE;
00843 }
00844
00845 if (!str_prefix (arg, "learned"))
00846 {
00847 list_group_chosen (ch);
00848 return TRUE;
00849 }
00850
00851 if (!str_prefix (arg, "info"))
00852 {
00853 do_function (ch, &do_groups, argument);
00854 return TRUE;
00855 }
00856
00857 return FALSE;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866 void do_groups (CHAR_DATA * ch, char *argument)
00867 {
00868 char buf[100];
00869 int gn, sn, col;
00870
00871 if (IS_NPC (ch))
00872 return;
00873
00874 col = 0;
00875
00876 if (argument[0] == '\0')
00877 {
00878
00879 for (gn = 0; gn < MAX_GROUP; gn++)
00880 {
00881 if (group_table[gn].name == NULL)
00882 break;
00883 if (ch->pcdata->group_known[gn])
00884 {
00885 sprintf (buf, "%-20s ", group_table[gn].name);
00886 send_to_char (buf, ch);
00887 if (++col % 3 == 0)
00888 send_to_char ("\n\r", ch);
00889 }
00890 }
00891 if (col % 3 != 0)
00892 send_to_char ("\n\r", ch);
00893 sprintf (buf, "Creation points: %d\n\r", ch->pcdata->points);
00894 send_to_char (buf, ch);
00895 return;
00896 }
00897
00898 if (!str_cmp (argument, "all"))
00899 {
00900 for (gn = 0; gn < MAX_GROUP; gn++)
00901 {
00902 if (group_table[gn].name == NULL)
00903 break;
00904 sprintf (buf, "%-20s ", group_table[gn].name);
00905 send_to_char (buf, ch);
00906 if (++col % 3 == 0)
00907 send_to_char ("\n\r", ch);
00908 }
00909 if (col % 3 != 0)
00910 send_to_char ("\n\r", ch);
00911 return;
00912 }
00913
00914
00915
00916 gn = group_lookup (argument);
00917 if (gn == -1)
00918 {
00919 send_to_char ("No group of that name exist.\n\r", ch);
00920 send_to_char
00921 ("Type 'groups all' or 'info all' for a full listing.\n\r", ch);
00922 return;
00923 }
00924
00925 for (sn = 0; sn < MAX_IN_GROUP; sn++)
00926 {
00927 if (group_table[gn].spells[sn] == NULL)
00928 break;
00929 sprintf (buf, "%-20s ", group_table[gn].spells[sn]);
00930 send_to_char (buf, ch);
00931 if (++col % 3 == 0)
00932 send_to_char ("\n\r", ch);
00933 }
00934 if (col % 3 != 0)
00935 send_to_char ("\n\r", ch);
00936 }
00937
00938
00939 void check_improve (CHAR_DATA * ch, int sn, bool success, int multiplier)
00940 {
00941 int chance;
00942 char buf[100];
00943
00944 if (IS_NPC (ch))
00945 return;
00946
00947 if (ch->level < skill_table[sn].skill_level[ch->class]
00948 || skill_table[sn].rating[ch->class] == 0
00949 || ch->pcdata->learned[sn] == 0 || ch->pcdata->learned[sn] == 100)
00950 return;
00951
00952
00953 chance = 10 * int_app[get_curr_stat (ch, STAT_INT)].learn;
00954 chance /= (multiplier * skill_table[sn].rating[ch->class] * 4);
00955 chance += ch->level;
00956
00957 if (number_range (1, 1000) > chance)
00958 return;
00959
00960
00961
00962 if (success)
00963 {
00964 chance = URANGE (5, 100 - ch->pcdata->learned[sn], 95);
00965 if (number_percent () < chance)
00966 {
00967 sprintf (buf, "You have become better at %s!\n\r",
00968 skill_table[sn].name);
00969 send_to_char (buf, ch);
00970 ch->pcdata->learned[sn]++;
00971 gain_exp (ch, 2 * skill_table[sn].rating[ch->class]);
00972 }
00973 }
00974
00975 else
00976 {
00977 chance = URANGE (5, ch->pcdata->learned[sn] / 2, 30);
00978 if (number_percent () < chance)
00979 {
00980 sprintf (buf,
00981 "You learn from your mistakes, and your %s skill improves.\n\r",
00982 skill_table[sn].name);
00983 send_to_char (buf, ch);
00984 ch->pcdata->learned[sn] += number_range (1, 3);
00985 ch->pcdata->learned[sn] = UMIN (ch->pcdata->learned[sn], 100);
00986 gain_exp (ch, 2 * skill_table[sn].rating[ch->class]);
00987 }
00988 }
00989 }
00990
00991
00992 int group_lookup (const char *name)
00993 {
00994 int gn;
00995
00996 for (gn = 0; gn < MAX_GROUP; gn++)
00997 {
00998 if (group_table[gn].name == NULL)
00999 break;
01000 if (LOWER (name[0]) == LOWER (group_table[gn].name[0])
01001 && !str_prefix (name, group_table[gn].name))
01002 return gn;
01003 }
01004
01005 return -1;
01006 }
01007
01008
01009 void gn_add (CHAR_DATA * ch, int gn)
01010 {
01011 int i;
01012
01013 ch->pcdata->group_known[gn] = TRUE;
01014 for (i = 0; i < MAX_IN_GROUP; i++)
01015 {
01016 if (group_table[gn].spells[i] == NULL)
01017 break;
01018 group_add (ch, group_table[gn].spells[i], FALSE);
01019 }
01020 }
01021
01022
01023 void gn_remove (CHAR_DATA * ch, int gn)
01024 {
01025 int i;
01026
01027 ch->pcdata->group_known[gn] = FALSE;
01028
01029 for (i = 0; i < MAX_IN_GROUP; i++)
01030 {
01031 if (group_table[gn].spells[i] == NULL)
01032 break;
01033 group_remove (ch, group_table[gn].spells[i]);
01034 }
01035 }
01036
01037
01038 void group_add (CHAR_DATA * ch, const char *name, bool deduct)
01039 {
01040 int sn, gn;
01041
01042 if (IS_NPC (ch))
01043 return;
01044
01045 sn = skill_lookup (name);
01046
01047 if (sn != -1)
01048 {
01049 if (ch->pcdata->learned[sn] == 0)
01050 {
01051 ch->pcdata->learned[sn] = 1;
01052 if (deduct)
01053 ch->pcdata->points += skill_table[sn].rating[ch->class];
01054 }
01055 return;
01056 }
01057
01058
01059
01060 gn = group_lookup (name);
01061
01062 if (gn != -1)
01063 {
01064 if (ch->pcdata->group_known[gn] == FALSE)
01065 {
01066 ch->pcdata->group_known[gn] = TRUE;
01067 if (deduct)
01068 ch->pcdata->points += group_table[gn].rating[ch->class];
01069 }
01070 gn_add (ch, gn);
01071 }
01072 }
01073
01074
01075
01076 void group_remove (CHAR_DATA * ch, const char *name)
01077 {
01078 int sn, gn;
01079
01080 sn = skill_lookup (name);
01081
01082 if (sn != -1)
01083 {
01084 ch->pcdata->learned[sn] = 0;
01085 return;
01086 }
01087
01088
01089
01090 gn = group_lookup (name);
01091
01092 if (gn != -1 && ch->pcdata->group_known[gn] == TRUE)
01093 {
01094 ch->pcdata->group_known[gn] = FALSE;
01095 gn_remove (ch, gn);
01096 }
01097 }