1 | /* |
1 | /* |
2 | * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Crossfire TRT is free software; you can redistribute it and/or modify it |
8 | * Deliantra is free software: you can redistribute it and/or modify |
9 | * under the terms of the GNU General Public License as published by the Free |
9 | * it under the terms of the GNU General Public License as published by |
10 | * Software Foundation; either version 2 of the License, or (at your option) |
10 | * the Free Software Foundation, either version 3 of the License, or |
11 | * any later version. |
11 | * (at your option) any later version. |
12 | * |
12 | * |
13 | * This program is distributed in the hope that it will be useful, but |
13 | * This program is distributed in the hope that it will be useful, |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * for more details. |
16 | * GNU General Public License for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the GNU General Public License along |
18 | * You should have received a copy of the GNU General Public License |
19 | * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51 |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
|
21 | * |
20 | * |
22 | * The authors can be reached via e-mail to <crossfire@schmorp.de> |
21 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | */ |
22 | */ |
24 | |
23 | |
25 | /* Created July 95 to separate skill utilities from actual skills -b.t. */ |
24 | /* Created July 95 to separate skill utilities from actual skills -b.t. */ |
26 | |
25 | |
27 | /* Reconfigured skills code to allow linking of skills to experience |
26 | /* Reconfigured skills code to allow linking of skills to experience |
… | |
… | |
292 | new_draw_info (NDI_UNIQUE, 0, op, "You come to earth."); |
291 | new_draw_info (NDI_UNIQUE, 0, op, "You come to earth."); |
293 | } |
292 | } |
294 | else |
293 | else |
295 | { |
294 | { |
296 | SET_FLAG (skill, FLAG_APPLIED); |
295 | SET_FLAG (skill, FLAG_APPLIED); |
297 | new_draw_info (NDI_UNIQUE, 0, op, "You rise into the air!."); |
296 | new_draw_info (NDI_UNIQUE, 0, op, "You rise into the air!"); |
298 | } |
297 | } |
299 | |
298 | |
300 | op->update_stats (); |
299 | op->update_stats (); |
301 | success = 1; |
300 | success = 1; |
302 | break; |
301 | break; |
… | |
… | |
511 | * If an object is not alive and magical we set the base exp higher to |
510 | * If an object is not alive and magical we set the base exp higher to |
512 | * help out exp awards for skill_ident skills. Also, if |
511 | * help out exp awards for skill_ident skills. Also, if |
513 | * an item is type RUNE, we give out exp based on stats.Cha |
512 | * an item is type RUNE, we give out exp based on stats.Cha |
514 | * and level (this was the old system) -b.t. |
513 | * and level (this was the old system) -b.t. |
515 | */ |
514 | */ |
516 | |
|
|
517 | if (!op) |
515 | if (!op) |
518 | { /* no item/creature */ |
516 | { /* no item/creature */ |
519 | op_lvl = who->map->difficulty < 1 ? 1 : who->map->difficulty; |
517 | op_lvl = max (1, who->map->difficulty); |
520 | op_exp = 0; |
518 | op_exp = 0; |
521 | } |
519 | } |
522 | else if (op->type == RUNE || op->type == TRAP) |
520 | else if (op->type == RUNE || op->type == TRAP) |
523 | { /* all traps. If stats.Cha > 1 we use that |
521 | { /* all traps. If stats.Cha > 1 we use that |
524 | * for the amount of experience */ |
522 | * for the amount of experience */ |
… | |
… | |
528 | else |
526 | else |
529 | { /* all other items/living creatures */ |
527 | { /* all other items/living creatures */ |
530 | op_exp = op->stats.exp; |
528 | op_exp = op->stats.exp; |
531 | op_lvl = op->level; |
529 | op_lvl = op->level; |
532 | if (!QUERY_FLAG (op, FLAG_ALIVE)) |
530 | if (!QUERY_FLAG (op, FLAG_ALIVE)) |
533 | { /* for ident/make items */ |
531 | op_lvl += 5 * abs (op->magic); /* for ident/make items */ |
534 | op_lvl += 5 * abs (op->magic); |
|
|
535 | } |
|
|
536 | } |
532 | } |
537 | |
533 | |
538 | if (op_lvl < 1) |
534 | if (op_lvl < 1) |
539 | op_lvl = 1; |
535 | op_lvl = 1; |
540 | |
536 | |
… | |
… | |
567 | } |
563 | } |
568 | } |
564 | } |
569 | else |
565 | else |
570 | { |
566 | { |
571 | /* Don't divide by zero here! */ |
567 | /* Don't divide by zero here! */ |
572 | lvl_mult = (float) op_lvl / (float) (skill->level ? skill->level : 1); |
568 | lvl_mult = (float) op_lvl / (float) max (1, skill->level); |
573 | } |
569 | } |
574 | } |
570 | } |
575 | |
571 | |
576 | /* assemble the exp total, and return value */ |
572 | /* assemble the exp total, and return value */ |
577 | |
573 | |
… | |
… | |
657 | * Note this function is a bit more complicated becauase we |
653 | * Note this function is a bit more complicated becauase we |
658 | * we want ot sort the skills before printing them. If we |
654 | * we want ot sort the skills before printing them. If we |
659 | * just dumped this as we found it, this would be a bit |
655 | * just dumped this as we found it, this would be a bit |
660 | * simpler. |
656 | * simpler. |
661 | */ |
657 | */ |
662 | |
658 | //TODO: egad, do it in perl, do not suffer from the big buffer on stack, make it one single drawinfo. |
663 | void |
659 | void |
664 | show_skills (object *op, const char *search) |
660 | show_skills (object *op, const char *search) |
665 | { |
661 | { |
666 | object *tmp = NULL; |
662 | object *tmp = NULL; |
667 | char buf[MAX_BUF]; |
663 | char buf[MAX_BUF]; |
… | |
… | |
669 | int i, num_skills_found = 0; |
665 | int i, num_skills_found = 0; |
670 | static const char *const periods = "........................................"; |
666 | static const char *const periods = "........................................"; |
671 | |
667 | |
672 | /* Need to have a pointer and use strdup for qsort to work properly */ |
668 | /* Need to have a pointer and use strdup for qsort to work properly */ |
673 | char skills[NUM_SKILLS][MAX_BUF]; |
669 | char skills[NUM_SKILLS][MAX_BUF]; |
674 | |
|
|
675 | |
670 | |
676 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
671 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
677 | { |
672 | { |
678 | if (tmp->type == SKILL) |
673 | if (tmp->type == SKILL) |
679 | { |
674 | { |
… | |
… | |
682 | /* Basically want to fill this out to 40 spaces with periods */ |
677 | /* Basically want to fill this out to 40 spaces with periods */ |
683 | sprintf (buf, "%s%s", &tmp->name, periods); |
678 | sprintf (buf, "%s%s", &tmp->name, periods); |
684 | buf[40] = 0; |
679 | buf[40] = 0; |
685 | |
680 | |
686 | if (settings.permanent_exp_ratio) |
681 | if (settings.permanent_exp_ratio) |
687 | { |
|
|
688 | sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%" PRId64 "/%" PRId64 "/%d%%)", |
682 | sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%" PRId64 "/%" PRId64 "/%d%%)", |
689 | buf, tmp->level, tmp->stats.exp, |
683 | buf, tmp->level, tmp->stats.exp, |
690 | level_exp (tmp->level + 1, op->expmul), clipped_percent (tmp->perm_exp, tmp->stats.exp)); |
684 | level_exp (tmp->level + 1, op->expmul), clipped_percent (tmp->perm_exp, tmp->stats.exp)); |
691 | } |
|
|
692 | else |
685 | else |
693 | { |
|
|
694 | sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%" PRId64 "/%" PRId64 ")", |
686 | sprintf (skills[num_skills_found++], "%slvl:%3d (xp:%" PRId64 "/%" PRId64 ")", |
695 | buf, tmp->level, tmp->stats.exp, level_exp (tmp->level + 1, op->expmul)); |
687 | buf, tmp->level, tmp->stats.exp, level_exp (tmp->level + 1, op->expmul)); |
696 | } |
688 | |
697 | /* I don't know why some characters get a bunch of skills, but |
689 | /* I don't know why some characters get a bunch of skills, but |
698 | * it sometimes happens (maybe a leftover from bugier earlier code |
690 | * it sometimes happens (maybe a leftover from bugier earlier code |
699 | * and those character are still about). In any case, lets handle |
691 | * and those character are still about). In any case, lets handle |
700 | * it so it doesn't crash the server - otherwise, one character may |
692 | * it so it doesn't crash the server - otherwise, one character may |
701 | * crash the server numerous times. |
693 | * crash the server numerous times. |
… | |
… | |
707 | break; |
699 | break; |
708 | } |
700 | } |
709 | } |
701 | } |
710 | } |
702 | } |
711 | |
703 | |
712 | clear_win_info (op); |
|
|
713 | new_draw_info (NDI_UNIQUE, 0, op, "Player skills:"); |
704 | new_draw_info (NDI_UNIQUE, 0, op, "Player skills:"); |
714 | if (num_skills_found > 1) |
705 | if (num_skills_found > 1) |
715 | qsort (skills, num_skills_found, MAX_BUF, (int (*)(const void *, const void *)) std::strcmp); |
706 | qsort (skills, num_skills_found, MAX_BUF, (int (*)(const void *, const void *)) std::strcmp); |
716 | |
707 | |
717 | for (i = 0; i < num_skills_found; i++) |
708 | for (i = 0; i < num_skills_found; i++) |