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 (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * 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 |
9 | * 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 |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * 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 Affero GNU General Public License |
18 | * 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 |
19 | * and the GNU General Public License along with this program. If not, see |
20 | * <http://www.gnu.org/licenses/>. |
20 | * <http://www.gnu.org/licenses/>. |
21 | * |
21 | * |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | */ |
23 | */ |
24 | |
24 | |
25 | #include <cmath> |
25 | #include <cmath> |
26 | |
26 | |
… | |
… | |
690 | // elmex: only identify if we need to, for example so that generated money doesn't |
690 | // elmex: only identify if we need to, for example so that generated money doesn't |
691 | // get an 'identified' flag so easily. |
691 | // get an 'identified' flag so easily. |
692 | if (item->need_identify ()) |
692 | if (item->need_identify ()) |
693 | identify (item); |
693 | identify (item); |
694 | |
694 | |
695 | insert_ob_in_map_at (item, converter->map, converter, 0, converter->x, converter->y); |
695 | item->insert_at (converter, 0, INS_NO_WALK_ON); |
|
|
696 | |
696 | return 1; |
697 | return 1; |
697 | } |
698 | } |
698 | |
699 | |
699 | /** |
700 | /** |
700 | * Handle apply on containers. |
701 | * Handle apply on containers. |
… | |
… | |
731 | op->close_container (); |
732 | op->close_container (); |
732 | return 1; |
733 | return 1; |
733 | } |
734 | } |
734 | else if (!sack->env) |
735 | else if (!sack->env) |
735 | { |
736 | { |
736 | // active, but not ours: some other player has opened it |
737 | // active on floor, but not ours: some other player has opened it |
|
|
738 | // normally this only happens to dms standing on the same space. |
|
|
739 | // but it doesn't hurt to handle it. |
737 | op->failmsgf ("Somebody else is using the %s already.", query_name (sack)); |
740 | op->failmsgf ("Somebody else is using the %s already.", query_name (sack)); |
738 | return 1; |
741 | return 1; |
739 | } |
742 | } |
|
|
743 | } |
740 | |
744 | |
741 | // fall through to opening it (active in inv) |
745 | // it's locked? |
|
|
746 | if (sack->slaying) |
742 | } |
747 | { |
743 | else if (sack->env) |
748 | if (object *tmp = find_key (op, op, sack)) |
|
|
749 | { |
|
|
750 | op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp))); |
|
|
751 | } |
|
|
752 | else |
|
|
753 | { |
|
|
754 | sack->flag [FLAG_APPLIED] = false; // might be applied in inv, let the user close it |
|
|
755 | esrv_update_item (UPD_FLAGS, op, sack); |
|
|
756 | op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack))); |
|
|
757 | return 1; |
|
|
758 | } |
|
|
759 | } |
|
|
760 | |
|
|
761 | if (sack->env && !sack->flag [FLAG_APPLIED]) |
744 | { |
762 | { |
745 | // it is in our env, so activate it, do not open yet |
763 | // it is in our env, so activate it, do not open yet |
746 | op->close_container (); |
764 | op->close_container (); |
747 | sack->flag [FLAG_APPLIED] = 1; |
765 | sack->flag [FLAG_APPLIED] = true; |
748 | esrv_update_item (UPD_FLAGS, op, sack); |
766 | esrv_update_item (UPD_FLAGS, op, sack); |
749 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
767 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
750 | return 1; |
|
|
751 | } |
|
|
752 | |
|
|
753 | // it's locked? |
|
|
754 | if (sack->slaying) |
|
|
755 | { |
768 | } |
756 | if (object *tmp = find_key (op, op, sack)) |
|
|
757 | op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp))); |
|
|
758 | else |
769 | else |
759 | { |
|
|
760 | op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack))); |
|
|
761 | return 1; |
|
|
762 | } |
|
|
763 | } |
|
|
764 | |
|
|
765 | op->open_container (sack); |
770 | op->open_container (sack); |
766 | |
771 | |
767 | return 1; |
772 | return 1; |
768 | } |
773 | } |
769 | |
774 | |
770 | /** |
775 | /** |
… | |
… | |
1058 | who->flag [FLAG_READY_WEAPON] = false; |
1063 | who->flag [FLAG_READY_WEAPON] = false; |
1059 | |
1064 | |
1060 | // unapplying a weapon or skill tool should also unapply the skill it governs |
1065 | // unapplying a weapon or skill tool should also unapply the skill it governs |
1061 | // but this is hard, as it shouldn't do so when the skill can |
1066 | // but this is hard, as it shouldn't do so when the skill can |
1062 | // be used for other reasons |
1067 | // be used for other reasons |
|
|
1068 | //TODO: really? |
1063 | if (who->chosen_skill) |
1069 | if (who->chosen_skill) |
1064 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1070 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1065 | unapply_special (who, op, 0); |
1071 | unapply_special (who, who->chosen_skill, 0); |
1066 | |
1072 | |
1067 | break; |
1073 | break; |
1068 | |
1074 | |
|
|
1075 | case RANGED: |
1069 | case BOW: |
1076 | case BOW: |
1070 | case WAND: |
1077 | case WAND: |
1071 | case ROD: |
1078 | case ROD: |
1072 | case HORN: |
1079 | case HORN: |
1073 | case RANGED: |
|
|
1074 | if (player *pl = who->contr) |
1080 | if (player *pl = who->contr) |
1075 | { |
1081 | { |
1076 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1082 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1077 | change_abil (who, op); |
1083 | change_abil (who, op); |
1078 | } |
1084 | } |
… | |
… | |
1387 | |
1393 | |
1388 | static bool |
1394 | static bool |
1389 | apply_special (object *who, object *op, int aflags) |
1395 | apply_special (object *who, object *op, int aflags) |
1390 | { |
1396 | { |
1391 | int basic_flag = aflags & AP_MODE; |
1397 | int basic_flag = aflags & AP_MODE; |
1392 | object *tmp, *tmp2, *skop = NULL; |
1398 | object *tmp, *skop = NULL; |
1393 | |
|
|
1394 | if (who == NULL) |
|
|
1395 | { |
|
|
1396 | LOG (llevError, "apply_special() from object without environment.\n"); |
|
|
1397 | return 1; |
|
|
1398 | } |
|
|
1399 | |
|
|
1400 | //TODO: remove these when apply_special is no longer exposed |
|
|
1401 | if (op->env != who) |
|
|
1402 | return 1; /* op is not in inventory */ |
|
|
1403 | |
1399 | |
1404 | /* trying to unequip op */ |
1400 | /* trying to unequip op */ |
1405 | if (op->flag [FLAG_APPLIED]) |
1401 | if (op->flag [FLAG_APPLIED]) |
1406 | { |
1402 | { |
1407 | /* always apply, so no reason to unapply */ |
1403 | /* always apply, so no reason to unapply */ |
1408 | if (basic_flag == AP_APPLY) |
1404 | if (basic_flag == AP_APPLY) |
1409 | return 0; |
1405 | return 0; |
1410 | |
|
|
1411 | if (!(aflags & AP_IGNORE_CURSE) && (op->flag [FLAG_CURSED] || op->flag [FLAG_DAMNED])) |
|
|
1412 | { |
|
|
1413 | who->failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, query_name (op)); |
|
|
1414 | return 1; |
|
|
1415 | } |
|
|
1416 | |
1406 | |
1417 | return unapply_special (who, op, aflags); |
1407 | return unapply_special (who, op, aflags); |
1418 | } |
1408 | } |
1419 | else if (basic_flag == AP_UNAPPLY) |
1409 | else if (basic_flag == AP_UNAPPLY) |
1420 | return 0; |
1410 | return 0; |
… | |
… | |
1538 | //TODO: unapplying should unapply the skill, though |
1528 | //TODO: unapplying should unapply the skill, though |
1539 | op->set_flag (FLAG_APPLIED); |
1529 | op->set_flag (FLAG_APPLIED); |
1540 | break; |
1530 | break; |
1541 | |
1531 | |
1542 | case SKILL: |
1532 | case SKILL: |
1543 | if (!(aflags & AP_NO_SLOT)) |
|
|
1544 | { |
|
|
1545 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
1546 | |
|
|
1547 | if (skill_flags [op->subtype] & (SF_NEED_ITEM | SF_MANA)) |
|
|
1548 | { |
|
|
1549 | who->failmsgf ( |
|
|
1550 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1551 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
1552 | "It cannot be used on its own.>", |
|
|
1553 | &op->skill |
|
|
1554 | ); |
|
|
1555 | if (tmp) who->insert (tmp); |
|
|
1556 | return 1; |
|
|
1557 | } |
|
|
1558 | |
|
|
1559 | if (skill_flags [op->subtype] & SF_AUTARK |
|
|
1560 | || !(skill_flags [op->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
1561 | { |
|
|
1562 | if (skill_flags [op->subtype] & SF_USE) |
|
|
1563 | who->failmsgf ( |
|
|
1564 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1565 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
1566 | &op->skill, &op->skill |
|
|
1567 | ); |
|
|
1568 | else |
|
|
1569 | who->failmsgf ( |
|
|
1570 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1571 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
1572 | &op->skill |
|
|
1573 | ); |
|
|
1574 | |
|
|
1575 | if (tmp) who->insert (tmp); |
|
|
1576 | |
|
|
1577 | return 1; |
|
|
1578 | } |
|
|
1579 | |
|
|
1580 | if (who->contr) |
1533 | if (who->contr) |
1581 | if (op->invisible) |
1534 | if (op->invisible) |
1582 | who->statusmsg (format ("You can now use the %s skill.", &op->skill)); |
1535 | who->statusmsg (format ("You can now use the %s skill.", &op->skill)); |
1583 | else |
1536 | else |
1584 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1537 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1585 | } |
|
|
1586 | |
1538 | |
1587 | who->set_flag (FLAG_READY_SKILL); |
1539 | who->set_flag (FLAG_READY_SKILL); |
1588 | op->set_flag (FLAG_APPLIED); |
1540 | op->set_flag (FLAG_APPLIED); |
1589 | change_abil (who, op); |
1541 | change_abil (who, op); |
1590 | break; |
1542 | break; |
… | |
… | |
1814 | * matching item. |
1766 | * matching item. |
1815 | **/ |
1767 | **/ |
1816 | void |
1768 | void |
1817 | handle_apply_yield (object *tmp) |
1769 | handle_apply_yield (object *tmp) |
1818 | { |
1770 | { |
1819 | if (shstr_tmp yield = tmp->kv (shstr_on_use_yield)) |
1771 | if (shstr_tmp yield = tmp->kv [shstr_on_use_yield]) |
1820 | archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); |
1772 | archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); |
1821 | } |
1773 | } |
1822 | |
1774 | |
1823 | /** |
1775 | /** |
1824 | * Handles applying a potion. |
1776 | * Handles applying a potion. |
… | |
… | |
1826 | int |
1778 | int |
1827 | apply_potion (object *op, object *tmp) |
1779 | apply_potion (object *op, object *tmp) |
1828 | { |
1780 | { |
1829 | int got_one = 0, i; |
1781 | int got_one = 0, i; |
1830 | object *force = 0; |
1782 | object *force = 0; |
1831 | |
|
|
1832 | object *floor = GET_MAP_OB (op->map, op->x, op->y); |
|
|
1833 | |
1783 | |
1834 | if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) |
1784 | if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) |
1835 | { |
1785 | { |
1836 | op->failmsg ("Gods prevent you from using this here, it's sacred ground!"); |
1786 | op->failmsg ("Gods prevent you from using this here, it's sacred ground!"); |
1837 | |
1787 | |
… | |
… | |
1991 | for (i = 0; i < NROFATTACKS; i++) |
1941 | for (i = 0; i < NROFATTACKS; i++) |
1992 | { |
1942 | { |
1993 | if (tmp->resist[i]) |
1943 | if (tmp->resist[i]) |
1994 | { |
1944 | { |
1995 | if (!force) |
1945 | if (!force) |
1996 | force = get_archetype (FORCE_NAME); |
1946 | force = archetype::get (FORCE_NAME); |
1997 | |
1947 | |
1998 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
1948 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
1999 | force->type = POTION_EFFECT; |
1949 | force->type = POTION_EFFECT; |
2000 | break; /* Only need to find one protection since we copy entire batch */ |
1950 | break; /* Only need to find one protection since we copy entire batch */ |
2001 | } |
1951 | } |
… | |
… | |
2144 | case ARROW: |
2094 | case ARROW: |
2145 | /* bad bug: monster throw a object, make a step forwards, step on object , |
2095 | /* bad bug: monster throw a object, make a step forwards, step on object , |
2146 | * trigger this here and get hit by own missile - and will be own enemy. |
2096 | * trigger this here and get hit by own missile - and will be own enemy. |
2147 | * Victim then is his own enemy and will start to kill herself (this is |
2097 | * Victim then is his own enemy and will start to kill herself (this is |
2148 | * removed) but we have not synced victim and his missile. To avoid senseless |
2098 | * removed) but we have not synced victim and his missile. To avoid senseless |
2149 | * action, we avoid hits here |
2099 | * action, we avoid hits here |
2150 | */ |
2100 | */ |
2151 | if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) |
2101 | if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) |
2152 | && trap->owner != victim) |
2102 | && trap->owner != victim) |
2153 | hit_with_arrow (trap, victim); |
2103 | hit_with_arrow (trap, victim); |
2154 | break; |
2104 | break; |
… | |
… | |
2361 | if (failure <= -1 && failure > -15) |
2311 | if (failure <= -1 && failure > -15) |
2362 | { /* wonder */ |
2312 | { /* wonder */ |
2363 | object *tmp; |
2313 | object *tmp; |
2364 | |
2314 | |
2365 | op->failmsg ("Your spell warps!"); |
2315 | op->failmsg ("Your spell warps!"); |
2366 | tmp = get_archetype (SPELL_WONDER); |
2316 | tmp = archetype::get (SPELL_WONDER); |
2367 | cast_wonder (op, op, 0, tmp); |
2317 | cast_wonder (op, op, 0, tmp); |
2368 | tmp->destroy (); |
2318 | tmp->destroy (); |
2369 | } |
2319 | } |
2370 | else if (failure <= -15 && failure > -35) |
2320 | else if (failure <= -15 && failure > -35) |
2371 | { /* drain mana */ |
2321 | { /* drain mana */ |
… | |
… | |
2391 | op->failmsg ("The magic recoils on you!"); |
2341 | op->failmsg ("The magic recoils on you!"); |
2392 | blind_player (op, op, power); |
2342 | blind_player (op, op, power); |
2393 | } |
2343 | } |
2394 | else if (failure <= -80) |
2344 | else if (failure <= -80) |
2395 | { /* blast the immediate area */ |
2345 | { /* blast the immediate area */ |
2396 | object *tmp = get_archetype (LOOSE_MANA); |
2346 | object *tmp = archetype::get (LOOSE_MANA); |
2397 | cast_magic_storm (op, tmp, power); |
2347 | cast_magic_storm (op, tmp, power); |
2398 | op->failmsg ("You unleash uncontrolled mana!"); |
2348 | op->failmsg ("You unleash uncontrolled mana!"); |
2399 | tmp->destroy (); |
2349 | tmp->destroy (); |
2400 | } |
2350 | } |
2401 | } |
2351 | } |
… | |
… | |
3075 | * the selected object to "burn". -b.t. |
3025 | * the selected object to "burn". -b.t. |
3076 | */ |
3026 | */ |
3077 | static void |
3027 | static void |
3078 | apply_lighter (object *who, object *lighter) |
3028 | apply_lighter (object *who, object *lighter) |
3079 | { |
3029 | { |
3080 | int is_player_env = 0; |
|
|
3081 | |
|
|
3082 | if (object *item = who->mark ()) |
3030 | if (object *item = who->mark ()) |
3083 | { |
3031 | { |
3084 | if (!auto_apply_lighter (who, item, lighter)) |
3032 | if (!auto_apply_lighter (who, item, lighter)) |
3085 | return; |
3033 | return; |
3086 | |
3034 | |
… | |
… | |
3343 | |
3291 | |
3344 | strcpy (got, find); |
3292 | strcpy (got, find); |
3345 | got[len] = '\0'; |
3293 | got[len] = '\0'; |
3346 | |
3294 | |
3347 | /* Now create new item, remove used ones when required. */ |
3295 | /* Now create new item, remove used ones when required. */ |
3348 | new_item = get_archetype (got); |
3296 | new_item = archetype::get (got); |
3349 | if (!new_item) |
3297 | if (!new_item) |
3350 | { |
3298 | { |
3351 | pl->failmsgf ("This %s is strange, better to not use it.", query_base_name (marked, 0)); |
3299 | pl->failmsgf ("This %s is strange, better to not use it.", query_base_name (marked, 0)); |
3352 | return; |
3300 | return; |
3353 | } |
3301 | } |
… | |
… | |
3380 | * them in this function - they are passed to apply_special |
3328 | * them in this function - they are passed to apply_special |
3381 | */ |
3329 | */ |
3382 | static bool |
3330 | static bool |
3383 | manual_apply (object *who, object *op, int aflag) |
3331 | manual_apply (object *who, object *op, int aflag) |
3384 | { |
3332 | { |
3385 | op = op->head_ (); |
|
|
3386 | |
|
|
3387 | if (op->flag [FLAG_UNPAID] && !op->flag [FLAG_APPLIED]) |
|
|
3388 | { |
|
|
3389 | if (who->contr) |
|
|
3390 | { |
|
|
3391 | examine (who, op); |
|
|
3392 | //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove |
|
|
3393 | return 1; |
|
|
3394 | } |
|
|
3395 | else |
|
|
3396 | return 0; /* monsters just skip unpaid items */ |
|
|
3397 | } |
|
|
3398 | |
|
|
3399 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3333 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3400 | return RESULT_INT (0); |
3334 | return RESULT_INT (0); |
3401 | else if (apply_types_inv_only [op->type]) |
3335 | else if (apply_types_inv_only [op->type]) |
3402 | { |
3336 | { |
3403 | // special item, using slot system, needs to be in inv |
3337 | // special item, using slot system, needs to be in inv |
… | |
… | |
3433 | |
3367 | |
3434 | break; |
3368 | break; |
3435 | |
3369 | |
3436 | case EXIT: |
3370 | case EXIT: |
3437 | if (!EXIT_PATH (op)) |
3371 | if (!EXIT_PATH (op)) |
3438 | who->failmsgf ("The %s is closed. H<And will stay closed, until somebody fires up the map editor and adds it.>", query_name (op)); |
3372 | who->failmsgf ("The %s is closed. H<This exit doesn't lead anywhere at the moment, and this is unlikely to change.>", query_name (op)); |
3439 | else |
3373 | else |
3440 | { |
3374 | { |
3441 | /* Don't display messages for random maps. */ |
3375 | /* Don't display messages for random maps. */ |
3442 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3376 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3443 | who->statusmsg (op->msg, NDI_NAVY); |
3377 | who->statusmsg (op->msg, NDI_NAVY); |
… | |
… | |
3549 | |
3483 | |
3550 | return 1; |
3484 | return 1; |
3551 | } |
3485 | } |
3552 | else |
3486 | else |
3553 | { |
3487 | { |
3554 | who->statusmsg (format ("I don't know how to apply the %s.", query_name (op))); |
3488 | who->statusmsg (format ("I don't know how to apply the %s. H<This object cannot be applied.>", query_name (op))); |
3555 | return 0; |
3489 | return 0; |
3556 | } |
3490 | } |
3557 | } |
3491 | } |
3558 | |
3492 | |
3559 | /** |
3493 | /** |
… | |
… | |
3622 | object::apply (object *ob, int aflags) |
3556 | object::apply (object *ob, int aflags) |
3623 | { |
3557 | { |
3624 | if (!ob) // simplifies a lot of callers |
3558 | if (!ob) // simplifies a lot of callers |
3625 | return true; |
3559 | return true; |
3626 | |
3560 | |
|
|
3561 | ob = ob->head_ (); |
|
|
3562 | |
|
|
3563 | if (ob->flag [FLAG_UNPAID] && !ob->flag [FLAG_APPLIED]) |
|
|
3564 | { |
|
|
3565 | if (contr) |
|
|
3566 | { |
|
|
3567 | examine (this, ob); |
|
|
3568 | //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove |
|
|
3569 | return 1; |
|
|
3570 | } |
|
|
3571 | else |
|
|
3572 | return 0; /* monsters just skip unpaid items */ |
|
|
3573 | } |
|
|
3574 | |
3627 | if (contr) |
3575 | if (contr) |
3628 | { |
3576 | { |
3629 | if (!ob->env && (move_type & MOVE_FLYING)) |
3577 | if (!ob->env && (move_type & MOVE_FLYING)) |
3630 | { |
3578 | { |
3631 | /* player is flying and applying object not in inventory */ |
3579 | /* player is flying and applying object not in inventory */ |
… | |
… | |
3644 | bool want_apply = |
3592 | bool want_apply = |
3645 | aflags & AP_APPLY ? true |
3593 | aflags & AP_APPLY ? true |
3646 | : aflags & AP_UNAPPLY ? false |
3594 | : aflags & AP_UNAPPLY ? false |
3647 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3595 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3648 | |
3596 | |
|
|
3597 | // cannot unapply cursed items |
|
|
3598 | if (!want_apply |
|
|
3599 | && (ob->flag [FLAG_CURSED] || ob->flag [FLAG_DAMNED]) |
|
|
3600 | && ob->flag [FLAG_APPLIED] |
|
|
3601 | && !(aflags & AP_IGNORE_CURSE)) |
|
|
3602 | { |
|
|
3603 | failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, ob->query_name ()); |
|
|
3604 | return 0; |
|
|
3605 | } |
|
|
3606 | |
3649 | object_ptr *slot = 0; |
3607 | object_ptr *slot = 0; |
3650 | |
3608 | |
3651 | // detect the slot, if this is a player |
3609 | // detect the slot, if this is a player |
3652 | if (contr && !(aflags & AP_NO_SLOT)) |
3610 | if (contr && !(aflags & AP_NO_SLOT)) |
3653 | { |
3611 | { |
… | |
… | |
3658 | case WEAPON: |
3616 | case WEAPON: |
3659 | slot = &contr->combat_ob; |
3617 | slot = &contr->combat_ob; |
3660 | oslot = contr->ranged_ob; |
3618 | oslot = contr->ranged_ob; |
3661 | break; |
3619 | break; |
3662 | |
3620 | |
|
|
3621 | case RANGED: |
3663 | case BOW: |
3622 | case BOW: |
3664 | case RANGED: |
|
|
3665 | case SPELL: |
3623 | case SPELL: |
3666 | case WAND: |
3624 | case WAND: |
3667 | case ROD: |
3625 | case ROD: |
3668 | case HORN: |
3626 | case HORN: |
3669 | case BUILDER: |
3627 | case BUILDER: |
… | |
… | |
3671 | oslot = contr->combat_ob; |
3629 | oslot = contr->combat_ob; |
3672 | break; |
3630 | break; |
3673 | |
3631 | |
3674 | // oh, the humanity |
3632 | // oh, the humanity |
3675 | case SKILL: |
3633 | case SKILL: |
3676 | if (aflags & AP_NO_SLOT) |
3634 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
3635 | |
|
|
3636 | if (skill_flags [ob->subtype] & (SF_NEED_ITEM | SF_MANA)) |
3677 | break; |
3637 | { |
|
|
3638 | failmsgf ( |
|
|
3639 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3640 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
3641 | "It cannot be used on its own.>", |
|
|
3642 | &ob->skill |
|
|
3643 | ); |
|
|
3644 | return 1; |
|
|
3645 | } |
|
|
3646 | |
|
|
3647 | if (skill_flags [ob->subtype] & SF_AUTARK |
|
|
3648 | || !(skill_flags [ob->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
3649 | { |
|
|
3650 | if (skill_flags [ob->subtype] & SF_USE) |
|
|
3651 | failmsgf ( |
|
|
3652 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3653 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
3654 | &ob->skill, &ob->skill |
|
|
3655 | ); |
|
|
3656 | else |
|
|
3657 | failmsgf ( |
|
|
3658 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3659 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
3660 | &ob->skill |
|
|
3661 | ); |
|
|
3662 | |
|
|
3663 | return 1; |
|
|
3664 | } |
3678 | |
3665 | |
3679 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3666 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3680 | break; |
3667 | break; |
3681 | |
3668 | |
3682 | if (skill_flags [ob->subtype] & SF_COMBAT) |
3669 | if (skill_flags [ob->subtype] & SF_COMBAT) |
… | |
… | |
3699 | // only one slot can be active |
3686 | // only one slot can be active |
3700 | if (want_apply) |
3687 | if (want_apply) |
3701 | { |
3688 | { |
3702 | // clear slot unless we are in it already |
3689 | // clear slot unless we are in it already |
3703 | if (*slot != ob) |
3690 | if (*slot != ob) |
3704 | apply (*slot, AP_UNAPPLY); |
3691 | if (!apply (*slot, AP_UNAPPLY)) |
|
|
3692 | return false; |
3705 | |
3693 | |
3706 | // unapply other slot, because we want to become active |
3694 | // unapply other slot, because we want to become active |
3707 | apply (oslot, AP_UNAPPLY); |
3695 | if (!apply (oslot, AP_UNAPPLY)) |
|
|
3696 | return false; |
3708 | } |
3697 | } |
3709 | |
3698 | |
3710 | // clear item from slot if applied |
3699 | // clear item from slot if applied |
3711 | if (!want_apply && current_weapon == ob) |
3700 | if (!want_apply && current_weapon == ob) |
3712 | current_weapon = 0; |
3701 | current_weapon = 0; |
… | |
… | |
3731 | * Generates shop floor's item, and treasures. |
3720 | * Generates shop floor's item, and treasures. |
3732 | */ |
3721 | */ |
3733 | int |
3722 | int |
3734 | auto_apply (object *op) |
3723 | auto_apply (object *op) |
3735 | { |
3724 | { |
3736 | object *tmp = NULL, *tmp2; |
3725 | object *tmp = NULL; |
3737 | int i; |
3726 | int i; |
3738 | |
3727 | |
3739 | op->clr_flag (FLAG_AUTO_APPLY); |
3728 | op->clr_flag (FLAG_AUTO_APPLY); |
3740 | |
3729 | |
3741 | switch (op->type) |
3730 | switch (op->type) |
… | |
… | |
3827 | while (invtmp->stats.hp-- > 0) |
3816 | while (invtmp->stats.hp-- > 0) |
3828 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3817 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3829 | |
3818 | |
3830 | invtmp->randomitems = NULL; |
3819 | invtmp->randomitems = NULL; |
3831 | } |
3820 | } |
3832 | else if (invtmp && invtmp->arch |
3821 | else if (invtmp->arch |
3833 | && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && invtmp->has_random_items ()) |
3822 | && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS |
|
|
3823 | && invtmp->has_random_items ()) |
3834 | { |
3824 | { |
3835 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3825 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3836 | /* Need to clear this so that we never try to create |
3826 | /* Need to clear this so that we never try to create |
3837 | * treasure again for this object |
3827 | * treasure again for this object |
3838 | */ |
3828 | */ |