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) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
5 | Copyright (C) 2003 Mark Wedel & Crossfire Development Team |
5 | * Copyright (C) 2003 Mark Wedel & Crossfire Development Team |
6 | Copyright (C) 1992 Frank Tore Johansen |
6 | * Copyright (C) 1992 Frank Tore Johansen |
7 | |
7 | * |
8 | 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 |
9 | 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 |
10 | the Free Software Foundation; either version 2 of the License, or |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | (at your option) 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, |
13 | * This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License 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 |
18 | * You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
19 | * along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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> |
27 | #ifndef __CEXTRACT__ |
|
|
28 | # include <sproto.h> |
27 | #include <sproto.h> |
29 | #endif |
|
|
30 | #include <living.h> |
28 | #include <living.h> |
31 | #include <skills.h> |
29 | #include <skills.h> |
32 | #include <spells.h> |
30 | #include <spells.h> |
33 | #include <book.h> |
31 | #include <book.h> |
34 | |
32 | |
… | |
… | |
42 | return -1; |
40 | return -1; |
43 | |
41 | |
44 | /* Only prohibit stealing if the player does not have a free |
42 | /* Only prohibit stealing if the player does not have a free |
45 | * hand available and in fact does have hands. |
43 | * hand available and in fact does have hands. |
46 | */ |
44 | */ |
47 | 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) |
48 | { |
46 | { |
49 | 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!"); |
50 | return -1; |
48 | return -1; |
51 | } |
49 | } |
52 | |
50 | |
… | |
… | |
95 | * or not. |
93 | * or not. |
96 | * op is the target (person being pilfered) |
94 | * op is the target (person being pilfered) |
97 | * who is the person doing the stealing. |
95 | * who is the person doing the stealing. |
98 | * skill is the skill object (stealing). |
96 | * skill is the skill object (stealing). |
99 | */ |
97 | */ |
100 | |
|
|
101 | static int |
98 | static int |
102 | attempt_steal (object *op, object *who, object *skill) |
99 | attempt_steal (object *op, object *who, object *skill) |
103 | { |
100 | { |
104 | object *success = NULL, *tmp = NULL, *next; |
101 | object *success = NULL, *tmp = NULL, *next; |
105 | int roll = 0, chance = 0, stats_value; |
102 | int roll = 0, chance = 0, stats_value; |
… | |
… | |
123 | 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 */ |
124 | op->stats.Wis += (op->stats.Int / 5) + 1; |
121 | op->stats.Wis += (op->stats.Int / 5) + 1; |
125 | if (op->stats.Wis > MAX_STAT) |
122 | if (op->stats.Wis > MAX_STAT) |
126 | op->stats.Wis = MAX_STAT; |
123 | op->stats.Wis = MAX_STAT; |
127 | } |
124 | } |
|
|
125 | |
128 | if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ)) |
126 | if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ)) |
129 | { |
127 | { |
130 | 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"); |
131 | return 0; |
129 | return 0; |
132 | } |
130 | } |
133 | #ifdef PROHIBIT_PLAYERKILL |
131 | |
|
|
132 | // only allow stealing between hostile players (TODO: probably should change) |
134 | 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)) |
135 | { |
134 | { |
136 | 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"); |
137 | return 0; |
136 | return 0; |
138 | } |
137 | } |
139 | #else |
|
|
140 | if (op->type == PLAYER && who->type == PLAYER && settings.no_player_stealing) |
|
|
141 | { |
|
|
142 | new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); |
|
|
143 | return 0; |
|
|
144 | } |
|
|
145 | #endif |
|
|
146 | |
|
|
147 | |
138 | |
148 | /* Ok then, go thru their inventory, stealing */ |
139 | /* Ok then, go thru their inventory, stealing */ |
149 | for (tmp = op->inv; tmp != NULL; tmp = next) |
140 | for (tmp = op->inv; tmp; tmp = next) |
150 | { |
141 | { |
151 | next = tmp->below; |
142 | next = tmp->below; |
152 | |
143 | |
153 | /* you can't steal worn items, starting items, wiz stuff, |
144 | /* you can't steal worn items, starting items, wiz stuff, |
154 | * innate abilities, or items w/o a type. Generally |
145 | * innate abilities, or items w/o a type. Generally |
… | |
… | |
158 | * future possible problems. -b.t. |
149 | * future possible problems. -b.t. |
159 | * 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 |
160 | * already -b.t. |
151 | * already -b.t. |
161 | */ |
152 | */ |
162 | |
153 | |
163 | if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED) |
154 | if (QUERY_FLAG (tmp, FLAG_APPLIED) |
164 | || !(tmp->type) |
155 | || !tmp->type |
165 | || tmp->type == SPELL |
156 | || tmp->type == SPELL |
166 | || 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) |
167 | continue; |
160 | continue; |
168 | |
161 | |
169 | /* Okay, try stealing this item. Dependent on dexterity of thief, |
162 | /* Okay, try stealing this item. Dependent on dexterity of thief, |
170 | * skill level, see the adj_stealroll fctn for more detail. |
163 | * skill level, see the adj_stealroll fctn for more detail. |
171 | */ |
164 | */ |
… | |
… | |
262 | /* play_sound("stop! thief!"); kindofthing */ |
255 | /* play_sound("stop! thief!"); kindofthing */ |
263 | } /* if you weren't 100% successful */ |
256 | } /* if you weren't 100% successful */ |
264 | return success ? 1 : 0; |
257 | return success ? 1 : 0; |
265 | } |
258 | } |
266 | |
259 | |
267 | |
|
|
268 | int |
260 | int |
269 | steal (object *op, int dir, object *skill) |
261 | steal (object *op, int dir, object *skill) |
270 | { |
262 | { |
271 | object *tmp, *next; |
263 | object *tmp, *next; |
272 | sint16 x, y; |
264 | sint16 x, y; |
… | |
… | |
808 | new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more."); |
800 | new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more."); |
809 | } |
801 | } |
810 | return success; |
802 | return success; |
811 | } |
803 | } |
812 | |
804 | |
813 | |
|
|
814 | /* players using this skill can 'charm' a monster -- |
805 | /* players using this skill can 'charm' a monster -- |
815 | * into working for them. It can only be used on |
806 | * into working for them. It can only be used on |
816 | * non-special (see below) 'neutral' creatures. |
807 | * non-special (see below) 'neutral' creatures. |
817 | * -b.t. (thomas@astro.psu.edu) |
808 | * -b.t. (thomas@astro.psu.edu) |
818 | */ |
809 | */ |
819 | |
|
|
820 | int |
810 | int |
821 | use_oratory (object *pl, int dir, object *skill) |
811 | use_oratory (object *pl, int dir, object *skill) |
822 | { |
812 | { |
823 | sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir]; |
813 | sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir]; |
824 | int mflags, chance; |
814 | int mflags, chance; |
… | |
… | |
914 | tmp->stats.exp = 0; |
904 | tmp->stats.exp = 0; |
915 | add_friendly_object (tmp); |
905 | add_friendly_object (tmp); |
916 | tmp->attack_movement = PETMOVE; |
906 | tmp->attack_movement = PETMOVE; |
917 | return calc_skill_exp (pl, tmp, skill); |
907 | return calc_skill_exp (pl, tmp, skill); |
918 | } |
908 | } |
|
|
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)) |
921 | { |
912 | { |
922 | 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)); |
923 | if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) |
914 | if (QUERY_FLAG (tmp, FLAG_FRIENDLY)) |
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 |
… | |
… | |
1235 | } |
1228 | } |
1236 | |
1229 | |
1237 | /* write_note() - this routine allows players to inscribe messages in |
1230 | /* write_note() - this routine allows players to inscribe messages in |
1238 | * ordinary 'books' (anything that is type BOOK). b.t. |
1231 | * ordinary 'books' (anything that is type BOOK). b.t. |
1239 | */ |
1232 | */ |
1240 | |
|
|
1241 | static int |
1233 | static int |
1242 | write_note (object *pl, object *item, const char *msg, object *skill) |
1234 | write_note (object *pl, object *item, const char *msg, object *skill) |
1243 | { |
1235 | { |
1244 | char buf[1024]; |
1236 | char buf[1024]; |
1245 | object *newBook = NULL; |
1237 | object *newBook = NULL; |
… | |
… | |
1252 | { |
1244 | { |
1253 | new_draw_info (NDI_UNIQUE, 0, pl, "No message to write!"); |
1245 | 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); |
1246 | new_draw_info_format (NDI_UNIQUE, 0, pl, "Usage: use_skill %s <message>", &skill->skill); |
1255 | return 0; |
1247 | return 0; |
1256 | } |
1248 | } |
|
|
1249 | |
1257 | if (strcasestr_local (msg, "endmsg")) |
1250 | if (strcasestr_local (msg, "endmsg")) |
1258 | { |
1251 | { |
1259 | new_draw_info (NDI_UNIQUE, 0, pl, "Trying to cheat now are we?"); |
1252 | new_draw_info (NDI_UNIQUE, 0, pl, "Trying to cheat now are we?"); |
1260 | return 0; |
1253 | return 0; |
1261 | } |
1254 | } |
… | |
… | |
1287 | /* This shouldn't be necessary - the object hasn't changed in any |
1280 | /* This shouldn't be necessary - the object hasn't changed in any |
1288 | * visible way |
1281 | * visible way |
1289 | */ |
1282 | */ |
1290 | /* esrv_send_item(pl, item); */ |
1283 | /* esrv_send_item(pl, item); */ |
1291 | } |
1284 | } |
|
|
1285 | |
1292 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You write in the %s.", query_short_name (item)); |
1286 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You write in the %s.", query_short_name (item)); |
1293 | return strlen (msg); |
1287 | return strlen (msg); |
1294 | } |
1288 | } |
1295 | else |
1289 | else |
1296 | new_draw_info_format (NDI_UNIQUE, 0, pl, "Your message won't fit in the %s!", query_short_name (item)); |
1290 | 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!"); |
1310 | new_draw_info (NDI_UNIQUE, 0, pl, "A spell can only be inscribed into a scroll!"); |
1317 | return 0; |
1311 | return 0; |
1318 | } |
1312 | } |
1319 | |
1313 | |
1320 | /* Check if we are ready to attempt inscription */ |
1314 | /* Check if we are ready to attempt inscription */ |
1321 | chosen_spell = pl->contr->ranges[range_magic]; |
1315 | chosen_spell = pl->contr->ranged_ob; |
1322 | if (!chosen_spell) |
1316 | if (!chosen_spell || chosen_spell->type != SPELL) |
1323 | { |
1317 | { |
1324 | new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!"); |
1318 | new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!"); |
1325 | return 0; |
1319 | return 0; |
1326 | } |
1320 | } |
|
|
1321 | |
1327 | if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE) > pl->stats.grace) |
1322 | if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE) > pl->stats.grace) |
1328 | { |
1323 | { |
1329 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough grace to write a scroll of %s.", &chosen_spell->name); |
1324 | 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; |
1325 | return 0; |
1331 | } |
1326 | } |
|
|
1327 | |
1332 | if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA) > pl->stats.sp) |
1328 | if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA) > pl->stats.sp) |
1333 | { |
1329 | { |
1334 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough mana to write a scroll of %s.", &chosen_spell->name); |
1330 | 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; |
1331 | return 0; |
1336 | } |
1332 | } |
… | |
… | |
1361 | newscroll = scroll->clone (); |
1357 | newscroll = scroll->clone (); |
1362 | decrease_ob (scroll); |
1358 | decrease_ob (scroll); |
1363 | newscroll->nrof = 1; |
1359 | newscroll->nrof = 1; |
1364 | } |
1360 | } |
1365 | else |
1361 | else |
1366 | { |
|
|
1367 | newscroll = scroll; |
1362 | newscroll = scroll; |
1368 | } |
|
|
1369 | |
1363 | |
1370 | if (!confused) |
1364 | if (!confused) |
1371 | { |
1365 | { |
1372 | newscroll->level = MAX (skill->level, chosen_spell->level); |
1366 | newscroll->level = MAX (skill->level, chosen_spell->level); |
1373 | new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll."); |
1367 | new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll."); |
… | |
… | |
1399 | { |
1393 | { |
1400 | /* Remove to correctly merge with other items which may exist in inventory */ |
1394 | /* Remove to correctly merge with other items which may exist in inventory */ |
1401 | newscroll->remove (); |
1395 | newscroll->remove (); |
1402 | esrv_del_item (pl->contr, newscroll->count); |
1396 | esrv_del_item (pl->contr, newscroll->count); |
1403 | } |
1397 | } |
|
|
1398 | |
1404 | newscroll = insert_ob_in_ob (newscroll, pl); |
1399 | newscroll = insert_ob_in_ob (newscroll, pl); |
1405 | esrv_send_item (pl, newscroll); |
1400 | esrv_send_item (pl, newscroll); |
1406 | success = calc_skill_exp (pl, newscroll, skill); |
1401 | success = calc_skill_exp (pl, newscroll, skill); |
1407 | if (!confused) |
1402 | if (!confused) |
1408 | success *= 2; |
1403 | success *= 2; |
… | |
… | |
1451 | if (!params) |
1446 | if (!params) |
1452 | { |
1447 | { |
1453 | params = ""; |
1448 | params = ""; |
1454 | string = params; |
1449 | string = params; |
1455 | } |
1450 | } |
|
|
1451 | |
1456 | skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY); |
1452 | skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY); |
1457 | |
1453 | |
1458 | /* Need to be able to read before we can write! */ |
1454 | /* Need to be able to read before we can write! */ |
1459 | if (!find_skill_by_name (pl, skat->clone.skill)) |
1455 | if (!find_skill_by_name (pl, skat->clone.skill)) |
1460 | { |
1456 | { |
… | |
… | |
1484 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll"); |
1480 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll"); |
1485 | return 0; |
1481 | return 0; |
1486 | } |
1482 | } |
1487 | |
1483 | |
1488 | if (msgtype == SCROLL) |
1484 | if (msgtype == SCROLL) |
1489 | { |
|
|
1490 | return write_scroll (pl, item, skill); |
1485 | return write_scroll (pl, item, skill); |
1491 | } |
|
|
1492 | else if (msgtype == BOOK) |
1486 | else if (msgtype == BOOK) |
1493 | { |
|
|
1494 | return write_note (pl, item, string, skill); |
1487 | return write_note (pl, item, string, skill); |
1495 | } |
1488 | |
1496 | return 0; |
1489 | return 0; |
1497 | } |
1490 | } |
1498 | |
|
|
1499 | |
|
|
1500 | |
1491 | |
1501 | /* find_throw_ob() - if we request an object, then |
1492 | /* find_throw_ob() - if we request an object, then |
1502 | * we search for it in the inventory of the owner (you've |
1493 | * we search for it in the inventory of the owner (you've |
1503 | * got to be carrying something in order to throw it!). |
1494 | * got to be carrying something in order to throw it!). |
1504 | * If we didnt request an object, then the top object in inventory |
1495 | * If we didnt request an object, then the top object in inventory |
1505 | * (that is "throwable", ie no throwing your skills away!) |
1496 | * (that is "throwable", ie no throwing your skills away!) |
1506 | * is the object of choice. Also check to see if object is |
1497 | * is the object of choice. Also check to see if object is |
1507 | * 'throwable' (ie not applied cursed obj, worn, etc). |
1498 | * 'throwable' (ie not applied cursed obj, worn, etc). |
1508 | */ |
1499 | */ |
1509 | |
|
|
1510 | static object * |
1500 | static object * |
1511 | find_throw_ob (object *op, const char *request) |
1501 | find_throw_ob (object *op, const char *request) |
1512 | { |
1502 | { |
1513 | object *tmp; |
1503 | object *tmp; |
1514 | |
1504 | |
… | |
… | |
1586 | |
1576 | |
1587 | /* make_throw_ob() We construct the 'carrier' object in |
1577 | /* make_throw_ob() We construct the 'carrier' object in |
1588 | * which we will insert the object that is being thrown. |
1578 | * which we will insert the object that is being thrown. |
1589 | * This combination becomes the 'thrown object'. -b.t. |
1579 | * This combination becomes the 'thrown object'. -b.t. |
1590 | */ |
1580 | */ |
1591 | |
|
|
1592 | static object * |
1581 | static object * |
1593 | make_throw_ob (object *orig) |
1582 | make_throw_ob (object *orig) |
1594 | { |
1583 | { |
1595 | if (!orig) |
1584 | if (!orig) |
1596 | return NULL; |
1585 | return NULL; |
… | |
… | |
1609 | toss_item->stats.dam = 0; /* default damage */ |
1598 | toss_item->stats.dam = 0; /* default damage */ |
1610 | insert_ob_in_ob (orig, toss_item); |
1599 | insert_ob_in_ob (orig, toss_item); |
1611 | return toss_item; |
1600 | return toss_item; |
1612 | } |
1601 | } |
1613 | |
1602 | |
1614 | |
|
|
1615 | /* do_throw() - op throws any object toss_item. This code |
1603 | /* do_throw() - op throws any object toss_item. This code |
1616 | * was borrowed from fire_bow. |
1604 | * was borrowed from fire_bow. |
1617 | * Returns 1 if skill was successfully used, 0 if not |
1605 | * Returns 1 if skill was successfully used, 0 if not |
1618 | */ |
1606 | */ |
1619 | |
|
|
1620 | static int |
1607 | static int |
1621 | do_throw (object *op, object *part, object *toss_item, int dir, object *skill) |
1608 | do_throw (object *op, object *part, object *toss_item, int dir, object *skill) |
1622 | { |
1609 | { |
1623 | object *throw_ob = toss_item, *left = NULL; |
1610 | object *throw_ob = toss_item, *left = NULL; |
1624 | int eff_str = 0, maxc, str = op->stats.Str, dam = 0; |
1611 | int eff_str = 0, maxc, str = op->stats.Str, dam = 0; |
… | |
… | |
1793 | if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob)) |
1780 | if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob)) |
1794 | SET_ANIMATION (throw_ob, dir); |
1781 | SET_ANIMATION (throw_ob, dir); |
1795 | } |
1782 | } |
1796 | else |
1783 | else |
1797 | { |
1784 | { |
|
|
1785 | uint16 mat = throw_ob->materials; |
|
|
1786 | |
1798 | /* some materials will adjust properties.. */ |
1787 | /* some materials will adjust properties.. */ |
1799 | if (throw_ob->material & M_LEATHER) |
1788 | if (mat & M_LEATHER) |
1800 | { |
1789 | { |
1801 | throw_ob->stats.dam -= 1; |
1790 | throw_ob->stats.dam -= 1; |
1802 | throw_ob->stats.food -= 10; |
1791 | throw_ob->stats.food -= 10; |
1803 | } |
1792 | } |
1804 | |
1793 | |
1805 | if (throw_ob->material & M_GLASS) |
1794 | if (mat & M_GLASS) |
1806 | throw_ob->stats.food += 60; |
1795 | throw_ob->stats.food += 60; |
1807 | |
1796 | |
1808 | if (throw_ob->material & M_ORGANIC) |
1797 | if (mat & M_ORGANIC) |
1809 | { |
1798 | { |
1810 | throw_ob->stats.dam -= 3; |
1799 | throw_ob->stats.dam -= 3; |
1811 | throw_ob->stats.food += 55; |
1800 | throw_ob->stats.food += 55; |
1812 | } |
1801 | } |
1813 | |
1802 | |
1814 | if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH) |
1803 | if (mat & M_PAPER || mat & M_CLOTH) |
1815 | { |
1804 | { |
1816 | throw_ob->stats.dam -= 5; |
1805 | throw_ob->stats.dam -= 5; |
1817 | throw_ob->speed *= 0.8; |
1806 | throw_ob->speed *= 0.8; |
1818 | throw_ob->stats.wc += 3; |
1807 | throw_ob->stats.wc += 3; |
1819 | throw_ob->stats.food -= 30; |
1808 | throw_ob->stats.food -= 30; |