ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/skills.C
(Generate patch)

Comparing deliantra/server/server/skills.C (file contents):
Revision 1.29 by root, Mon May 7 03:05:58 2007 UTC vs.
Revision 1.37 by root, Mon Jun 4 13:04:00 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game for X-windows 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2003 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2003,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software; you can redistribute it and/or modify it
9 * it under the terms of the GNU General Public License as published by 9 * under the terms of the GNU General Public License as published by the Free
10 * the Free Software Foundation; either version 2 of the License, or 10 * Software Foundation; either version 2 of the License, or (at your option)
11 * (at your option) any later version. 11 * any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful, but
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * GNU General Public License for more details. 16 * for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License along
19 * along with this program; if not, write to the Free Software 19 * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * 21 *
22 * The authors can be reached via e-mail to <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
40 return -1; 40 return -1;
41 41
42 /* Only prohibit stealing if the player does not have a free 42 /* Only prohibit stealing if the player does not have a free
43 * hand available and in fact does have hands. 43 * hand available and in fact does have hands.
44 */ 44 */
45 if (op->type == PLAYER && op->slot[BODY_ARMS].used <= 0 && op->slot[BODY_ARMS].info) 45 if (op->type == PLAYER && op->slot[body_arm].used <= 0 && op->slot[body_arm].info)
46 { 46 {
47 new_draw_info (NDI_UNIQUE, 0, op, "But you have no free hands to steal with!"); 47 new_draw_info (NDI_UNIQUE, 0, op, "But you have no free hands to steal with!");
48 return -1; 48 return -1;
49 } 49 }
50 50
93 * or not. 93 * or not.
94 * op is the target (person being pilfered) 94 * op is the target (person being pilfered)
95 * who is the person doing the stealing. 95 * who is the person doing the stealing.
96 * skill is the skill object (stealing). 96 * skill is the skill object (stealing).
97 */ 97 */
98
99static int 98static int
100attempt_steal (object *op, object *who, object *skill) 99attempt_steal (object *op, object *who, object *skill)
101{ 100{
102 object *success = NULL, *tmp = NULL, *next; 101 object *success = NULL, *tmp = NULL, *next;
103 int roll = 0, chance = 0, stats_value; 102 int roll = 0, chance = 0, stats_value;
121 else /* help npc to detect thief next time by raising its wisdom */ 120 else /* help npc to detect thief next time by raising its wisdom */
122 op->stats.Wis += (op->stats.Int / 5) + 1; 121 op->stats.Wis += (op->stats.Int / 5) + 1;
123 if (op->stats.Wis > MAX_STAT) 122 if (op->stats.Wis > MAX_STAT)
124 op->stats.Wis = MAX_STAT; 123 op->stats.Wis = MAX_STAT;
125 } 124 }
125
126 if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ)) 126 if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ))
127 { 127 {
128 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n"); 128 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n");
129 return 0; 129 return 0;
130 } 130 }
131#ifdef PROHIBIT_PLAYERKILL 131
132 // only allow stealing between hostile players (TODO: probably should change)
132 if (op->type == PLAYER && who->type == PLAYER && (who->contr->peaceful || op->contr->peaceful)) 133 if (op->type == PLAYER && who->type == PLAYER && (who->contr->peaceful || op->contr->peaceful))
133 { 134 {
134 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); 135 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n");
135 return 0; 136 return 0;
136 } 137 }
137#else
138 if (op->type == PLAYER && who->type == PLAYER && settings.no_player_stealing)
139 {
140 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n");
141 return 0;
142 }
143#endif
144
145 138
146 /* Ok then, go thru their inventory, stealing */ 139 /* Ok then, go thru their inventory, stealing */
147 for (tmp = op->inv; tmp != NULL; tmp = next) 140 for (tmp = op->inv; tmp; tmp = next)
148 { 141 {
149 next = tmp->below; 142 next = tmp->below;
150 143
151 /* you can't steal worn items, starting items, wiz stuff, 144 /* you can't steal worn items, starting items, wiz stuff,
152 * innate abilities, or items w/o a type. Generally 145 * innate abilities, or items w/o a type. Generally
156 * future possible problems. -b.t. 149 * future possible problems. -b.t.
157 * Flesh items generated w/ fix_flesh_item should have FLAG_NO_STEAL 150 * Flesh items generated w/ fix_flesh_item should have FLAG_NO_STEAL
158 * already -b.t. 151 * already -b.t.
159 */ 152 */
160 153
161 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED) 154 if (QUERY_FLAG (tmp, FLAG_APPLIED)
162 || !(tmp->type) 155 || !tmp->type
163 || tmp->type == SPELL 156 || tmp->type == SPELL
164 || QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_STEAL) || tmp->invisible) 157 || QUERY_FLAG (tmp, FLAG_STARTEQUIP)
158 || QUERY_FLAG (tmp, FLAG_NO_STEAL)
159 || tmp->invisible)
165 continue; 160 continue;
166 161
167 /* Okay, try stealing this item. Dependent on dexterity of thief, 162 /* Okay, try stealing this item. Dependent on dexterity of thief,
168 * skill level, see the adj_stealroll fctn for more detail. 163 * skill level, see the adj_stealroll fctn for more detail.
169 */ 164 */
414 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to pick the lock."); 409 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to pick the lock.");
415 return 0; 410 return 0;
416 } 411 }
417} 412}
418 413
419
420/* HIDE CODE. The user becomes undetectable (not just 'invisible') for 414/* HIDE CODE. The user becomes undetectable (not just 'invisible') for
421 * a short while (success and duration dependant on player SK_level, 415 * a short while (success and duration dependant on player SK_level,
422 * dexterity, charisma, and map difficulty). 416 * dexterity, charisma, and map difficulty).
423 * Players have a good chance of becoming 'unhidden' if they move 417 * Players have a good chance of becoming 'unhidden' if they move
424 * and like invisiblity will be come visible if they attack 418 * and like invisiblity will be come visible if they attack
425 * Implemented by b.t. (thomas@astro.psu.edu) 419 * Implemented by b.t. (thomas@astro.psu.edu)
426 * July 7, 1995 - made hiding possible for monsters. -b.t. 420 * July 7, 1995 - made hiding possible for monsters. -b.t.
427 */ 421 */
428
429static int 422static int
430attempt_hide (object *op, object *skill) 423attempt_hide (object *op, object *skill)
431{ 424{
432 int number, difficulty = op->map->difficulty; 425 int number, difficulty = op->map->difficulty;
433 int terrain = hideability (op); 426 int terrain = hideability (op);
436 return 0; 429 return 0;
437 430
438 /* Hiding success and duration dependant on skill level, 431 /* Hiding success and duration dependant on skill level,
439 * op->stats.Dex, map difficulty and terrain. 432 * op->stats.Dex, map difficulty and terrain.
440 */ 433 */
441
442 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2; 434 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2;
435
443 if (!stand_near_hostile (op) && (number < (op->stats.Dex + skill->level + terrain - difficulty))) 436 if (!stand_near_hostile (op) && (number < (op->stats.Dex + skill->level + terrain - difficulty)))
444 { 437 {
445 op->invisible += 100; /* set the level of 'hiddeness' */ 438 op->invisible += 100; /* set the level of 'hiddeness' */
439
446 if (op->type == PLAYER) 440 if (op->type == PLAYER)
447 op->contr->tmp_invis = 1; 441 op->contr->tmp_invis = 1;
442
448 op->hide = 1; 443 op->hide = 1;
449 return 1; 444 return 1;
450 } 445 }
446
451 return 0; 447 return 0;
452} 448}
453 449
454/* patched this to take terrain into consideration */ 450/* patched this to take terrain into consideration */
455int 451int
456hide (object *op, object *skill) 452hide (object *op, object *skill)
457{ 453{
458
459 /* the preliminaries -- Can we really hide now? */ 454 /* the preliminaries -- Can we really hide now? */
460 /* this keeps monsters from using invisibilty spells and hiding */ 455 /* this keeps monsters from using invisibilty spells and hiding */
461 456
462 if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) 457 if (QUERY_FLAG (op, FLAG_MAKE_INVIS))
463 { 458 {
468 { 463 {
469 new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!"); 464 new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!");
470 make_visible (op); 465 make_visible (op);
471 } 466 }
472 467
473 if (op->invisible > (50 * skill->level)) 468 if (op->invisible > 50 * skill->level)
474 { 469 {
475 new_draw_info (NDI_UNIQUE, 0, op, "You are as hidden as you can get."); 470 new_draw_info (NDI_UNIQUE, 0, op, "You are as hidden as you can get.");
476 return 0; 471 return 0;
477 } 472 }
478 473
480 { 475 {
481 new_draw_info (NDI_UNIQUE, 0, op, "You hide in the shadows."); 476 new_draw_info (NDI_UNIQUE, 0, op, "You hide in the shadows.");
482 update_object (op, UP_OBJ_FACE); 477 update_object (op, UP_OBJ_FACE);
483 return calc_skill_exp (op, NULL, skill); 478 return calc_skill_exp (op, NULL, skill);
484 } 479 }
480
485 new_draw_info (NDI_UNIQUE, 0, op, "You fail to conceal yourself."); 481 new_draw_info (NDI_UNIQUE, 0, op, "You fail to conceal yourself.");
486 return 0; 482 return 0;
487} 483}
488
489 484
490/* stop_jump() - End of jump. Clear flags, restore the map, and 485/* stop_jump() - End of jump. Clear flags, restore the map, and
491 * freeze the jumper a while to simulate the exhaustion 486 * freeze the jumper a while to simulate the exhaustion
492 * of jumping. 487 * of jumping.
493 */ 488 */
813 * -b.t. (thomas@astro.psu.edu) 808 * -b.t. (thomas@astro.psu.edu)
814 */ 809 */
815int 810int
816use_oratory (object *pl, int dir, object *skill) 811use_oratory (object *pl, int dir, object *skill)
817{ 812{
818 sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir];
819 int mflags, chance;
820 object *tmp;
821 maptile *m;
822
823 if (pl->type != PLAYER) 813 if (pl->type != PLAYER)
824 return 0; /* only players use this skill */ 814 return 0; /* only players use this skill */
815
816 sint16 x = pl->x + freearr_x[dir],
817 y = pl->y + freearr_y[dir];
825 m = pl->map; 818 maptile *m = pl->map;
819
826 mflags = get_map_flags (m, &m, x, y, &x, &y); 820 int mflags = get_map_flags (m, &m, x, y, &x, &y);
827 if (mflags & P_OUT_OF_MAP) 821 if (mflags & P_OUT_OF_MAP)
828 return 0; 822 return 0;
829 823
830 /* Save some processing - we have the flag already anyways 824 /* Save some processing - we have the flag already anyways
831 */ 825 */
833 { 827 {
834 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to."); 828 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to.");
835 return 0; 829 return 0;
836 } 830 }
837 831
832 object *tmp;
838 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) 833 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
839 { 834 {
840 /* can't persuade players - return because there is nothing else 835 /* can't persuade players - return because there is nothing else
841 * on that space to charm. Same for multi space monsters and 836 * on that space to charm. Same for multi space monsters and
842 * special monsters - we don't allow them to be charmed, and there 837 * special monsters - we don't allow them to be charmed, and there
843 * is no reason to do further processing since they should be the 838 * is no reason to do further processing since they should be the
844 * only monster on the space. 839 * only monster on the space.
845 */ 840 */
846 if (tmp->type == PLAYER) 841 if (tmp->type == PLAYER
847 return 0; 842 || tmp->more || tmp->head_ () != tmp
848 if (tmp->more || tmp->head) 843 || tmp->msg)
849 return 0;
850 if (tmp->msg)
851 return 0; 844 return 0;
852 845
853 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 846 if (QUERY_FLAG (tmp, FLAG_MONSTER))
854 break; 847 break;
855 } 848 }
870 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp)); 863 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
871 return 0; 864 return 0;
872 } 865 }
873 866
874 /* it's already allied! */ 867 /* it's already allied! */
875 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE)) 868 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE)
876 { 869 {
877 if (tmp->owner == pl) 870 if (tmp->owner == pl)
878 { 871 {
879 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n"); 872 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n");
880 return 0; 873 return 0;
883 { 876 {
884 /* you steal the follower. Perhaps we should really look at the 877 /* you steal the follower. Perhaps we should really look at the
885 * level of the owner above? 878 * level of the owner above?
886 */ 879 */
887 tmp->set_owner (pl); 880 tmp->set_owner (pl);
881 tmp->skill = skill->skill;
882
888 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp)); 883 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp));
889 /* Abuse fix - don't give exp since this can otherwise 884 /* Abuse fix - don't give exp since this can otherwise
890 * be used by a couple players to gets lots of exp. 885 * be used by a couple players to gets lots of exp.
891 */ 886 */
892 return 0; 887 return 0;
896 /* In this case, you can't steal it from the other player */ 891 /* In this case, you can't steal it from the other player */
897 return 0; 892 return 0;
898 } 893 }
899 } /* Creature was already a pet of someone */ 894 } /* Creature was already a pet of someone */
900 895
901 chance = skill->level * 2 + (pl->stats.Cha - 2 * tmp->stats.Int) / 2; 896 int level = skill->level + (pl->stats.Cha - tmp->stats.Int) / 2;
902 897
903 /* Ok, got a 'sucker' lets try to make them a follower */ 898 /* Ok, got a 'sucker' lets try to make them a follower */
904 if (chance > 0 && tmp->level < (random_roll (0, chance - 1, pl, PREFER_HIGH) - 1)) 899 if (level > 0 && tmp->level < (random_roll (0, level - 1, pl, PREFER_HIGH) - 1))
905 { 900 {
906 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp)); 901 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp));
907 902
908 tmp->set_owner (pl); 903 tmp->set_owner (pl);
904 tmp->skill = skill->skill;
909 tmp->stats.exp = 0; 905 tmp->stats.exp = 0;
910 add_friendly_object (tmp); 906 add_friendly_object (tmp);
911 tmp->attack_movement = PETMOVE; 907 tmp->attack_movement = PETMOVE;
912 return calc_skill_exp (pl, tmp, skill); 908 return calc_skill_exp (pl, tmp, skill);
913 } 909 }
914
915 /* Charm failed. Creature may be angry now */ 910 /* Charm failed. Creature may be angry now */
916 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW)) 911 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW))
917 { 912 {
918 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your speech angers the %s!\n", query_name (tmp)); 913 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your speech angers the %s!\n", query_name (tmp));
919 if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) 914 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
936 * successfully pacified the creature gets Int=1. Thus, a player 931 * successfully pacified the creature gets Int=1. Thus, a player
937 * may only pacify a creature once. 932 * may only pacify a creature once.
938 * BTW, I appologize for the naming of the skill, I couldnt think 933 * BTW, I appologize for the naming of the skill, I couldnt think
939 * of anything better! -b.t. 934 * of anything better! -b.t.
940 */ 935 */
941
942int 936int
943singing (object *pl, int dir, object *skill) 937singing (object *pl, int dir, object *skill)
944{ 938{
945 int i, exp = 0, chance, mflags; 939 int i, exp = 0;
946 object *tmp; 940 object *tmp;
947 maptile *m; 941 maptile *m;
948 sint16 x, y; 942 sint16 x, y;
949 943
950 if (pl->type != PLAYER) 944 if (pl->type != PLAYER)
955 { 949 {
956 x = pl->x + freearr_x[i]; 950 x = pl->x + freearr_x[i];
957 y = pl->y + freearr_y[i]; 951 y = pl->y + freearr_y[i];
958 m = pl->map; 952 m = pl->map;
959 953
960 mflags = get_map_flags (m, &m, x, y, &x, &y); 954 int mflags = get_map_flags (m, &m, x, y, &x, &y);
961 if (mflags & P_OUT_OF_MAP) 955 if (mflags & P_OUT_OF_MAP)
962 continue; 956 continue;
963 if (!(mflags & P_IS_ALIVE)) 957 if (!(mflags & P_IS_ALIVE))
964 continue; 958 continue;
965 959
984 978
985 /* stealing isn't really related (although, maybe it should 979 /* stealing isn't really related (although, maybe it should
986 * be). This is mainly to prevent singing to the same monster 980 * be). This is mainly to prevent singing to the same monster
987 * over and over again and getting exp for it. 981 * over and over again and getting exp for it.
988 */ 982 */
989 chance = skill->level * 2 + (pl->stats.Cha - 5 - tmp->stats.Int) / 2; 983 int level = skill->level + (pl->stats.Cha - 5 - tmp->stats.Int) / 2;
984
990 if (chance && tmp->level * 2 < random_roll (0, chance - 1, pl, PREFER_HIGH)) 985 if (level && tmp->level < random_roll (0, level - 1, pl, PREFER_HIGH))
991 { 986 {
992 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 987 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
993 new_draw_info_format (NDI_UNIQUE, 0, pl, "You calm down the %s\n", query_name (tmp)); 988 new_draw_info_format (NDI_UNIQUE, 0, pl, "You calm down the %s\n", query_name (tmp));
994 /* Give exp only if they are not aware */ 989 /* Give exp only if they are not aware */
990
995 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL)) 991 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL))
996 exp += calc_skill_exp (pl, tmp, skill); 992 exp += calc_skill_exp (pl, tmp, skill);
993
997 SET_FLAG (tmp, FLAG_NO_STEAL); 994 SET_FLAG (tmp, FLAG_NO_STEAL);
998 } 995 }
999 else 996 else
1000 { 997 {
1001 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp)); 998 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
1198 return; 1195 return;
1199 } 1196 }
1200 else 1197 else
1201 { 1198 {
1202 for (tmp = pl->inv; tmp; tmp = tmp->below) 1199 for (tmp = pl->inv; tmp; tmp = tmp->below)
1203 if (((tmp->type == ARMOUR && skill->level < 12) 1200 if (((tmp->type == ARMOUR && skill->level < 12)
1204 || (tmp->type == HELMET && skill->level < 10) 1201 || (tmp->type == HELMET && skill->level < 10)
1205 || (tmp->type == SHIELD && skill->level < 6) 1202 || (tmp->type == SHIELD && skill->level < 6)
1206 || (tmp->type == BOOTS && skill->level < 4) || (tmp->type == GLOVES && skill->level < 2)) && QUERY_FLAG (tmp, FLAG_APPLIED)) 1203 || (tmp->type == BOOTS && skill->level < 4)
1204 || (tmp->type == GLOVES && skill->level < 2))
1205 && QUERY_FLAG (tmp, FLAG_APPLIED))
1207 { 1206 {
1208 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n"); 1207 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n");
1209 return; 1208 return;
1210 } 1209 }
1211 } 1210 }
1388 insert_ob_in_ob (tmp, newscroll); 1387 insert_ob_in_ob (tmp, newscroll);
1389 1388
1390 /* Same code as from treasure.c - so they can better merge. 1389 /* Same code as from treasure.c - so they can better merge.
1391 * if players want to sell them, so be it. 1390 * if players want to sell them, so be it.
1392 */ 1391 */
1393 newscroll->value = newscroll->arch->clone.value * newscroll->inv->value * (newscroll->level + 50) / (newscroll->inv->level + 50); 1392 newscroll->value = newscroll->arch->value * newscroll->inv->value * (newscroll->level + 50) / (newscroll->inv->level + 50);
1394 newscroll->stats.exp = newscroll->value / 5; 1393 newscroll->stats.exp = newscroll->value / 5;
1395 1394
1396 /* wait until finished manipulating the scroll before inserting it */ 1395 /* wait until finished manipulating the scroll before inserting it */
1397 if (newscroll == scroll) 1396 if (newscroll == scroll)
1398 { 1397 {
1455 } 1454 }
1456 1455
1457 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY); 1456 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY);
1458 1457
1459 /* Need to be able to read before we can write! */ 1458 /* Need to be able to read before we can write! */
1460 if (!find_skill_by_name (pl, skat->clone.skill)) 1459 if (!find_skill_by_name (pl, skat->skill))
1461 { 1460 {
1462 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!"); 1461 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!");
1463 return 0; 1462 return 0;
1464 } 1463 }
1465 1464
1581 1580
1582/* make_throw_ob() We construct the 'carrier' object in 1581/* make_throw_ob() We construct the 'carrier' object in
1583 * which we will insert the object that is being thrown. 1582 * which we will insert the object that is being thrown.
1584 * This combination becomes the 'thrown object'. -b.t. 1583 * This combination becomes the 'thrown object'. -b.t.
1585 */ 1584 */
1586
1587static object * 1585static object *
1588make_throw_ob (object *orig) 1586make_throw_ob (object *orig)
1589{ 1587{
1590 if (!orig) 1588 if (!orig)
1591 return NULL; 1589 return NULL;
1604 toss_item->stats.dam = 0; /* default damage */ 1602 toss_item->stats.dam = 0; /* default damage */
1605 insert_ob_in_ob (orig, toss_item); 1603 insert_ob_in_ob (orig, toss_item);
1606 return toss_item; 1604 return toss_item;
1607} 1605}
1608 1606
1609
1610/* do_throw() - op throws any object toss_item. This code 1607/* do_throw() - op throws any object toss_item. This code
1611 * was borrowed from fire_bow. 1608 * was borrowed from fire_bow.
1612 * Returns 1 if skill was successfully used, 0 if not 1609 * Returns 1 if skill was successfully used, 0 if not
1613 */ 1610 */
1614
1615static int 1611static int
1616do_throw (object *op, object *part, object *toss_item, int dir, object *skill) 1612do_throw (object *op, object *part, object *toss_item, int dir, object *skill)
1617{ 1613{
1618 object *throw_ob = toss_item, *left = NULL; 1614 object *throw_ob = toss_item, *left = NULL;
1619 int eff_str = 0, maxc, str = op->stats.Str, dam = 0; 1615 int eff_str = 0, maxc, str = op->stats.Str, dam = 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines