… | |
… | |
65 | |
65 | |
66 | static const struct apply_types_player_only : typeset |
66 | static const struct apply_types_player_only : typeset |
67 | { |
67 | { |
68 | apply_types_player_only () |
68 | apply_types_player_only () |
69 | { |
69 | { |
|
|
70 | set (TRANSPORT); |
70 | set (EXIT); |
71 | set (EXIT); |
71 | set (BOOK); |
72 | set (BOOK); |
72 | set (SIGN); |
73 | set (SIGN); |
73 | set (BOOK); |
74 | set (BOOK); |
74 | set (SKILLSCROLL); |
75 | set (SKILLSCROLL); |
… | |
… | |
250 | */ |
251 | */ |
251 | static int |
252 | static int |
252 | prepare_weapon (object *op, object *improver, object *weapon) |
253 | prepare_weapon (object *op, object *improver, object *weapon) |
253 | { |
254 | { |
254 | int sacrifice_count, i; |
255 | int sacrifice_count, i; |
255 | char buf[MAX_BUF]; |
|
|
256 | |
256 | |
257 | if (weapon->level != 0) |
257 | if (weapon->level != 0) |
258 | { |
258 | { |
259 | op->failmsg ("Weapon is already prepared!"); |
259 | op->failmsg ("Weapon is already prepared!"); |
260 | return 0; |
260 | return 0; |
… | |
… | |
289 | "Your sacrifice was accepted." |
289 | "Your sacrifice was accepted." |
290 | "Your *%s may be improved %d times.", |
290 | "Your *%s may be improved %d times.", |
291 | &weapon->name, weapon->level |
291 | &weapon->name, weapon->level |
292 | )); |
292 | )); |
293 | |
293 | |
294 | sprintf (buf, "%s's %s", &op->name, &weapon->name); |
294 | weapon->name = weapon->name_pl = format ("%s's %s", &op->name, &weapon->name); |
295 | weapon->name = weapon->name_pl = buf; |
|
|
296 | weapon->nrof = 0; /* prevents preparing n weapons in the same |
295 | weapon->nrof = 0; /* prevents preparing n weapons in the same |
297 | slot at once! */ |
296 | slot at once! */ |
298 | improver->decrease (); |
297 | improver->decrease (); |
299 | weapon->last_eat = 0; |
298 | weapon->last_eat = 0; |
300 | return 1; |
299 | return 1; |
… | |
… | |
688 | */ |
687 | */ |
689 | } |
688 | } |
690 | |
689 | |
691 | // 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 |
692 | // get an 'identified' flag so easily. |
691 | // get an 'identified' flag so easily. |
693 | if (need_identify (item)) |
692 | if (item->need_identify ()) |
694 | identify (item); |
693 | identify (item); |
695 | |
694 | |
696 | 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 | |
697 | return 1; |
697 | return 1; |
698 | } |
698 | } |
699 | |
699 | |
700 | /** |
700 | /** |
701 | * Handle apply on containers. |
701 | * Handle apply on containers. |
… | |
… | |
732 | op->close_container (); |
732 | op->close_container (); |
733 | return 1; |
733 | return 1; |
734 | } |
734 | } |
735 | else if (!sack->env) |
735 | else if (!sack->env) |
736 | { |
736 | { |
737 | // 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. |
738 | 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)); |
739 | return 1; |
741 | return 1; |
740 | } |
742 | } |
|
|
743 | } |
741 | |
744 | |
742 | // fall through to opening it (active in inv) |
745 | // it's locked? |
|
|
746 | if (sack->slaying) |
743 | } |
747 | { |
744 | 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]) |
745 | { |
762 | { |
746 | // 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 |
747 | op->close_container (); |
764 | op->close_container (); |
748 | sack->flag [FLAG_APPLIED] = 1; |
765 | sack->flag [FLAG_APPLIED] = true; |
749 | esrv_update_item (UPD_FLAGS, op, sack); |
766 | esrv_update_item (UPD_FLAGS, op, sack); |
750 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
767 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
751 | return 1; |
|
|
752 | } |
|
|
753 | |
|
|
754 | // it's locked? |
|
|
755 | if (sack->slaying) |
|
|
756 | { |
768 | } |
757 | if (object *tmp = find_key (op, op, sack)) |
|
|
758 | op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp))); |
|
|
759 | else |
769 | else |
760 | { |
|
|
761 | op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack))); |
|
|
762 | return 1; |
|
|
763 | } |
|
|
764 | } |
|
|
765 | |
|
|
766 | op->open_container (sack); |
770 | op->open_container (sack); |
767 | |
771 | |
768 | return 1; |
772 | return 1; |
769 | } |
773 | } |
770 | |
774 | |
771 | /** |
775 | /** |
… | |
… | |
1059 | who->flag [FLAG_READY_WEAPON] = false; |
1063 | who->flag [FLAG_READY_WEAPON] = false; |
1060 | |
1064 | |
1061 | // 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 |
1062 | // 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 |
1063 | // be used for other reasons |
1067 | // be used for other reasons |
|
|
1068 | //TODO: really? |
1064 | if (who->chosen_skill) |
1069 | if (who->chosen_skill) |
1065 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1070 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1066 | unapply_special (who, op, 0); |
1071 | unapply_special (who, who->chosen_skill, 0); |
1067 | |
1072 | |
1068 | break; |
1073 | break; |
1069 | |
1074 | |
|
|
1075 | case RANGED: |
1070 | case BOW: |
1076 | case BOW: |
1071 | case WAND: |
1077 | case WAND: |
1072 | case ROD: |
1078 | case ROD: |
1073 | case HORN: |
1079 | case HORN: |
1074 | case RANGED: |
|
|
1075 | if (player *pl = who->contr) |
1080 | if (player *pl = who->contr) |
1076 | { |
1081 | { |
1077 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1082 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1078 | change_abil (who, op); |
1083 | change_abil (who, op); |
1079 | } |
1084 | } |
… | |
… | |
1390 | apply_special (object *who, object *op, int aflags) |
1395 | apply_special (object *who, object *op, int aflags) |
1391 | { |
1396 | { |
1392 | int basic_flag = aflags & AP_MODE; |
1397 | int basic_flag = aflags & AP_MODE; |
1393 | object *tmp, *tmp2, *skop = NULL; |
1398 | object *tmp, *tmp2, *skop = NULL; |
1394 | |
1399 | |
1395 | if (who == NULL) |
|
|
1396 | { |
|
|
1397 | LOG (llevError, "apply_special() from object without environment.\n"); |
|
|
1398 | return 1; |
|
|
1399 | } |
|
|
1400 | |
|
|
1401 | //TODO: remove these when apply_special is no longer exposed |
|
|
1402 | if (op->env != who) |
|
|
1403 | return 1; /* op is not in inventory */ |
|
|
1404 | |
|
|
1405 | /* trying to unequip op */ |
1400 | /* trying to unequip op */ |
1406 | if (op->flag [FLAG_APPLIED]) |
1401 | if (op->flag [FLAG_APPLIED]) |
1407 | { |
1402 | { |
1408 | /* always apply, so no reason to unapply */ |
1403 | /* always apply, so no reason to unapply */ |
1409 | if (basic_flag == AP_APPLY) |
1404 | if (basic_flag == AP_APPLY) |
1410 | return 0; |
1405 | return 0; |
1411 | |
|
|
1412 | if (!(aflags & AP_IGNORE_CURSE) && (op->flag [FLAG_CURSED] || op->flag [FLAG_DAMNED])) |
|
|
1413 | { |
|
|
1414 | who->failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, query_name (op)); |
|
|
1415 | return 1; |
|
|
1416 | } |
|
|
1417 | |
1406 | |
1418 | return unapply_special (who, op, aflags); |
1407 | return unapply_special (who, op, aflags); |
1419 | } |
1408 | } |
1420 | else if (basic_flag == AP_UNAPPLY) |
1409 | else if (basic_flag == AP_UNAPPLY) |
1421 | return 0; |
1410 | return 0; |
… | |
… | |
1539 | //TODO: unapplying should unapply the skill, though |
1528 | //TODO: unapplying should unapply the skill, though |
1540 | op->set_flag (FLAG_APPLIED); |
1529 | op->set_flag (FLAG_APPLIED); |
1541 | break; |
1530 | break; |
1542 | |
1531 | |
1543 | case SKILL: |
1532 | case SKILL: |
1544 | if (!(aflags & AP_NO_SLOT)) |
|
|
1545 | { |
|
|
1546 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
1547 | |
|
|
1548 | if (skill_flags [op->subtype] & (SF_NEED_ITEM | SF_MANA)) |
|
|
1549 | { |
|
|
1550 | who->failmsgf ( |
|
|
1551 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1552 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
1553 | "It cannot be used on its own.>", |
|
|
1554 | &op->skill |
|
|
1555 | ); |
|
|
1556 | if (tmp) who->insert (tmp); |
|
|
1557 | return 1; |
|
|
1558 | } |
|
|
1559 | |
|
|
1560 | if (skill_flags [op->subtype] & SF_AUTARK |
|
|
1561 | || !(skill_flags [op->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
1562 | { |
|
|
1563 | if (skill_flags [op->subtype] & SF_USE) |
|
|
1564 | who->failmsgf ( |
|
|
1565 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1566 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
1567 | &op->skill, &op->skill |
|
|
1568 | ); |
|
|
1569 | else |
|
|
1570 | who->failmsgf ( |
|
|
1571 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
1572 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
1573 | &op->skill |
|
|
1574 | ); |
|
|
1575 | |
|
|
1576 | if (tmp) who->insert (tmp); |
|
|
1577 | |
|
|
1578 | return 1; |
|
|
1579 | } |
|
|
1580 | |
|
|
1581 | if (who->contr) |
1533 | if (who->contr) |
1582 | if (op->invisible) |
1534 | if (op->invisible) |
1583 | 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)); |
1584 | else |
1536 | else |
1585 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1537 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1586 | } |
|
|
1587 | |
1538 | |
1588 | who->set_flag (FLAG_READY_SKILL); |
1539 | who->set_flag (FLAG_READY_SKILL); |
1589 | op->set_flag (FLAG_APPLIED); |
1540 | op->set_flag (FLAG_APPLIED); |
1590 | change_abil (who, op); |
1541 | change_abil (who, op); |
1591 | break; |
1542 | break; |
… | |
… | |
1762 | |
1713 | |
1763 | /* if the player has a marked item, identify that if it needs to be |
1714 | /* if the player has a marked item, identify that if it needs to be |
1764 | * identified. If it doesn't, then go through the player inventory. |
1715 | * identified. If it doesn't, then go through the player inventory. |
1765 | */ |
1716 | */ |
1766 | if (object *marked = pl->mark ()) |
1717 | if (object *marked = pl->mark ()) |
1767 | if (!marked->flag [FLAG_IDENTIFIED] && need_identify (marked)) |
1718 | if (!marked->flag [FLAG_IDENTIFIED] && marked->need_identify ()) |
1768 | { |
1719 | { |
1769 | if (operate_altar (altar, &money, pl)) |
1720 | if (operate_altar (altar, &money, pl)) |
1770 | { |
1721 | { |
1771 | identify (marked); |
1722 | identify (marked); |
1772 | |
1723 | |
… | |
… | |
1778 | } |
1729 | } |
1779 | } |
1730 | } |
1780 | |
1731 | |
1781 | for (object *id = pl->inv; id; id = id->below) |
1732 | for (object *id = pl->inv; id; id = id->below) |
1782 | { |
1733 | { |
1783 | if (!id->flag [FLAG_IDENTIFIED] && !id->invisible && need_identify (id)) |
1734 | if (!id->flag [FLAG_IDENTIFIED] && !id->invisible && id->need_identify ()) |
1784 | { |
1735 | { |
1785 | if (operate_altar (altar, &money, pl)) |
1736 | if (operate_altar (altar, &money, pl)) |
1786 | { |
1737 | { |
1787 | identify (id); |
1738 | identify (id); |
1788 | |
1739 | |
… | |
… | |
2060 | void |
2011 | void |
2061 | move_apply (object *trap, object *victim, object *originator) |
2012 | move_apply (object *trap, object *victim, object *originator) |
2062 | { |
2013 | { |
2063 | static int recursion_depth = 0; |
2014 | static int recursion_depth = 0; |
2064 | |
2015 | |
|
|
2016 | trap = trap->head_ (); |
|
|
2017 | |
2065 | /* Only exits affect DMs. */ |
2018 | /* Only exits affect DMs. */ |
2066 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2019 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2067 | return; |
2020 | return; |
2068 | |
2021 | |
2069 | /* move_apply() is the most likely candidate for causing unwanted and |
2022 | /* move_apply() is the most likely candidate for causing unwanted and |
2070 | * possibly unlimited recursion. |
2023 | * possibly unlimited recursion. |
2071 | */ |
2024 | */ |
|
|
2025 | |
2072 | /* The following was changed because it was causing perfectly correct |
2026 | /* The following was changed because it was causing perfectly correct |
2073 | * maps to fail. 1) it's not an error to recurse: |
2027 | * maps to fail. 1) it's not an error to recurse: |
2074 | * rune detonates, summoning monster. monster lands on nearby rune. |
2028 | * rune detonates, summoning monster. monster lands on nearby rune. |
2075 | * nearby rune detonates. This sort of recursion is expected and |
2029 | * nearby rune detonates. This sort of recursion is expected and |
2076 | * proper. This code was causing needless crashes. |
2030 | * proper. This code was causing needless crashes. |
… | |
… | |
2081 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
2035 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
2082 | return; |
2036 | return; |
2083 | } |
2037 | } |
2084 | |
2038 | |
2085 | recursion_depth++; |
2039 | recursion_depth++; |
2086 | if (trap->head) |
|
|
2087 | trap = trap->head; |
|
|
2088 | |
2040 | |
2089 | if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
2041 | if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
2090 | switch (trap->type) |
2042 | switch (trap->type) |
2091 | { |
2043 | { |
2092 | case PLAYERMOVER: |
2044 | case PLAYERMOVER: |
… | |
… | |
2102 | |
2054 | |
2103 | /* Just put in some sanity check. I think there is a bug in the |
2055 | /* Just put in some sanity check. I think there is a bug in the |
2104 | * above with some objects have zero speed, and thus the player |
2056 | * above with some objects have zero speed, and thus the player |
2105 | * getting permanently paralyzed. |
2057 | * getting permanently paralyzed. |
2106 | */ |
2058 | */ |
2107 | if (victim->speed_left < -50.f) |
2059 | victim->speed_left = max (-50.f, victim->speed_left); |
2108 | victim->speed_left = -50.f; |
|
|
2109 | /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */ |
2060 | /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */ |
2110 | } |
2061 | } |
2111 | break; |
2062 | break; |
2112 | |
2063 | |
2113 | case SPINNER: |
2064 | case SPINNER: |
… | |
… | |
3381 | * them in this function - they are passed to apply_special |
3332 | * them in this function - they are passed to apply_special |
3382 | */ |
3333 | */ |
3383 | static bool |
3334 | static bool |
3384 | manual_apply (object *who, object *op, int aflag) |
3335 | manual_apply (object *who, object *op, int aflag) |
3385 | { |
3336 | { |
3386 | op = op->head_ (); |
|
|
3387 | |
|
|
3388 | if (op->flag [FLAG_UNPAID] && !op->flag [FLAG_APPLIED]) |
|
|
3389 | { |
|
|
3390 | if (who->contr) |
|
|
3391 | { |
|
|
3392 | examine (who, op); |
|
|
3393 | //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove |
|
|
3394 | return 1; |
|
|
3395 | } |
|
|
3396 | else |
|
|
3397 | return 0; /* monsters just skip unpaid items */ |
|
|
3398 | } |
|
|
3399 | |
|
|
3400 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3337 | if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) |
3401 | return RESULT_INT (0); |
3338 | return RESULT_INT (0); |
3402 | else if (apply_types_inv_only [op->type]) |
3339 | else if (apply_types_inv_only [op->type]) |
3403 | { |
3340 | { |
3404 | // special item, using slot system, needs to be in inv |
3341 | // special item, using slot system, needs to be in inv |
… | |
… | |
3434 | |
3371 | |
3435 | break; |
3372 | break; |
3436 | |
3373 | |
3437 | case EXIT: |
3374 | case EXIT: |
3438 | if (!EXIT_PATH (op)) |
3375 | if (!EXIT_PATH (op)) |
3439 | who->failmsgf ("The %s is closed. H<And will stay closed, until somebody fires up the map editor and adds it.>", query_name (op)); |
3376 | 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)); |
3440 | else |
3377 | else |
3441 | { |
3378 | { |
3442 | /* Don't display messages for random maps. */ |
3379 | /* Don't display messages for random maps. */ |
3443 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3380 | if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) |
3444 | who->statusmsg (op->msg, NDI_NAVY); |
3381 | who->statusmsg (op->msg, NDI_NAVY); |
… | |
… | |
3517 | check_improve_weapon (who, op); |
3454 | check_improve_weapon (who, op); |
3518 | break; |
3455 | break; |
3519 | |
3456 | |
3520 | case CLOCK: |
3457 | case CLOCK: |
3521 | { |
3458 | { |
3522 | char buf[MAX_BUF]; |
|
|
3523 | timeofday_t tod; |
3459 | timeofday_t tod; |
3524 | |
3460 | |
3525 | get_tod (&tod); |
3461 | get_tod (&tod); |
3526 | who->play_sound (sound_find ("sound_clock")); |
3462 | who->play_sound (sound_find ("sound_clock")); |
3527 | who->statusmsg (format ( |
3463 | who->statusmsg (format ( |
… | |
… | |
3624 | object::apply (object *ob, int aflags) |
3560 | object::apply (object *ob, int aflags) |
3625 | { |
3561 | { |
3626 | if (!ob) // simplifies a lot of callers |
3562 | if (!ob) // simplifies a lot of callers |
3627 | return true; |
3563 | return true; |
3628 | |
3564 | |
|
|
3565 | ob = ob->head_ (); |
|
|
3566 | |
|
|
3567 | if (ob->flag [FLAG_UNPAID] && !ob->flag [FLAG_APPLIED]) |
|
|
3568 | { |
|
|
3569 | if (contr) |
|
|
3570 | { |
|
|
3571 | examine (this, ob); |
|
|
3572 | //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove |
|
|
3573 | return 1; |
|
|
3574 | } |
|
|
3575 | else |
|
|
3576 | return 0; /* monsters just skip unpaid items */ |
|
|
3577 | } |
|
|
3578 | |
3629 | if (contr) |
3579 | if (contr) |
3630 | { |
3580 | { |
3631 | if (!ob->env && (move_type & MOVE_FLYING)) |
3581 | if (!ob->env && (move_type & MOVE_FLYING)) |
3632 | { |
3582 | { |
3633 | /* player is flying and applying object not in inventory */ |
3583 | /* player is flying and applying object not in inventory */ |
… | |
… | |
3646 | bool want_apply = |
3596 | bool want_apply = |
3647 | aflags & AP_APPLY ? true |
3597 | aflags & AP_APPLY ? true |
3648 | : aflags & AP_UNAPPLY ? false |
3598 | : aflags & AP_UNAPPLY ? false |
3649 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3599 | : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE |
3650 | |
3600 | |
|
|
3601 | // cannot unapply cursed items |
|
|
3602 | if (!want_apply |
|
|
3603 | && (ob->flag [FLAG_CURSED] || ob->flag [FLAG_DAMNED]) |
|
|
3604 | && ob->flag [FLAG_APPLIED] |
|
|
3605 | && !(aflags & AP_IGNORE_CURSE)) |
|
|
3606 | { |
|
|
3607 | failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, ob->query_name ()); |
|
|
3608 | return 0; |
|
|
3609 | } |
|
|
3610 | |
3651 | object_ptr *slot = 0; |
3611 | object_ptr *slot = 0; |
3652 | |
3612 | |
3653 | // detect the slot, if this is a player |
3613 | // detect the slot, if this is a player |
3654 | if (contr && !(aflags & AP_NO_SLOT)) |
3614 | if (contr && !(aflags & AP_NO_SLOT)) |
3655 | { |
3615 | { |
… | |
… | |
3660 | case WEAPON: |
3620 | case WEAPON: |
3661 | slot = &contr->combat_ob; |
3621 | slot = &contr->combat_ob; |
3662 | oslot = contr->ranged_ob; |
3622 | oslot = contr->ranged_ob; |
3663 | break; |
3623 | break; |
3664 | |
3624 | |
|
|
3625 | case RANGED: |
3665 | case BOW: |
3626 | case BOW: |
3666 | case RANGED: |
|
|
3667 | case SPELL: |
3627 | case SPELL: |
3668 | case WAND: |
3628 | case WAND: |
3669 | case ROD: |
3629 | case ROD: |
3670 | case HORN: |
3630 | case HORN: |
3671 | case BUILDER: |
3631 | case BUILDER: |
… | |
… | |
3673 | oslot = contr->combat_ob; |
3633 | oslot = contr->combat_ob; |
3674 | break; |
3634 | break; |
3675 | |
3635 | |
3676 | // oh, the humanity |
3636 | // oh, the humanity |
3677 | case SKILL: |
3637 | case SKILL: |
3678 | if (aflags & AP_NO_SLOT) |
3638 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
3639 | |
|
|
3640 | if (skill_flags [ob->subtype] & (SF_NEED_ITEM | SF_MANA)) |
3679 | break; |
3641 | { |
|
|
3642 | failmsgf ( |
|
|
3643 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3644 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
3645 | "It cannot be used on its own.>", |
|
|
3646 | &ob->skill |
|
|
3647 | ); |
|
|
3648 | return 1; |
|
|
3649 | } |
|
|
3650 | |
|
|
3651 | if (skill_flags [ob->subtype] & SF_AUTARK |
|
|
3652 | || !(skill_flags [ob->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
3653 | { |
|
|
3654 | if (skill_flags [ob->subtype] & SF_USE) |
|
|
3655 | failmsgf ( |
|
|
3656 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3657 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
3658 | &ob->skill, &ob->skill |
|
|
3659 | ); |
|
|
3660 | else |
|
|
3661 | failmsgf ( |
|
|
3662 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3663 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
3664 | &ob->skill |
|
|
3665 | ); |
|
|
3666 | |
|
|
3667 | return 1; |
|
|
3668 | } |
3680 | |
3669 | |
3681 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3670 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3682 | break; |
3671 | break; |
3683 | |
3672 | |
3684 | if (skill_flags [ob->subtype] & SF_COMBAT) |
3673 | if (skill_flags [ob->subtype] & SF_COMBAT) |
… | |
… | |
3701 | // only one slot can be active |
3690 | // only one slot can be active |
3702 | if (want_apply) |
3691 | if (want_apply) |
3703 | { |
3692 | { |
3704 | // clear slot unless we are in it already |
3693 | // clear slot unless we are in it already |
3705 | if (*slot != ob) |
3694 | if (*slot != ob) |
3706 | apply (*slot, AP_UNAPPLY); |
3695 | if (!apply (*slot, AP_UNAPPLY)) |
|
|
3696 | return false; |
3707 | |
3697 | |
3708 | // unapply other slot, because we want to become active |
3698 | // unapply other slot, because we want to become active |
3709 | apply (oslot, AP_UNAPPLY); |
3699 | if (!apply (oslot, AP_UNAPPLY)) |
|
|
3700 | return false; |
3710 | } |
3701 | } |
3711 | |
3702 | |
3712 | // clear item from slot if applied |
3703 | // clear item from slot if applied |
3713 | if (!want_apply && current_weapon == ob) |
3704 | if (!want_apply && current_weapon == ob) |
3714 | current_weapon = 0; |
3705 | current_weapon = 0; |