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.20 by root, Tue Dec 26 20:04:09 2006 UTC vs.
Revision 1.35 by root, Sat May 19 00:31:08 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2003 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2003 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 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
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 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>
22*/ 23 */
23 24
24#include <global.h> 25#include <global.h>
25#include <object.h> 26#include <object.h>
26#ifndef __CEXTRACT__
27# include <sproto.h> 27#include <sproto.h>
28#endif
29#include <living.h> 28#include <living.h>
30#include <skills.h> 29#include <skills.h>
31#include <spells.h> 30#include <spells.h>
32#include <book.h> 31#include <book.h>
33 32
41 return -1; 40 return -1;
42 41
43 /* Only prohibit stealing if the player does not have a free 42 /* Only prohibit stealing if the player does not have a free
44 * hand available and in fact does have hands. 43 * hand available and in fact does have hands.
45 */ 44 */
46 if (op->type == PLAYER && op->body_used[BODY_ARMS] <= 0 && op->body_info[BODY_ARMS]) 45 if (op->type == PLAYER && op->slot[body_arm].used <= 0 && op->slot[body_arm].info)
47 { 46 {
48 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!");
49 return -1; 48 return -1;
50 } 49 }
51 50
94 * or not. 93 * or not.
95 * op is the target (person being pilfered) 94 * op is the target (person being pilfered)
96 * who is the person doing the stealing. 95 * who is the person doing the stealing.
97 * skill is the skill object (stealing). 96 * skill is the skill object (stealing).
98 */ 97 */
99
100static int 98static int
101attempt_steal (object *op, object *who, object *skill) 99attempt_steal (object *op, object *who, object *skill)
102{ 100{
103 object *success = NULL, *tmp = NULL, *next; 101 object *success = NULL, *tmp = NULL, *next;
104 int roll = 0, chance = 0, stats_value; 102 int roll = 0, chance = 0, stats_value;
122 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 */
123 op->stats.Wis += (op->stats.Int / 5) + 1; 121 op->stats.Wis += (op->stats.Int / 5) + 1;
124 if (op->stats.Wis > MAX_STAT) 122 if (op->stats.Wis > MAX_STAT)
125 op->stats.Wis = MAX_STAT; 123 op->stats.Wis = MAX_STAT;
126 } 124 }
125
127 if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ)) 126 if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ))
128 { 127 {
129 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");
130 return 0; 129 return 0;
131 } 130 }
132#ifdef PROHIBIT_PLAYERKILL 131
132 // only allow stealing between hostile players (TODO: probably should change)
133 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))
134 { 134 {
135 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");
136 return 0; 136 return 0;
137 } 137 }
138#else
139 if (op->type == PLAYER && who->type == PLAYER && settings.no_player_stealing)
140 {
141 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n");
142 return 0;
143 }
144#endif
145
146 138
147 /* Ok then, go thru their inventory, stealing */ 139 /* Ok then, go thru their inventory, stealing */
148 for (tmp = op->inv; tmp != NULL; tmp = next) 140 for (tmp = op->inv; tmp; tmp = next)
149 { 141 {
150 next = tmp->below; 142 next = tmp->below;
151 143
152 /* you can't steal worn items, starting items, wiz stuff, 144 /* you can't steal worn items, starting items, wiz stuff,
153 * innate abilities, or items w/o a type. Generally 145 * innate abilities, or items w/o a type. Generally
157 * future possible problems. -b.t. 149 * future possible problems. -b.t.
158 * 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
159 * already -b.t. 151 * already -b.t.
160 */ 152 */
161 153
162 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED) 154 if (QUERY_FLAG (tmp, FLAG_APPLIED)
163 || !(tmp->type) 155 || !tmp->type
164 || tmp->type == SPELL 156 || tmp->type == SPELL
165 || 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)
166 continue; 160 continue;
167 161
168 /* Okay, try stealing this item. Dependent on dexterity of thief, 162 /* Okay, try stealing this item. Dependent on dexterity of thief,
169 * skill level, see the adj_stealroll fctn for more detail. 163 * skill level, see the adj_stealroll fctn for more detail.
170 */ 164 */
261 /* play_sound("stop! thief!"); kindofthing */ 255 /* play_sound("stop! thief!"); kindofthing */
262 } /* if you weren't 100% successful */ 256 } /* if you weren't 100% successful */
263 return success ? 1 : 0; 257 return success ? 1 : 0;
264} 258}
265 259
266
267int 260int
268steal (object *op, int dir, object *skill) 261steal (object *op, int dir, object *skill)
269{ 262{
270 object *tmp, *next; 263 object *tmp, *next;
271 sint16 x, y; 264 sint16 x, y;
415 { 408 {
416 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.");
417 return 0; 410 return 0;
418 } 411 }
419} 412}
420
421 413
422/* HIDE CODE. The user becomes undetectable (not just 'invisible') for 414/* HIDE CODE. The user becomes undetectable (not just 'invisible') for
423 * a short while (success and duration dependant on player SK_level, 415 * a short while (success and duration dependant on player SK_level,
424 * dexterity, charisma, and map difficulty). 416 * dexterity, charisma, and map difficulty).
425 * Players have a good chance of becoming 'unhidden' if they move 417 * Players have a good chance of becoming 'unhidden' if they move
426 * and like invisiblity will be come visible if they attack 418 * and like invisiblity will be come visible if they attack
427 * Implemented by b.t. (thomas@astro.psu.edu) 419 * Implemented by b.t. (thomas@astro.psu.edu)
428 * July 7, 1995 - made hiding possible for monsters. -b.t. 420 * July 7, 1995 - made hiding possible for monsters. -b.t.
429 */ 421 */
430
431static int 422static int
432attempt_hide (object *op, object *skill) 423attempt_hide (object *op, object *skill)
433{ 424{
434 int number, difficulty = op->map->difficulty; 425 int number, difficulty = op->map->difficulty;
435 int terrain = hideability (op); 426 int terrain = hideability (op);
438 return 0; 429 return 0;
439 430
440 /* Hiding success and duration dependant on skill level, 431 /* Hiding success and duration dependant on skill level,
441 * op->stats.Dex, map difficulty and terrain. 432 * op->stats.Dex, map difficulty and terrain.
442 */ 433 */
443
444 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2; 434 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2;
435
445 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)))
446 { 437 {
447 op->invisible += 100; /* set the level of 'hiddeness' */ 438 op->invisible += 100; /* set the level of 'hiddeness' */
439
448 if (op->type == PLAYER) 440 if (op->type == PLAYER)
449 op->contr->tmp_invis = 1; 441 op->contr->tmp_invis = 1;
442
450 op->hide = 1; 443 op->hide = 1;
451 return 1; 444 return 1;
452 } 445 }
446
453 return 0; 447 return 0;
454} 448}
455 449
456/* patched this to take terrain into consideration */ 450/* patched this to take terrain into consideration */
457int 451int
458hide (object *op, object *skill) 452hide (object *op, object *skill)
459{ 453{
460
461 /* the preliminaries -- Can we really hide now? */ 454 /* the preliminaries -- Can we really hide now? */
462 /* this keeps monsters from using invisibilty spells and hiding */ 455 /* this keeps monsters from using invisibilty spells and hiding */
463 456
464 if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) 457 if (QUERY_FLAG (op, FLAG_MAKE_INVIS))
465 { 458 {
470 { 463 {
471 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!");
472 make_visible (op); 465 make_visible (op);
473 } 466 }
474 467
475 if (op->invisible > (50 * skill->level)) 468 if (op->invisible > 50 * skill->level)
476 { 469 {
477 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.");
478 return 0; 471 return 0;
479 } 472 }
480 473
482 { 475 {
483 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.");
484 update_object (op, UP_OBJ_FACE); 477 update_object (op, UP_OBJ_FACE);
485 return calc_skill_exp (op, NULL, skill); 478 return calc_skill_exp (op, NULL, skill);
486 } 479 }
480
487 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.");
488 return 0; 482 return 0;
489} 483}
490
491 484
492/* stop_jump() - End of jump. Clear flags, restore the map, and 485/* stop_jump() - End of jump. Clear flags, restore the map, and
493 * freeze the jumper a while to simulate the exhaustion 486 * freeze the jumper a while to simulate the exhaustion
494 * of jumping. 487 * of jumping.
495 */ 488 */
807 new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more."); 800 new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more.");
808 } 801 }
809 return success; 802 return success;
810} 803}
811 804
812
813/* players using this skill can 'charm' a monster -- 805/* players using this skill can 'charm' a monster --
814 * into working for them. It can only be used on 806 * into working for them. It can only be used on
815 * non-special (see below) 'neutral' creatures. 807 * non-special (see below) 'neutral' creatures.
816 * -b.t. (thomas@astro.psu.edu) 808 * -b.t. (thomas@astro.psu.edu)
817 */ 809 */
818
819int 810int
820use_oratory (object *pl, int dir, object *skill) 811use_oratory (object *pl, int dir, object *skill)
821{ 812{
822 sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir];
823 int mflags, chance;
824 object *tmp;
825 maptile *m;
826
827 if (pl->type != PLAYER) 813 if (pl->type != PLAYER)
828 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];
829 m = pl->map; 818 maptile *m = pl->map;
819
830 mflags = get_map_flags (m, &m, x, y, &x, &y); 820 int mflags = get_map_flags (m, &m, x, y, &x, &y);
831 if (mflags & P_OUT_OF_MAP) 821 if (mflags & P_OUT_OF_MAP)
832 return 0; 822 return 0;
833 823
834 /* Save some processing - we have the flag already anyways 824 /* Save some processing - we have the flag already anyways
835 */ 825 */
837 { 827 {
838 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.");
839 return 0; 829 return 0;
840 } 830 }
841 831
832 object *tmp;
842 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)
843 { 834 {
844 /* can't persuade players - return because there is nothing else 835 /* can't persuade players - return because there is nothing else
845 * on that space to charm. Same for multi space monsters and 836 * on that space to charm. Same for multi space monsters and
846 * 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
847 * 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
848 * only monster on the space. 839 * only monster on the space.
849 */ 840 */
850 if (tmp->type == PLAYER) 841 if (tmp->type == PLAYER
851 return 0; 842 || tmp->more || tmp->head_ () != tmp
852 if (tmp->more || tmp->head) 843 || tmp->msg)
853 return 0;
854 if (tmp->msg)
855 return 0; 844 return 0;
856 845
857 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 846 if (QUERY_FLAG (tmp, FLAG_MONSTER))
858 break; 847 break;
859 } 848 }
874 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));
875 return 0; 864 return 0;
876 } 865 }
877 866
878 /* it's already allied! */ 867 /* it's already allied! */
879 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE)) 868 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE)
880 { 869 {
881 if (tmp->owner == pl) 870 if (tmp->owner == pl)
882 { 871 {
883 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");
884 return 0; 873 return 0;
887 { 876 {
888 /* you steal the follower. Perhaps we should really look at the 877 /* you steal the follower. Perhaps we should really look at the
889 * level of the owner above? 878 * level of the owner above?
890 */ 879 */
891 tmp->set_owner (pl); 880 tmp->set_owner (pl);
881 tmp->skill = skill->skill;
882
892 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));
893 /* Abuse fix - don't give exp since this can otherwise 884 /* Abuse fix - don't give exp since this can otherwise
894 * be used by a couple players to gets lots of exp. 885 * be used by a couple players to gets lots of exp.
895 */ 886 */
896 return 0; 887 return 0;
900 /* 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 */
901 return 0; 892 return 0;
902 } 893 }
903 } /* Creature was already a pet of someone */ 894 } /* Creature was already a pet of someone */
904 895
905 chance = skill->level * 2 + (pl->stats.Cha - 2 * tmp->stats.Int) / 2; 896 int level = skill->level + (pl->stats.Cha - tmp->stats.Int) / 2;
906 897
907 /* Ok, got a 'sucker' lets try to make them a follower */ 898 /* Ok, got a 'sucker' lets try to make them a follower */
908 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))
909 { 900 {
910 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));
911 902
912 tmp->set_owner (pl); 903 tmp->set_owner (pl);
904 tmp->skill = skill->skill;
913 tmp->stats.exp = 0; 905 tmp->stats.exp = 0;
914 add_friendly_object (tmp); 906 add_friendly_object (tmp);
915 SET_FLAG (tmp, FLAG_FRIENDLY);
916 tmp->attack_movement = PETMOVE; 907 tmp->attack_movement = PETMOVE;
917 return calc_skill_exp (pl, tmp, skill); 908 return calc_skill_exp (pl, tmp, skill);
918 } 909 }
919 /* Charm failed. Creature may be angry now */ 910 /* Charm failed. Creature may be angry now */
920 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))
924 { 915 {
925 CLEAR_FLAG (tmp, FLAG_FRIENDLY); 916 CLEAR_FLAG (tmp, FLAG_FRIENDLY);
926 remove_friendly_object (tmp); 917 remove_friendly_object (tmp);
927 tmp->attack_movement = 0; /* needed? */ 918 tmp->attack_movement = 0; /* needed? */
928 } 919 }
920
929 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE); 921 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
930 } 922 }
923
931 return 0; /* Fall through - if we get here, we didn't charm anything */ 924 return 0; /* Fall through - if we get here, we didn't charm anything */
932} 925}
933 926
934/* Singing() -this skill allows the player to pacify nearby creatures. 927/* Singing() -this skill allows the player to pacify nearby creatures.
935 * There are few limitations on who/what kind of 928 * There are few limitations on who/what kind of
938 * successfully pacified the creature gets Int=1. Thus, a player 931 * successfully pacified the creature gets Int=1. Thus, a player
939 * may only pacify a creature once. 932 * may only pacify a creature once.
940 * 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
941 * of anything better! -b.t. 934 * of anything better! -b.t.
942 */ 935 */
943
944int 936int
945singing (object *pl, int dir, object *skill) 937singing (object *pl, int dir, object *skill)
946{ 938{
947 int i, exp = 0, chance, mflags; 939 int i, exp = 0;
948 object *tmp; 940 object *tmp;
949 maptile *m; 941 maptile *m;
950 sint16 x, y; 942 sint16 x, y;
951 943
952 if (pl->type != PLAYER) 944 if (pl->type != PLAYER)
957 { 949 {
958 x = pl->x + freearr_x[i]; 950 x = pl->x + freearr_x[i];
959 y = pl->y + freearr_y[i]; 951 y = pl->y + freearr_y[i];
960 m = pl->map; 952 m = pl->map;
961 953
962 mflags = get_map_flags (m, &m, x, y, &x, &y); 954 int mflags = get_map_flags (m, &m, x, y, &x, &y);
963 if (mflags & P_OUT_OF_MAP) 955 if (mflags & P_OUT_OF_MAP)
964 continue; 956 continue;
965 if (!(mflags & P_IS_ALIVE)) 957 if (!(mflags & P_IS_ALIVE))
966 continue; 958 continue;
967 959
986 978
987 /* stealing isn't really related (although, maybe it should 979 /* stealing isn't really related (although, maybe it should
988 * be). This is mainly to prevent singing to the same monster 980 * be). This is mainly to prevent singing to the same monster
989 * over and over again and getting exp for it. 981 * over and over again and getting exp for it.
990 */ 982 */
991 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
992 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))
993 { 986 {
994 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 987 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
995 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));
996 /* Give exp only if they are not aware */ 989 /* Give exp only if they are not aware */
990
997 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL)) 991 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL))
998 exp += calc_skill_exp (pl, tmp, skill); 992 exp += calc_skill_exp (pl, tmp, skill);
993
999 SET_FLAG (tmp, FLAG_NO_STEAL); 994 SET_FLAG (tmp, FLAG_NO_STEAL);
1000 } 995 }
1001 else 996 else
1002 { 997 {
1003 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));
1200 return; 1195 return;
1201 } 1196 }
1202 else 1197 else
1203 { 1198 {
1204 for (tmp = pl->inv; tmp; tmp = tmp->below) 1199 for (tmp = pl->inv; tmp; tmp = tmp->below)
1205 if (((tmp->type == ARMOUR && skill->level < 12) 1200 if (((tmp->type == ARMOUR && skill->level < 12)
1206 || (tmp->type == HELMET && skill->level < 10) 1201 || (tmp->type == HELMET && skill->level < 10)
1207 || (tmp->type == SHIELD && skill->level < 6) 1202 || (tmp->type == SHIELD && skill->level < 6)
1208 || (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))
1209 { 1206 {
1210 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");
1211 return; 1208 return;
1212 } 1209 }
1213 } 1210 }
1235} 1232}
1236 1233
1237/* write_note() - this routine allows players to inscribe messages in 1234/* write_note() - this routine allows players to inscribe messages in
1238 * ordinary 'books' (anything that is type BOOK). b.t. 1235 * ordinary 'books' (anything that is type BOOK). b.t.
1239 */ 1236 */
1240
1241static int 1237static int
1242write_note (object *pl, object *item, const char *msg, object *skill) 1238write_note (object *pl, object *item, const char *msg, object *skill)
1243{ 1239{
1244 char buf[1024]; 1240 char buf[1024];
1245 object *newBook = NULL; 1241 object *newBook = NULL;
1252 { 1248 {
1253 new_draw_info (NDI_UNIQUE, 0, pl, "No message to write!"); 1249 new_draw_info (NDI_UNIQUE, 0, pl, "No message to write!");
1254 new_draw_info_format (NDI_UNIQUE, 0, pl, "Usage: use_skill %s <message>", &skill->skill); 1250 new_draw_info_format (NDI_UNIQUE, 0, pl, "Usage: use_skill %s <message>", &skill->skill);
1255 return 0; 1251 return 0;
1256 } 1252 }
1253
1257 if (strcasestr_local (msg, "endmsg")) 1254 if (strcasestr_local (msg, "endmsg"))
1258 { 1255 {
1259 new_draw_info (NDI_UNIQUE, 0, pl, "Trying to cheat now are we?"); 1256 new_draw_info (NDI_UNIQUE, 0, pl, "Trying to cheat now are we?");
1260 return 0; 1257 return 0;
1261 } 1258 }
1287 /* This shouldn't be necessary - the object hasn't changed in any 1284 /* This shouldn't be necessary - the object hasn't changed in any
1288 * visible way 1285 * visible way
1289 */ 1286 */
1290 /* esrv_send_item(pl, item); */ 1287 /* esrv_send_item(pl, item); */
1291 } 1288 }
1289
1292 new_draw_info_format (NDI_UNIQUE, 0, pl, "You write in the %s.", query_short_name (item)); 1290 new_draw_info_format (NDI_UNIQUE, 0, pl, "You write in the %s.", query_short_name (item));
1293 return strlen (msg); 1291 return strlen (msg);
1294 } 1292 }
1295 else 1293 else
1296 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your message won't fit in the %s!", query_short_name (item)); 1294 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your message won't fit in the %s!", query_short_name (item));
1316 new_draw_info (NDI_UNIQUE, 0, pl, "A spell can only be inscribed into a scroll!"); 1314 new_draw_info (NDI_UNIQUE, 0, pl, "A spell can only be inscribed into a scroll!");
1317 return 0; 1315 return 0;
1318 } 1316 }
1319 1317
1320 /* Check if we are ready to attempt inscription */ 1318 /* Check if we are ready to attempt inscription */
1321 chosen_spell = pl->contr->ranges[range_magic]; 1319 chosen_spell = pl->contr->ranged_ob;
1322 if (!chosen_spell) 1320 if (!chosen_spell || chosen_spell->type != SPELL)
1323 { 1321 {
1324 new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!"); 1322 new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!");
1325 return 0; 1323 return 0;
1326 } 1324 }
1325
1327 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE) > pl->stats.grace) 1326 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE) > pl->stats.grace)
1328 { 1327 {
1329 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough grace to write a scroll of %s.", &chosen_spell->name); 1328 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough grace to write a scroll of %s.", &chosen_spell->name);
1330 return 0; 1329 return 0;
1331 } 1330 }
1331
1332 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA) > pl->stats.sp) 1332 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA) > pl->stats.sp)
1333 { 1333 {
1334 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough mana to write a scroll of %s.", &chosen_spell->name); 1334 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough mana to write a scroll of %s.", &chosen_spell->name);
1335 return 0; 1335 return 0;
1336 } 1336 }
1361 newscroll = scroll->clone (); 1361 newscroll = scroll->clone ();
1362 decrease_ob (scroll); 1362 decrease_ob (scroll);
1363 newscroll->nrof = 1; 1363 newscroll->nrof = 1;
1364 } 1364 }
1365 else 1365 else
1366 {
1367 newscroll = scroll; 1366 newscroll = scroll;
1368 }
1369 1367
1370 if (!confused) 1368 if (!confused)
1371 { 1369 {
1372 newscroll->level = MAX (skill->level, chosen_spell->level); 1370 newscroll->level = MAX (skill->level, chosen_spell->level);
1373 new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll."); 1371 new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll.");
1399 { 1397 {
1400 /* Remove to correctly merge with other items which may exist in inventory */ 1398 /* Remove to correctly merge with other items which may exist in inventory */
1401 newscroll->remove (); 1399 newscroll->remove ();
1402 esrv_del_item (pl->contr, newscroll->count); 1400 esrv_del_item (pl->contr, newscroll->count);
1403 } 1401 }
1402
1404 newscroll = insert_ob_in_ob (newscroll, pl); 1403 newscroll = insert_ob_in_ob (newscroll, pl);
1405 esrv_send_item (pl, newscroll); 1404 esrv_send_item (pl, newscroll);
1406 success = calc_skill_exp (pl, newscroll, skill); 1405 success = calc_skill_exp (pl, newscroll, skill);
1407 if (!confused) 1406 if (!confused)
1408 success *= 2; 1407 success *= 2;
1451 if (!params) 1450 if (!params)
1452 { 1451 {
1453 params = ""; 1452 params = "";
1454 string = params; 1453 string = params;
1455 } 1454 }
1455
1456 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY); 1456 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY);
1457 1457
1458 /* Need to be able to read before we can write! */ 1458 /* Need to be able to read before we can write! */
1459 if (!find_skill_by_name (pl, skat->clone.skill)) 1459 if (!find_skill_by_name (pl, skat->clone.skill))
1460 { 1460 {
1484 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll"); 1484 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll");
1485 return 0; 1485 return 0;
1486 } 1486 }
1487 1487
1488 if (msgtype == SCROLL) 1488 if (msgtype == SCROLL)
1489 {
1490 return write_scroll (pl, item, skill); 1489 return write_scroll (pl, item, skill);
1491 }
1492 else if (msgtype == BOOK) 1490 else if (msgtype == BOOK)
1493 {
1494 return write_note (pl, item, string, skill); 1491 return write_note (pl, item, string, skill);
1495 } 1492
1496 return 0; 1493 return 0;
1497} 1494}
1498
1499
1500 1495
1501/* find_throw_ob() - if we request an object, then 1496/* find_throw_ob() - if we request an object, then
1502 * we search for it in the inventory of the owner (you've 1497 * we search for it in the inventory of the owner (you've
1503 * got to be carrying something in order to throw it!). 1498 * got to be carrying something in order to throw it!).
1504 * If we didnt request an object, then the top object in inventory 1499 * If we didnt request an object, then the top object in inventory
1505 * (that is "throwable", ie no throwing your skills away!) 1500 * (that is "throwable", ie no throwing your skills away!)
1506 * is the object of choice. Also check to see if object is 1501 * is the object of choice. Also check to see if object is
1507 * 'throwable' (ie not applied cursed obj, worn, etc). 1502 * 'throwable' (ie not applied cursed obj, worn, etc).
1508 */ 1503 */
1509
1510static object * 1504static object *
1511find_throw_ob (object *op, const char *request) 1505find_throw_ob (object *op, const char *request)
1512{ 1506{
1513 object *tmp; 1507 object *tmp;
1514 1508
1586 1580
1587/* make_throw_ob() We construct the 'carrier' object in 1581/* make_throw_ob() We construct the 'carrier' object in
1588 * which we will insert the object that is being thrown. 1582 * which we will insert the object that is being thrown.
1589 * This combination becomes the 'thrown object'. -b.t. 1583 * This combination becomes the 'thrown object'. -b.t.
1590 */ 1584 */
1591
1592static object * 1585static object *
1593make_throw_ob (object *orig) 1586make_throw_ob (object *orig)
1594{ 1587{
1595 if (!orig) 1588 if (!orig)
1596 return NULL; 1589 return NULL;
1609 toss_item->stats.dam = 0; /* default damage */ 1602 toss_item->stats.dam = 0; /* default damage */
1610 insert_ob_in_ob (orig, toss_item); 1603 insert_ob_in_ob (orig, toss_item);
1611 return toss_item; 1604 return toss_item;
1612} 1605}
1613 1606
1614
1615/* do_throw() - op throws any object toss_item. This code 1607/* do_throw() - op throws any object toss_item. This code
1616 * was borrowed from fire_bow. 1608 * was borrowed from fire_bow.
1617 * Returns 1 if skill was successfully used, 0 if not 1609 * Returns 1 if skill was successfully used, 0 if not
1618 */ 1610 */
1619
1620static int 1611static int
1621do_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)
1622{ 1613{
1623 object *throw_ob = toss_item, *left = NULL; 1614 object *throw_ob = toss_item, *left = NULL;
1624 int eff_str = 0, maxc, str = op->stats.Str, dam = 0; 1615 int eff_str = 0, maxc, str = op->stats.Str, dam = 0;
1793 if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob)) 1784 if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob))
1794 SET_ANIMATION (throw_ob, dir); 1785 SET_ANIMATION (throw_ob, dir);
1795 } 1786 }
1796 else 1787 else
1797 { 1788 {
1789 uint16 mat = throw_ob->materials;
1790
1798 /* some materials will adjust properties.. */ 1791 /* some materials will adjust properties.. */
1799 if (throw_ob->material & M_LEATHER) 1792 if (mat & M_LEATHER)
1800 { 1793 {
1801 throw_ob->stats.dam -= 1; 1794 throw_ob->stats.dam -= 1;
1802 throw_ob->stats.food -= 10; 1795 throw_ob->stats.food -= 10;
1803 } 1796 }
1804 1797
1805 if (throw_ob->material & M_GLASS) 1798 if (mat & M_GLASS)
1806 throw_ob->stats.food += 60; 1799 throw_ob->stats.food += 60;
1807 1800
1808 if (throw_ob->material & M_ORGANIC) 1801 if (mat & M_ORGANIC)
1809 { 1802 {
1810 throw_ob->stats.dam -= 3; 1803 throw_ob->stats.dam -= 3;
1811 throw_ob->stats.food += 55; 1804 throw_ob->stats.food += 55;
1812 } 1805 }
1813 1806
1814 if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH) 1807 if (mat & M_PAPER || mat & M_CLOTH)
1815 { 1808 {
1816 throw_ob->stats.dam -= 5; 1809 throw_ob->stats.dam -= 5;
1817 throw_ob->speed *= 0.8; 1810 throw_ob->speed *= 0.8;
1818 throw_ob->stats.wc += 3; 1811 throw_ob->stats.wc += 3;
1819 throw_ob->stats.food -= 30; 1812 throw_ob->stats.food -= 30;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines