… | |
… | |
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 | insert_ob_in_map_at (item, converter->map, converter, 0, converter->x, converter->y); |
697 | return 1; |
696 | return 1; |
698 | } |
697 | } |
… | |
… | |
732 | op->close_container (); |
731 | op->close_container (); |
733 | return 1; |
732 | return 1; |
734 | } |
733 | } |
735 | else if (!sack->env) |
734 | else if (!sack->env) |
736 | { |
735 | { |
737 | // active, but not ours: some other player has opened it |
736 | // active on floor, but not ours: some other player has opened it |
|
|
737 | // normally this only happens to dms standing on the same space. |
|
|
738 | // but it doesn't hurt to handle it. |
738 | op->failmsgf ("Somebody else is using the %s already.", query_name (sack)); |
739 | op->failmsgf ("Somebody else is using the %s already.", query_name (sack)); |
739 | return 1; |
740 | return 1; |
740 | } |
741 | } |
|
|
742 | } |
741 | |
743 | |
742 | // fall through to opening it (active in inv) |
744 | // it's locked? |
|
|
745 | if (sack->slaying) |
743 | } |
746 | { |
744 | else if (sack->env) |
747 | if (object *tmp = find_key (op, op, sack)) |
|
|
748 | { |
|
|
749 | op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp))); |
|
|
750 | } |
|
|
751 | else |
|
|
752 | { |
|
|
753 | sack->flag [FLAG_APPLIED] = false; // might be applied in inv, let the user close it |
|
|
754 | esrv_update_item (UPD_FLAGS, op, sack); |
|
|
755 | op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack))); |
|
|
756 | return 1; |
|
|
757 | } |
|
|
758 | } |
|
|
759 | |
|
|
760 | if (sack->env && !sack->flag [FLAG_APPLIED]) |
745 | { |
761 | { |
746 | // it is in our env, so activate it, do not open yet |
762 | // it is in our env, so activate it, do not open yet |
747 | op->close_container (); |
763 | op->close_container (); |
748 | sack->flag [FLAG_APPLIED] = 1; |
764 | sack->flag [FLAG_APPLIED] = true; |
749 | esrv_update_item (UPD_FLAGS, op, sack); |
765 | esrv_update_item (UPD_FLAGS, op, sack); |
750 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
766 | op->statusmsg (format ("You ready %s.", query_name (sack))); |
751 | return 1; |
|
|
752 | } |
|
|
753 | |
|
|
754 | // it's locked? |
|
|
755 | if (sack->slaying) |
|
|
756 | { |
767 | } |
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 |
768 | 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); |
769 | op->open_container (sack); |
767 | |
770 | |
768 | return 1; |
771 | return 1; |
769 | } |
772 | } |
770 | |
773 | |
771 | /** |
774 | /** |
… | |
… | |
1059 | who->flag [FLAG_READY_WEAPON] = false; |
1062 | who->flag [FLAG_READY_WEAPON] = false; |
1060 | |
1063 | |
1061 | // unapplying a weapon or skill tool should also unapply the skill it governs |
1064 | // 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 |
1065 | // but this is hard, as it shouldn't do so when the skill can |
1063 | // be used for other reasons |
1066 | // be used for other reasons |
|
|
1067 | //TODO: really? |
1064 | if (who->chosen_skill) |
1068 | if (who->chosen_skill) |
1065 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1069 | if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) |
1066 | unapply_special (who, op, 0); |
1070 | unapply_special (who, who->chosen_skill, 0); |
1067 | |
1071 | |
1068 | break; |
1072 | break; |
1069 | |
1073 | |
|
|
1074 | case RANGED: |
1070 | case BOW: |
1075 | case BOW: |
1071 | case WAND: |
1076 | case WAND: |
1072 | case ROD: |
1077 | case ROD: |
1073 | case HORN: |
1078 | case HORN: |
1074 | case RANGED: |
|
|
1075 | if (player *pl = who->contr) |
1079 | if (player *pl = who->contr) |
1076 | { |
1080 | { |
1077 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1081 | who->statusmsg (format ("You unready %s.", query_name (op))); |
1078 | change_abil (who, op); |
1082 | change_abil (who, op); |
1079 | } |
1083 | } |
… | |
… | |
1539 | //TODO: unapplying should unapply the skill, though |
1543 | //TODO: unapplying should unapply the skill, though |
1540 | op->set_flag (FLAG_APPLIED); |
1544 | op->set_flag (FLAG_APPLIED); |
1541 | break; |
1545 | break; |
1542 | |
1546 | |
1543 | case SKILL: |
1547 | 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) |
1548 | if (who->contr) |
1582 | if (op->invisible) |
1549 | if (op->invisible) |
1583 | who->statusmsg (format ("You can now use the %s skill.", &op->skill)); |
1550 | who->statusmsg (format ("You can now use the %s skill.", &op->skill)); |
1584 | else |
1551 | else |
1585 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1552 | who->statusmsg (format ("You ready %s.", query_name (op))); |
1586 | } |
|
|
1587 | |
1553 | |
1588 | who->set_flag (FLAG_READY_SKILL); |
1554 | who->set_flag (FLAG_READY_SKILL); |
1589 | op->set_flag (FLAG_APPLIED); |
1555 | op->set_flag (FLAG_APPLIED); |
1590 | change_abil (who, op); |
1556 | change_abil (who, op); |
1591 | break; |
1557 | break; |
… | |
… | |
1762 | |
1728 | |
1763 | /* if the player has a marked item, identify that if it needs to be |
1729 | /* 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. |
1730 | * identified. If it doesn't, then go through the player inventory. |
1765 | */ |
1731 | */ |
1766 | if (object *marked = pl->mark ()) |
1732 | if (object *marked = pl->mark ()) |
1767 | if (!marked->flag [FLAG_IDENTIFIED] && need_identify (marked)) |
1733 | if (!marked->flag [FLAG_IDENTIFIED] && marked->need_identify ()) |
1768 | { |
1734 | { |
1769 | if (operate_altar (altar, &money, pl)) |
1735 | if (operate_altar (altar, &money, pl)) |
1770 | { |
1736 | { |
1771 | identify (marked); |
1737 | identify (marked); |
1772 | |
1738 | |
… | |
… | |
1778 | } |
1744 | } |
1779 | } |
1745 | } |
1780 | |
1746 | |
1781 | for (object *id = pl->inv; id; id = id->below) |
1747 | for (object *id = pl->inv; id; id = id->below) |
1782 | { |
1748 | { |
1783 | if (!id->flag [FLAG_IDENTIFIED] && !id->invisible && need_identify (id)) |
1749 | if (!id->flag [FLAG_IDENTIFIED] && !id->invisible && id->need_identify ()) |
1784 | { |
1750 | { |
1785 | if (operate_altar (altar, &money, pl)) |
1751 | if (operate_altar (altar, &money, pl)) |
1786 | { |
1752 | { |
1787 | identify (id); |
1753 | identify (id); |
1788 | |
1754 | |
… | |
… | |
2060 | void |
2026 | void |
2061 | move_apply (object *trap, object *victim, object *originator) |
2027 | move_apply (object *trap, object *victim, object *originator) |
2062 | { |
2028 | { |
2063 | static int recursion_depth = 0; |
2029 | static int recursion_depth = 0; |
2064 | |
2030 | |
|
|
2031 | trap = trap->head_ (); |
|
|
2032 | |
2065 | /* Only exits affect DMs. */ |
2033 | /* Only exits affect DMs. */ |
2066 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2034 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2067 | return; |
2035 | return; |
2068 | |
2036 | |
2069 | /* move_apply() is the most likely candidate for causing unwanted and |
2037 | /* move_apply() is the most likely candidate for causing unwanted and |
2070 | * possibly unlimited recursion. |
2038 | * possibly unlimited recursion. |
2071 | */ |
2039 | */ |
|
|
2040 | |
2072 | /* The following was changed because it was causing perfectly correct |
2041 | /* The following was changed because it was causing perfectly correct |
2073 | * maps to fail. 1) it's not an error to recurse: |
2042 | * maps to fail. 1) it's not an error to recurse: |
2074 | * rune detonates, summoning monster. monster lands on nearby rune. |
2043 | * rune detonates, summoning monster. monster lands on nearby rune. |
2075 | * nearby rune detonates. This sort of recursion is expected and |
2044 | * nearby rune detonates. This sort of recursion is expected and |
2076 | * proper. This code was causing needless crashes. |
2045 | * 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); |
2050 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
2082 | return; |
2051 | return; |
2083 | } |
2052 | } |
2084 | |
2053 | |
2085 | recursion_depth++; |
2054 | recursion_depth++; |
2086 | if (trap->head) |
|
|
2087 | trap = trap->head; |
|
|
2088 | |
2055 | |
2089 | if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
2056 | if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
2090 | switch (trap->type) |
2057 | switch (trap->type) |
2091 | { |
2058 | { |
2092 | case PLAYERMOVER: |
2059 | case PLAYERMOVER: |
… | |
… | |
2102 | |
2069 | |
2103 | /* Just put in some sanity check. I think there is a bug in the |
2070 | /* 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 |
2071 | * above with some objects have zero speed, and thus the player |
2105 | * getting permanently paralyzed. |
2072 | * getting permanently paralyzed. |
2106 | */ |
2073 | */ |
2107 | if (victim->speed_left < -50.f) |
2074 | 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); */ |
2075 | /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */ |
2110 | } |
2076 | } |
2111 | break; |
2077 | break; |
2112 | |
2078 | |
2113 | case SPINNER: |
2079 | case SPINNER: |
… | |
… | |
3517 | check_improve_weapon (who, op); |
3483 | check_improve_weapon (who, op); |
3518 | break; |
3484 | break; |
3519 | |
3485 | |
3520 | case CLOCK: |
3486 | case CLOCK: |
3521 | { |
3487 | { |
3522 | char buf[MAX_BUF]; |
|
|
3523 | timeofday_t tod; |
3488 | timeofday_t tod; |
3524 | |
3489 | |
3525 | get_tod (&tod); |
3490 | get_tod (&tod); |
3526 | who->play_sound (sound_find ("sound_clock")); |
3491 | who->play_sound (sound_find ("sound_clock")); |
3527 | who->statusmsg (format ( |
3492 | who->statusmsg (format ( |
… | |
… | |
3660 | case WEAPON: |
3625 | case WEAPON: |
3661 | slot = &contr->combat_ob; |
3626 | slot = &contr->combat_ob; |
3662 | oslot = contr->ranged_ob; |
3627 | oslot = contr->ranged_ob; |
3663 | break; |
3628 | break; |
3664 | |
3629 | |
|
|
3630 | case RANGED: |
3665 | case BOW: |
3631 | case BOW: |
3666 | case RANGED: |
|
|
3667 | case SPELL: |
3632 | case SPELL: |
3668 | case WAND: |
3633 | case WAND: |
3669 | case ROD: |
3634 | case ROD: |
3670 | case HORN: |
3635 | case HORN: |
3671 | case BUILDER: |
3636 | case BUILDER: |
… | |
… | |
3673 | oslot = contr->combat_ob; |
3638 | oslot = contr->combat_ob; |
3674 | break; |
3639 | break; |
3675 | |
3640 | |
3676 | // oh, the humanity |
3641 | // oh, the humanity |
3677 | case SKILL: |
3642 | case SKILL: |
3678 | if (aflags & AP_NO_SLOT) |
3643 | // skill is used on it's own, as opposed to being a chosen_skill |
|
|
3644 | |
|
|
3645 | if (skill_flags [ob->subtype] & (SF_NEED_ITEM | SF_MANA)) |
3679 | break; |
3646 | { |
|
|
3647 | failmsgf ( |
|
|
3648 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3649 | "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. " |
|
|
3650 | "It cannot be used on its own.>", |
|
|
3651 | &ob->skill |
|
|
3652 | ); |
|
|
3653 | return 1; |
|
|
3654 | } |
|
|
3655 | |
|
|
3656 | if (skill_flags [ob->subtype] & SF_AUTARK |
|
|
3657 | || !(skill_flags [ob->subtype] & (SF_COMBAT | SF_RANGED))) |
|
|
3658 | { |
|
|
3659 | if (skill_flags [ob->subtype] & SF_USE) |
|
|
3660 | failmsgf ( |
|
|
3661 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3662 | "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>", |
|
|
3663 | &ob->skill, &ob->skill |
|
|
3664 | ); |
|
|
3665 | else |
|
|
3666 | failmsgf ( |
|
|
3667 | "You feel as if you wanted to do something funny, but you can't remember what. " |
|
|
3668 | "H<The %s skill cannot be readied or used, it is always active.>", |
|
|
3669 | &ob->skill |
|
|
3670 | ); |
|
|
3671 | |
|
|
3672 | return 1; |
|
|
3673 | } |
3680 | |
3674 | |
3681 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3675 | if (skill_flags [ob->subtype] & SF_NEED_ITEM) |
3682 | break; |
3676 | break; |
3683 | |
3677 | |
3684 | if (skill_flags [ob->subtype] & SF_COMBAT) |
3678 | if (skill_flags [ob->subtype] & SF_COMBAT) |