1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
|
|
4 | * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
8 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
12 | * option) any later version. |
12 | * |
13 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * GNU General Public License for more details. |
17 | * |
18 | * |
18 | * You should have received a copy of the Affero GNU General Public License |
19 | * You should have received a copy of the Affero GNU General Public License |
19 | * and the GNU General Public License along with this program. If not, see |
20 | * and the GNU General Public License along with this program. If not, see |
20 | * <http://www.gnu.org/licenses/>. |
21 | * <http://www.gnu.org/licenses/>. |
21 | * |
22 | * |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | */ |
24 | */ |
24 | |
25 | |
25 | /* Created July 95 to separate skill utilities from actual skills -b.t. */ |
26 | /* Created July 95 to separate skill utilities from actual skills -b.t. */ |
26 | |
27 | |
… | |
… | |
71 | void |
72 | void |
72 | add_skill_archetype (object *o) |
73 | add_skill_archetype (object *o) |
73 | { |
74 | { |
74 | assert (("skill name must equal skill skill", o->name == o->skill)); |
75 | assert (("skill name must equal skill skill", o->name == o->skill)); |
75 | |
76 | |
76 | for (vector<object_ptr>::iterator i = skillvec.begin (); i != skillvec.end (); ++i) |
77 | for (auto &&i = skillvec.begin (); i != skillvec.end (); ++i) |
77 | if ((*i)->name == o->name) |
78 | if ((*i)->name == o->name) |
78 | { |
79 | { |
79 | // replace existing entry |
80 | // replace existing entry |
80 | SKILL_INDEX (o) = i - skillvec.begin (); |
81 | SKILL_INDEX (o) = i - skillvec.begin (); |
81 | *i = o; |
82 | *i = o; |
… | |
… | |
88 | skillvec.push_back (o); |
89 | skillvec.push_back (o); |
89 | } |
90 | } |
90 | |
91 | |
91 | /* This function goes through the player inventory and sets |
92 | /* This function goes through the player inventory and sets |
92 | * up the last_skills[] array in the player object. |
93 | * up the last_skills[] array in the player object. |
93 | * the last_skills[] is used to more quickly lookup skills - |
94 | * the last_skills[] is used to more quickly lookup skills - |
94 | * mostly used for sending exp. |
95 | * mostly used for sending exp. |
95 | */ |
96 | */ |
96 | void |
97 | void |
97 | player::link_skills () |
98 | player::link_skills () |
98 | { |
99 | { |
… | |
… | |
195 | * one that accumulates exp, has the level, etc). |
196 | * one that accumulates exp, has the level, etc). |
196 | * |
197 | * |
197 | * It is presumed that the player will be needing to actually |
198 | * It is presumed that the player will be needing to actually |
198 | * use the skill, so thus if use of the skill requires a skill |
199 | * use the skill, so thus if use of the skill requires a skill |
199 | * tool, this code will equip it. |
200 | * tool, this code will equip it. |
200 | * |
201 | * |
201 | * This code is basically the same as find_skill_by_name() above, |
202 | * This code is basically the same as find_skill_by_name() above, |
202 | * but instead a skill name, we search by matching number. |
203 | * but instead a skill name, we search by matching number. |
203 | * this replaces find_skill. |
204 | * this replaces find_skill. |
204 | * |
205 | * |
205 | * MUST NOT BE USED IN NEW CODE! (schmorp) |
206 | * MUST NOT BE USED IN NEW CODE! (schmorp) |
… | |
… | |
227 | skill->flag [FLAG_CAN_USE_SKILL] = true; |
228 | skill->flag [FLAG_CAN_USE_SKILL] = true; |
228 | |
229 | |
229 | return skill; |
230 | return skill; |
230 | } |
231 | } |
231 | |
232 | |
232 | /* do_skill() - Main skills use function-similar in scope to cast_spell(). |
233 | /* do_skill() - Main skills use function-similar in scope to cast_spell(). |
233 | * We handle all requests for skill use outside of some combat here. |
234 | * We handle all requests for skill use outside of some combat here. |
234 | * We require a separate routine outside of fire() so as to allow monsters |
235 | * We require a separate routine outside of fire() so as to allow monsters |
235 | * to utilize skills. Returns 1 on use of skill, otherwise 0. |
236 | * to utilize skills. Returns 1 on use of skill, otherwise 0. |
236 | * This is changed (2002-11-30) from the old method that returned |
237 | * This is changed (2002-11-30) from the old method that returned |
237 | * exp - no caller needed that info, but it also prevented the callers |
238 | * exp - no caller needed that info, but it also prevented the callers |
238 | * from know if a skill was actually used, as many skills don't |
239 | * from know if a skill was actually used, as many skills don't |
239 | * give any exp for their direct use (eg, throwing). |
240 | * give any exp for their direct use (eg, throwing). |
… | |
… | |
373 | case SK_ALCHEMY: |
374 | case SK_ALCHEMY: |
374 | case SK_THAUMATURGY: |
375 | case SK_THAUMATURGY: |
375 | case SK_LITERACY: |
376 | case SK_LITERACY: |
376 | case SK_WOODSMAN: |
377 | case SK_WOODSMAN: |
377 | /* first, we try to find a cauldron, and do the alchemy thing. |
378 | /* first, we try to find a cauldron, and do the alchemy thing. |
378 | * failing that, we go and identify stuff. |
379 | * failing that, we go and identify stuff. |
379 | */ |
380 | */ |
380 | { |
381 | { |
381 | bool found_cauldron = false; |
382 | bool found_cauldron = false; |
382 | |
383 | |
383 | for (object *next, *tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = next) |
384 | for (object *next, *tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = next) |
… | |
… | |
453 | default: |
454 | default: |
454 | LOG (llevDebug, "%s attempted to use unknown skill: %d\n", query_name (op), op->chosen_skill->stats.sp); |
455 | LOG (llevDebug, "%s attempted to use unknown skill: %d\n", query_name (op), op->chosen_skill->stats.sp); |
455 | break; |
456 | break; |
456 | } |
457 | } |
457 | |
458 | |
458 | /* For players we now update the speed_left from using the skill. |
459 | /* For players we now update the speed_left from using the skill. |
459 | * Monsters have no skill use time because of the random nature in |
460 | * Monsters have no skill use time because of the random nature in |
460 | * which use_monster_skill is called already simulates this. |
461 | * which use_monster_skill is called already simulates this. |
461 | * If certain skills should take more/less time, that should be |
462 | * If certain skills should take more/less time, that should be |
462 | * in the code for the skill itself. |
463 | * in the code for the skill itself. |
463 | */ |
464 | */ |
464 | if (op->type == PLAYER) |
465 | if (op->type == PLAYER) |
… | |
… | |
514 | * non-living magic obj, runes and everything else. |
515 | * non-living magic obj, runes and everything else. |
515 | * |
516 | * |
516 | * If an object is not alive and magical we set the base exp higher to |
517 | * If an object is not alive and magical we set the base exp higher to |
517 | * help out exp awards for skill_ident skills. Also, if |
518 | * help out exp awards for skill_ident skills. Also, if |
518 | * an item is type RUNE, we give out exp based on stats.Cha |
519 | * an item is type RUNE, we give out exp based on stats.Cha |
519 | * and level (this was the old system) -b.t. |
520 | * and level (this was the old system) -b.t. |
520 | */ |
521 | */ |
521 | if (!op) |
522 | if (!op) |
522 | { /* no item/creature */ |
523 | { /* no item/creature */ |
523 | op_lvl = max (1, who->map->difficulty); |
524 | op_lvl = max (1, who->map->difficulty); |
524 | op_exp = 0; |
525 | op_exp = 0; |
… | |
… | |
588 | } |
589 | } |
589 | |
590 | |
590 | /* Learn skill. This inserts the requested skill in the player's |
591 | /* Learn skill. This inserts the requested skill in the player's |
591 | * inventory. The skill field of the scroll should have the |
592 | * inventory. The skill field of the scroll should have the |
592 | * exact name of the requested skill. |
593 | * exact name of the requested skill. |
593 | * This one actually teaches the player the skill as something |
594 | * This one actually teaches the player the skill as something |
594 | * they can equip. |
595 | * they can equip. |
595 | * Return 0 if the player knows the skill, 1 if the |
596 | * Return 0 if the player knows the skill, 1 if the |
596 | * player learns the skill, 2 otherwise. |
597 | * player learns the skill, 2 otherwise. |
597 | */ |
598 | */ |
598 | int |
599 | int |
… | |
… | |
661 | /* show_skills() - Meant to allow players to examine |
662 | /* show_skills() - Meant to allow players to examine |
662 | * their current skill list. |
663 | * their current skill list. |
663 | * This shows the amount of exp they have in the skills. |
664 | * This shows the amount of exp they have in the skills. |
664 | * we also include some other non skill related info (god, |
665 | * we also include some other non skill related info (god, |
665 | * max weapon improvments, item power). |
666 | * max weapon improvments, item power). |
666 | * Note this function is a bit more complicated becauase we |
667 | * Note this function is a bit more complicated because we |
667 | * we want ot sort the skills before printing them. If we |
668 | * we want to sort the skills before printing them. If we |
668 | * just dumped this as we found it, this would be a bit |
669 | * just dumped this as we found it, this would be a bit |
669 | * simpler. |
670 | * simpler. |
670 | */ |
671 | */ |
671 | void |
672 | void |
672 | show_skills (object *pl, const char *search) |
673 | show_skills (object *pl, const char *search) |
… | |
… | |
739 | << ".\n"; |
740 | << ".\n"; |
740 | |
741 | |
741 | pl->contr->infobox (MSG_CHANNEL ("skills"), msg); |
742 | pl->contr->infobox (MSG_CHANNEL ("skills"), msg); |
742 | } |
743 | } |
743 | |
744 | |
744 | /* use_skill() - similar to invoke command, it executes the skill in the |
745 | /* use_skill() - similar to invoke command, it executes the skill in the |
745 | * direction that the user is facing. Returns false if we are unable to |
746 | * direction that the user is facing. Returns false if we are unable to |
746 | * change to the requested skill, or were unable to use the skill properly. |
747 | * change to the requested skill, or were unable to use the skill properly. |
747 | * This is tricky because skills can have spaces. We basically roll |
748 | * This is tricky because skills can have spaces. We basically roll |
748 | * our own find_skill_by_name so we can try to do better string matching. |
749 | * our own find_skill_by_name so we can try to do better string matching. |
749 | */ |
750 | */ |
750 | int |
751 | int |
751 | use_skill (object *op, const char *string) |
752 | use_skill (object *op, const char *string) |
752 | { |
753 | { |
… | |
… | |
952 | int mflags; |
953 | int mflags; |
953 | |
954 | |
954 | if (!dir) |
955 | if (!dir) |
955 | dir = pl->facing; |
956 | dir = pl->facing; |
956 | |
957 | |
957 | tx = freearr_x[dir]; |
958 | tx = DIRX (dir); |
958 | ty = freearr_y[dir]; |
959 | ty = DIRY (dir); |
959 | |
960 | |
960 | /* If we don't yet have an opponent, find if one exists, and attack. |
961 | /* If we don't yet have an opponent, find if one exists, and attack. |
961 | * Legal opponents are the same as outlined in move_player_attack() |
962 | * Legal opponents are the same as outlined in move_player_attack() |
962 | */ |
963 | */ |
963 | if (!tmp) |
964 | if (!tmp) |
964 | { |
965 | { |
965 | m = pl->map; |
966 | m = pl->map; |
966 | tx = pl->x + freearr_x[dir]; |
967 | tx = pl->x + DIRX (dir); |
967 | ty = pl->y + freearr_y[dir]; |
968 | ty = pl->y + DIRY (dir); |
968 | |
969 | |
969 | mflags = get_map_flags (m, &m, tx, ty, &tx, &ty); |
970 | mflags = get_map_flags (m, &m, tx, ty, &tx, &ty); |
970 | if (mflags & P_OUT_OF_MAP) |
971 | if (mflags & P_OUT_OF_MAP) |
971 | return 0; |
972 | return 0; |
972 | |
973 | |