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. |
… | |
… | |
1069 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1070 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1070 | unapply_special (who, who->chosen_skill, 0); |
1071 | unapply_special (who, who->chosen_skill, 0); |
1071 | |
1072 | |
1072 | break; |
1073 | break; |
1073 | |
1074 | |
|
|
1075 | case RANGED: |
1074 | case BOW: |
1076 | case BOW: |
1075 | case WAND: |
1077 | case WAND: |
1076 | case ROD: |
1078 | case ROD: |
1077 | case HORN: |
1079 | case HORN: |
1078 | case RANGED: |
|
|
1079 | if (player *pl = who->contr) |
1080 | if (player *pl = who->contr) |
1080 | { |
1081 | { |
1081 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1082 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1082 | change_abil (who, op); |
1083 | change_abil (who, op); |
1083 | } |
1084 | } |
… | |
… | |
1392 | |
1393 | |
1393 | static bool |
1394 | static bool |
1394 | apply_special (object *who, object *op, int aflags) |
1395 | apply_special (object *who, object *op, int aflags) |
1395 | { |
1396 | { |
1396 | int basic_flag = aflags & AP_MODE; |
1397 | int basic_flag = aflags & AP_MODE; |
1397 | object *tmp, *tmp2, *skop = NULL; |
1398 | object *tmp, *skop = NULL; |
1398 | |
|
|
1399 | if (who == NULL) |
|
|
1400 | { |
|
|
1401 | LOG (llevError, "apply_special() from object without environment.\n"); |
|
|
1402 | return 1; |
|
|
1403 | } |
|
|
1404 | |
|
|
1405 | //TODO: remove these when apply_special is no longer exposed |
|
|
1406 | if (op->env != who) |
|
|
1407 | return 1; /* op is not in inventory */ |
|
|
1408 | |
1399 | |
1409 | /* trying to unequip op */ |
1400 | /* trying to unequip op */ |
1410 | if (op->flag [FLAG_APPLIED]) |
1401 | if (op->flag [FLAG_APPLIED]) |
1411 | { |
1402 | { |
1412 | /* always apply, so no reason to unapply */ |
1403 | /* always apply, so no reason to unapply */ |
1413 | if (basic_flag == AP_APPLY) |
1404 | if (basic_flag == AP_APPLY) |
1414 | return 0; |
1405 | return 0; |
1415 | |
|
|
1416 | if (!(aflags & AP_IGNORE_CURSE) && (op->flag [FLAG_CURSED] || op->flag [FLAG_DAMNED])) |
|
|
1417 | { |
|
|
1418 | who->failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, query_name (op)); |
|
|
1419 | return 1; |
|
|
1420 | } |
|
|
1421 | |
1406 | |
1422 | return unapply_special (who, op, aflags); |
1407 | return unapply_special (who, op, aflags); |
1423 | } |
1408 | } |
1424 | else if (basic_flag == AP_UNAPPLY) |
1409 | else if (basic_flag == AP_UNAPPLY) |
1425 | return 0; |
1410 | return 0; |
… | |
… | |
1543 | //TODO: unapplying should unapply the skill, though |
1528 | //TODO: unapplying should unapply the skill, though |
1544 | op->set_flag (FLAG_APPLIED); |
1529 | op->set_flag (FLAG_APPLIED); |
1545 | break; |
1530 | break; |
1546 | |
1531 | |
1547 | case SKILL: |
1532 | case SKILL: |
1548 | if (!(aflags & AP_NO_SLOT)) |
|
|
1549 | { |
|
|
1550 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
1551 | |
|
|
1552 | if (skill_flags [op->subtype] & (SF_NEED_ITEM | SF_MANA)) |
|
|
1553 | { |
|
|
1554 | who->failmsgf ( |
|
|
1555 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1556 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
1557 | "It cannot be used on its own.>", |
|
|
1558 | &op->skill |
|
|
1559 | ); |
|
|
1560 | if (tmp) who->insert (tmp); |
|
|
1561 | return 1; |
|
|
1562 | } |
|
|
1563 | |
|
|
1564 | if (skill_flags [op->subtype] & SF_AUTARK |
|
|
1565 | || !(skill_flags [op->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
1566 | { |
|
|
1567 | if (skill_flags [op->subtype] & SF_USE) |
|
|
1568 | who->failmsgf ( |
|
|
1569 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1570 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
1571 | &op->skill, &op->skill |
|
|
1572 | ); |
|
|
1573 | else |
|
|
1574 | who->failmsgf ( |
|
|
1575 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1576 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
1577 | &op->skill |
|
|
1578 | ); |
|
|
1579 | |
|
|
1580 | if (tmp) who->insert (tmp); |
|
|
1581 | |
|
|
1582 | return 1; |
|
|
1583 | } |
|
|
1584 | |
|
|
1585 | if (who->contr) |
1533 | if (who->contr) |
1586 | if (op->invisible) |
1534 | if (op->invisible) |
1587 | 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)); |
1588 | else |
1536 | else |
1589 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1537 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1590 | } |
|
|
1591 | |
1538 | |
1592 | who->set_flag (FLAG_READY_SKILL); |
1539 | who->set_flag (FLAG_READY_SKILL); |
1593 | op->set_flag (FLAG_APPLIED); |
1540 | op->set_flag (FLAG_APPLIED); |
1594 | change_abil (who, op); |
1541 | change_abil (who, op); |
1595 | break; |
1542 | break; |
… | |
… | |
1819 | * matching item. |
1766 | * matching item. |
1820 | **/ |
1767 | **/ |
1821 | void |
1768 | void |
1822 | handle_apply_yield (object *tmp) |
1769 | handle_apply_yield (object *tmp) |
1823 | { |
1770 | { |
1824 | if (shstr_tmp yield = tmp->kv (shstr_on_use_yield)) |
1771 | if (shstr_tmp yield = tmp->kv [shstr_on_use_yield]) |
1825 | archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); |
1772 | archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); |
1826 | } |
1773 | } |
1827 | |
1774 | |
1828 | /** |
1775 | /** |
1829 | * Handles applying a potion. |
1776 | * Handles applying a potion. |
… | |
… | |
1831 | int |
1778 | int |
1832 | apply_potion (object *op, object *tmp) |
1779 | apply_potion (object *op, object *tmp) |
1833 | { |
1780 | { |
1834 | int got_one = 0, i; |
1781 | int got_one = 0, i; |
1835 | object *force = 0; |
1782 | object *force = 0; |
1836 | |
|
|
1837 | object *floor = GET_MAP_OB (op->map, op->x, op->y); |
|
|
1838 | |
1783 | |
1839 | 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) |
1840 | { |
1785 | { |
1841 | 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!"); |
1842 | |
1787 | |
… | |
… | |
1996 | for (i = 0; i < NROFATTACKS; i++) |
1941 | for (i = 0; i < NROFATTACKS; i++) |
1997 | { |
1942 | { |
1998 | if (tmp->resist[i]) |
1943 | if (tmp->resist[i]) |
1999 | { |
1944 | { |
2000 | if (!force) |
1945 | if (!force) |
2001 | force = get_archetype (FORCE_NAME); |
1946 | force = archetype::get (FORCE_NAME); |
2002 | |
1947 | |
2003 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
1948 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
2004 | force->type = POTION_EFFECT; |
1949 | force->type = POTION_EFFECT; |
2005 | 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 */ |
2006 | } |
1951 | } |
… | |
… | |
2149 | case ARROW: |
2094 | case ARROW: |
2150 | /* 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 , |
2151 | * 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. |
2152 | * 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 |
2153 | * 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 |
2154 | * action, we avoid hits here |
2099 | * action, we avoid hits here |
2155 | */ |
2100 | */ |
2156 | if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) |
2101 | if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) |
2157 | && trap->owner != victim) |
2102 | && trap->owner != victim) |
2158 | hit_with_arrow (trap, victim); |
2103 | hit_with_arrow (trap, victim); |
2159 | break; |
2104 | break; |
… | |
… | |
2366 | if (failure <= -1 && failure > -15) |
2311 | if (failure <= -1 && failure > -15) |
2367 | { /* wonder */ |
2312 | { /* wonder */ |
2368 | object *tmp; |
2313 | object *tmp; |
2369 | |
2314 | |
2370 | op->failmsg ("Your spell warps!"); |
2315 | op->failmsg ("Your spell warps!"); |
2371 | tmp = get_archetype (SPELL_WONDER); |
2316 | tmp = archetype::get (SPELL_WONDER); |
2372 | cast_wonder (op, op, 0, tmp); |
2317 | cast_wonder (op, op, 0, tmp); |
2373 | tmp->destroy (); |
2318 | tmp->destroy (); |
2374 | } |
2319 | } |
2375 | else if (failure <= -15 && failure > -35) |
2320 | else if (failure <= -15 && failure > -35) |
2376 | { /* drain mana */ |
2321 | { /* drain mana */ |
… | |
… | |
2396 | op->failmsg ("The magic recoils on you!"); |
2341 | op->failmsg ("The magic recoils on you!"); |
2397 | blind_player (op, op, power); |
2342 | blind_player (op, op, power); |
2398 | } |
2343 | } |
2399 | else if (failure <= -80) |
2344 | else if (failure <= -80) |
2400 | { /* blast the immediate area */ |
2345 | { /* blast the immediate area */ |
2401 | object *tmp = get_archetype (LOOSE_MANA); |
2346 | object *tmp = archetype::get (LOOSE_MANA); |
2402 | cast_magic_storm (op, tmp, power); |
2347 | cast_magic_storm (op, tmp, power); |
2403 | op->failmsg ("You unleash uncontrolled mana!"); |
2348 | op->failmsg ("You unleash uncontrolled mana!"); |
2404 | tmp->destroy (); |
2349 | tmp->destroy (); |
2405 | } |
2350 | } |
2406 | } |
2351 | } |
… | |
… | |
3080 | * the selected object to "burn". -b.t. |
3025 | * the selected object to "burn". -b.t. |
3081 | */ |
3026 | */ |
3082 | static void |
3027 | static void |
3083 | apply_lighter (object *who, object *lighter) |
3028 | apply_lighter (object *who, object *lighter) |
3084 | { |
3029 | { |
3085 | int is_player_env = 0; |
|
|
3086 | |
|
|
3087 | if (object *item = who->mark ()) |
3030 | if (object *item = who->mark ()) |
3088 | { |
3031 | { |
3089 | if (!auto_apply_lighter (who, item, lighter)) |
3032 | if (!auto_apply_lighter (who, item, lighter)) |
3090 | return; |
3033 | return; |
3091 | |
3034 | |
… | |
… | |
3348 | |
3291 | |
3349 | strcpy (got, find); |
3292 | strcpy (got, find); |
3350 | got[len] = '\0'; |
3293 | got[len] = '\0'; |
3351 | |
3294 | |
3352 | /* Now create new item, remove used ones when required. */ |
3295 | /* Now create new item, remove used ones when required. */ |
3353 | new_item = get_archetype (got); |
3296 | new_item = archetype::get (got); |
3354 | if (!new_item) |
3297 | if (!new_item) |
3355 | { |
3298 | { |
3356 | 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)); |
3357 | return; |
3300 | return; |
3358 | } |
3301 | } |
… | |
… | |
3385 | * them in this function - they are passed to apply_special |
3328 | * them in this function - they are passed to apply_special |
3386 | */ |
3329 | */ |
3387 | static bool |
3330 | static bool |
3388 | manual_apply (object *who, object *op, int aflag) |
3331 | manual_apply (object *who, object *op, int aflag) |
3389 | { |
3332 | { |
3390 | op = op->head_ (); |
|
|
3391 | |
|
|
3392 | if (op->flag [FLAG_UNPAID] && !op->flag [FLAG_APPLIED]) |
|
|
3393 | { |
|
|
3394 | if (who->contr) |
|
|
3395 | { |
|
|
3396 | examine (who, op); |
|
|
3397 | //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove |
|
|
3398 | return 1; |
|
|
3399 | } |
|
|
3400 | else |
|
|
3401 | return 0; /* monsters just skip unpaid items */ |
|
|
3402 | } |
|
|
3403 | |
|
|
3404 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3333 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3405 | return RESULT_INT (0); |
3334 | return RESULT_INT (0); |
3406 | else if (apply_types_inv_only [op->type]) |
3335 | else if (apply_types_inv_only [op->type]) |
3407 | { |
3336 | { |
3408 | // special item, using slot system, needs to be in inv |
3337 | // special item, using slot system, needs to be in inv |
… | |
… | |
3438 | |
3367 | |
3439 | break; |
3368 | break; |
3440 | |
3369 | |
3441 | case EXIT: |
3370 | case EXIT: |
3442 | if (!EXIT_PATH (op)) |
3371 | if (!EXIT_PATH (op)) |
3443 | 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)); |
3444 | else |
3373 | else |
3445 | { |
3374 | { |
3446 | /* Don't display messages for random maps. */ |
3375 | /* Don't display messages for random maps. */ |
3447 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3376 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3448 | who->statusmsg (op->msg, NDI_NAVY); |
3377 | who->statusmsg (op->msg, NDI_NAVY); |
… | |
… | |
3554 | |
3483 | |
3555 | return 1; |
3484 | return 1; |
3556 | } |
3485 | } |
3557 | else |
3486 | else |
3558 | { |
3487 | { |
3559 | 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))); |
3560 | return 0; |
3489 | return 0; |
3561 | } |
3490 | } |
3562 | } |
3491 | } |
3563 | |
3492 | |
3564 | /** |
3493 | /** |
… | |
… | |
3627 | object::apply (object *ob, int aflags) |
3556 | object::apply (object *ob, int aflags) |
3628 | { |
3557 | { |
3629 | if (!ob) // simplifies a lot of callers |
3558 | if (!ob) // simplifies a lot of callers |
3630 | return true; |
3559 | return true; |
3631 | |
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 | |
3632 | if (contr) |
3575 | if (contr) |
3633 | { |
3576 | { |
3634 | if (!ob->env && (move_type & MOVE_FLYING)) |
3577 | if (!ob->env && (move_type & MOVE_FLYING)) |
3635 | { |
3578 | { |
3636 | /* player is flying and applying object not in inventory */ |
3579 | /* player is flying and applying object not in inventory */ |
… | |
… | |
3649 | bool want_apply = |
3592 | bool want_apply = |
3650 | aflags & AP_APPLY ? true |
3593 | aflags & AP_APPLY ? true |
3651 | : aflags & AP_UNAPPLY ? false |
3594 | : aflags & AP_UNAPPLY ? false |
3652 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3595 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3653 | |
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 | |
3654 | object_ptr *slot = 0; |
3607 | object_ptr *slot = 0; |
3655 | |
3608 | |
3656 | // detect the slot, if this is a player |
3609 | // detect the slot, if this is a player |
3657 | if (contr && !(aflags & AP_NO_SLOT)) |
3610 | if (contr && !(aflags & AP_NO_SLOT)) |
3658 | { |
3611 | { |
… | |
… | |
3663 | case WEAPON: |
3616 | case WEAPON: |
3664 | slot = &contr->combat_ob; |
3617 | slot = &contr->combat_ob; |
3665 | oslot = contr->ranged_ob; |
3618 | oslot = contr->ranged_ob; |
3666 | break; |
3619 | break; |
3667 | |
3620 | |
|
|
3621 | case RANGED: |
3668 | case BOW: |
3622 | case BOW: |
3669 | case RANGED: |
|
|
3670 | case SPELL: |
3623 | case SPELL: |
3671 | case WAND: |
3624 | case WAND: |
3672 | case ROD: |
3625 | case ROD: |
3673 | case HORN: |
3626 | case HORN: |
3674 | case BUILDER: |
3627 | case BUILDER: |
… | |
… | |
3676 | oslot = contr->combat_ob; |
3629 | oslot = contr->combat_ob; |
3677 | break; |
3630 | break; |
3678 | |
3631 | |
3679 | // oh, the humanity |
3632 | // oh, the humanity |
3680 | case SKILL: |
3633 | case SKILL: |
3681 | 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)) |
3682 | 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 | } |
3683 | |
3665 | |
3684 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3666 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3685 | break; |
3667 | break; |
3686 | |
3668 | |
3687 | if (skill_flags [ob->subtype] & SF_COMBAT) |
3669 | if (skill_flags [ob->subtype] & SF_COMBAT) |
… | |
… | |
3704 | // only one slot can be active |
3686 | // only one slot can be active |
3705 | if (want_apply) |
3687 | if (want_apply) |
3706 | { |
3688 | { |
3707 | // clear slot unless we are in it already |
3689 | // clear slot unless we are in it already |
3708 | if (*slot != ob) |
3690 | if (*slot != ob) |
3709 | apply (*slot, AP_UNAPPLY); |
3691 | if (!apply (*slot, AP_UNAPPLY)) |
|
|
3692 | return false; |
3710 | |
3693 | |
3711 | // unapply other slot, because we want to become active |
3694 | // unapply other slot, because we want to become active |
3712 | apply (oslot, AP_UNAPPLY); |
3695 | if (!apply (oslot, AP_UNAPPLY)) |
|
|
3696 | return false; |
3713 | } |
3697 | } |
3714 | |
3698 | |
3715 | // clear item from slot if applied |
3699 | // clear item from slot if applied |
3716 | if (!want_apply && current_weapon == ob) |
3700 | if (!want_apply && current_weapon == ob) |
3717 | current_weapon = 0; |
3701 | current_weapon = 0; |
… | |
… | |
3736 | * Generates shop floor's item, and treasures. |
3720 | * Generates shop floor's item, and treasures. |
3737 | */ |
3721 | */ |
3738 | int |
3722 | int |
3739 | auto_apply (object *op) |
3723 | auto_apply (object *op) |
3740 | { |
3724 | { |
3741 | object *tmp = NULL, *tmp2; |
3725 | object *tmp = NULL; |
3742 | int i; |
3726 | int i; |
3743 | |
3727 | |
3744 | op->clr_flag (FLAG_AUTO_APPLY); |
3728 | op->clr_flag (FLAG_AUTO_APPLY); |
3745 | |
3729 | |
3746 | switch (op->type) |
3730 | switch (op->type) |
… | |
… | |
3832 | while (invtmp->stats.hp-- > 0) |
3816 | while (invtmp->stats.hp-- > 0) |
3833 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3817 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3834 | |
3818 | |
3835 | invtmp->randomitems = NULL; |
3819 | invtmp->randomitems = NULL; |
3836 | } |
3820 | } |
3837 | else if (invtmp && invtmp->arch |
3821 | else if (invtmp->arch |
3838 | && 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 ()) |
3839 | { |
3824 | { |
3840 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3825 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3841 | /* Need to clear this so that we never try to create |
3826 | /* Need to clear this so that we never try to create |
3842 | * treasure again for this object |
3827 | * treasure again for this object |
3843 | */ |
3828 | */ |