ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/apply.C
(Generate patch)

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.257 by root, Thu Apr 15 00:36:51 2010 UTC vs.
Revision 1.278 by root, Thu Nov 17 04:49:22 2016 UTC

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
65 65
66static const struct apply_types_player_only : typeset 66static 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 */
251static int 252static int
252prepare_weapon (object *op, object *improver, object *weapon) 253prepare_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 }
1388 1393
1389static bool 1394static bool
1390apply_special (object *who, object *op, int aflags) 1395apply_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, *skop = NULL;
1394
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 1399
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
1815 * matching item. 1766 * matching item.
1816 **/ 1767 **/
1817void 1768void
1818handle_apply_yield (object *tmp) 1769handle_apply_yield (object *tmp)
1819{ 1770{
1820 if (shstr_tmp yield = tmp->kv (shstr_on_use_yield)) 1771 if (shstr_tmp yield = tmp->kv [shstr_on_use_yield])
1821 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); 1772 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR);
1822} 1773}
1823 1774
1824/** 1775/**
1825 * Handles applying a potion. 1776 * Handles applying a potion.
1827int 1778int
1828apply_potion (object *op, object *tmp) 1779apply_potion (object *op, object *tmp)
1829{ 1780{
1830 int got_one = 0, i; 1781 int got_one = 0, i;
1831 object *force = 0; 1782 object *force = 0;
1832
1833 object *floor = GET_MAP_OB (op->map, op->x, op->y);
1834 1783
1835 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)
1836 { 1785 {
1837 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!");
1838 1787
1992 for (i = 0; i < NROFATTACKS; i++) 1941 for (i = 0; i < NROFATTACKS; i++)
1993 { 1942 {
1994 if (tmp->resist[i]) 1943 if (tmp->resist[i])
1995 { 1944 {
1996 if (!force) 1945 if (!force)
1997 force = get_archetype (FORCE_NAME); 1946 force = archetype::get (FORCE_NAME);
1998 1947
1999 memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); 1948 memcpy (force->resist, tmp->resist, sizeof (tmp->resist));
2000 force->type = POTION_EFFECT; 1949 force->type = POTION_EFFECT;
2001 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 */
2002 } 1951 }
2060void 2009void
2061move_apply (object *trap, object *victim, object *originator) 2010move_apply (object *trap, object *victim, object *originator)
2062{ 2011{
2063 static int recursion_depth = 0; 2012 static int recursion_depth = 0;
2064 2013
2014 trap = trap->head_ ();
2015
2065 /* Only exits affect DMs. */ 2016 /* Only exits affect DMs. */
2066 if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) 2017 if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN)
2067 return; 2018 return;
2068 2019
2069 /* move_apply() is the most likely candidate for causing unwanted and 2020 /* move_apply() is the most likely candidate for causing unwanted and
2070 * possibly unlimited recursion. 2021 * possibly unlimited recursion.
2071 */ 2022 */
2023
2072 /* The following was changed because it was causing perfectly correct 2024 /* The following was changed because it was causing perfectly correct
2073 * maps to fail. 1) it's not an error to recurse: 2025 * maps to fail. 1) it's not an error to recurse:
2074 * rune detonates, summoning monster. monster lands on nearby rune. 2026 * rune detonates, summoning monster. monster lands on nearby rune.
2075 * nearby rune detonates. This sort of recursion is expected and 2027 * nearby rune detonates. This sort of recursion is expected and
2076 * proper. This code was causing needless crashes. 2028 * 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); 2033 "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name);
2082 return; 2034 return;
2083 } 2035 }
2084 2036
2085 recursion_depth++; 2037 recursion_depth++;
2086 if (trap->head)
2087 trap = trap->head;
2088 2038
2089 if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) 2039 if (!INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
2090 switch (trap->type) 2040 switch (trap->type)
2091 { 2041 {
2092 case PLAYERMOVER: 2042 case PLAYERMOVER:
2102 2052
2103 /* Just put in some sanity check. I think there is a bug in the 2053 /* 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 2054 * above with some objects have zero speed, and thus the player
2105 * getting permanently paralyzed. 2055 * getting permanently paralyzed.
2106 */ 2056 */
2107 if (victim->speed_left < -50.f) 2057 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); */ 2058 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
2110 } 2059 }
2111 break; 2060 break;
2112 2061
2113 case SPINNER: 2062 case SPINNER:
2145 case ARROW: 2094 case ARROW:
2146 /* 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 ,
2147 * 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.
2148 * 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
2149 * 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
2150 * action, we avoid hits here 2099 * action, we avoid hits here
2151 */ 2100 */
2152 if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) 2101 if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ())
2153 && trap->owner != victim) 2102 && trap->owner != victim)
2154 hit_with_arrow (trap, victim); 2103 hit_with_arrow (trap, victim);
2155 break; 2104 break;
2362 if (failure <= -1 && failure > -15) 2311 if (failure <= -1 && failure > -15)
2363 { /* wonder */ 2312 { /* wonder */
2364 object *tmp; 2313 object *tmp;
2365 2314
2366 op->failmsg ("Your spell warps!"); 2315 op->failmsg ("Your spell warps!");
2367 tmp = get_archetype (SPELL_WONDER); 2316 tmp = archetype::get (SPELL_WONDER);
2368 cast_wonder (op, op, 0, tmp); 2317 cast_wonder (op, op, 0, tmp);
2369 tmp->destroy (); 2318 tmp->destroy ();
2370 } 2319 }
2371 else if (failure <= -15 && failure > -35) 2320 else if (failure <= -15 && failure > -35)
2372 { /* drain mana */ 2321 { /* drain mana */
2392 op->failmsg ("The magic recoils on you!"); 2341 op->failmsg ("The magic recoils on you!");
2393 blind_player (op, op, power); 2342 blind_player (op, op, power);
2394 } 2343 }
2395 else if (failure <= -80) 2344 else if (failure <= -80)
2396 { /* blast the immediate area */ 2345 { /* blast the immediate area */
2397 object *tmp = get_archetype (LOOSE_MANA); 2346 object *tmp = archetype::get (LOOSE_MANA);
2398 cast_magic_storm (op, tmp, power); 2347 cast_magic_storm (op, tmp, power);
2399 op->failmsg ("You unleash uncontrolled mana!"); 2348 op->failmsg ("You unleash uncontrolled mana!");
2400 tmp->destroy (); 2349 tmp->destroy ();
2401 } 2350 }
2402 } 2351 }
3076 * the selected object to "burn". -b.t. 3025 * the selected object to "burn". -b.t.
3077 */ 3026 */
3078static void 3027static void
3079apply_lighter (object *who, object *lighter) 3028apply_lighter (object *who, object *lighter)
3080{ 3029{
3081 int is_player_env = 0;
3082
3083 if (object *item = who->mark ()) 3030 if (object *item = who->mark ())
3084 { 3031 {
3085 if (!auto_apply_lighter (who, item, lighter)) 3032 if (!auto_apply_lighter (who, item, lighter))
3086 return; 3033 return;
3087 3034
3344 3291
3345 strcpy (got, find); 3292 strcpy (got, find);
3346 got[len] = '\0'; 3293 got[len] = '\0';
3347 3294
3348 /* Now create new item, remove used ones when required. */ 3295 /* Now create new item, remove used ones when required. */
3349 new_item = get_archetype (got); 3296 new_item = archetype::get (got);
3350 if (!new_item) 3297 if (!new_item)
3351 { 3298 {
3352 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));
3353 return; 3300 return;
3354 } 3301 }
3381 * them in this function - they are passed to apply_special 3328 * them in this function - they are passed to apply_special
3382 */ 3329 */
3383static bool 3330static bool
3384manual_apply (object *who, object *op, int aflag) 3331manual_apply (object *who, object *op, int aflag)
3385{ 3332{
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))) 3333 if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who)))
3401 return RESULT_INT (0); 3334 return RESULT_INT (0);
3402 else if (apply_types_inv_only [op->type]) 3335 else if (apply_types_inv_only [op->type])
3403 { 3336 {
3404 // special item, using slot system, needs to be in inv 3337 // special item, using slot system, needs to be in inv
3434 3367
3435 break; 3368 break;
3436 3369
3437 case EXIT: 3370 case EXIT:
3438 if (!EXIT_PATH (op)) 3371 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)); 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));
3440 else 3373 else
3441 { 3374 {
3442 /* Don't display messages for random maps. */ 3375 /* Don't display messages for random maps. */
3443 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) 3376 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit)
3444 who->statusmsg (op->msg, NDI_NAVY); 3377 who->statusmsg (op->msg, NDI_NAVY);
3517 check_improve_weapon (who, op); 3450 check_improve_weapon (who, op);
3518 break; 3451 break;
3519 3452
3520 case CLOCK: 3453 case CLOCK:
3521 { 3454 {
3522 char buf[MAX_BUF];
3523 timeofday_t tod; 3455 timeofday_t tod;
3524 3456
3525 get_tod (&tod); 3457 get_tod (&tod);
3526 who->play_sound (sound_find ("sound_clock")); 3458 who->play_sound (sound_find ("sound_clock"));
3527 who->statusmsg (format ( 3459 who->statusmsg (format (
3551 3483
3552 return 1; 3484 return 1;
3553 } 3485 }
3554 else 3486 else
3555 { 3487 {
3556 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)));
3557 return 0; 3489 return 0;
3558 } 3490 }
3559} 3491}
3560 3492
3561/** 3493/**
3624object::apply (object *ob, int aflags) 3556object::apply (object *ob, int aflags)
3625{ 3557{
3626 if (!ob) // simplifies a lot of callers 3558 if (!ob) // simplifies a lot of callers
3627 return true; 3559 return true;
3628 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
3629 if (contr) 3575 if (contr)
3630 { 3576 {
3631 if (!ob->env && (move_type & MOVE_FLYING)) 3577 if (!ob->env && (move_type & MOVE_FLYING))
3632 { 3578 {
3633 /* player is flying and applying object not in inventory */ 3579 /* player is flying and applying object not in inventory */
3646 bool want_apply = 3592 bool want_apply =
3647 aflags & AP_APPLY ? true 3593 aflags & AP_APPLY ? true
3648 : aflags & AP_UNAPPLY ? false 3594 : aflags & AP_UNAPPLY ? false
3649 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE 3595 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE
3650 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
3651 object_ptr *slot = 0; 3607 object_ptr *slot = 0;
3652 3608
3653 // detect the slot, if this is a player 3609 // detect the slot, if this is a player
3654 if (contr && !(aflags & AP_NO_SLOT)) 3610 if (contr && !(aflags & AP_NO_SLOT))
3655 { 3611 {
3660 case WEAPON: 3616 case WEAPON:
3661 slot = &contr->combat_ob; 3617 slot = &contr->combat_ob;
3662 oslot = contr->ranged_ob; 3618 oslot = contr->ranged_ob;
3663 break; 3619 break;
3664 3620
3621 case RANGED:
3665 case BOW: 3622 case BOW:
3666 case RANGED:
3667 case SPELL: 3623 case SPELL:
3668 case WAND: 3624 case WAND:
3669 case ROD: 3625 case ROD:
3670 case HORN: 3626 case HORN:
3671 case BUILDER: 3627 case BUILDER:
3673 oslot = contr->combat_ob; 3629 oslot = contr->combat_ob;
3674 break; 3630 break;
3675 3631
3676 // oh, the humanity 3632 // oh, the humanity
3677 case SKILL: 3633 case SKILL:
3678 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))
3679 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 }
3680 3665
3681 if (skill_flags [ob->subtype] & SF_NEED_ITEM) 3666 if (skill_flags [ob->subtype] & SF_NEED_ITEM)
3682 break; 3667 break;
3683 3668
3684 if (skill_flags [ob->subtype] & SF_COMBAT) 3669 if (skill_flags [ob->subtype] & SF_COMBAT)
3701 // only one slot can be active 3686 // only one slot can be active
3702 if (want_apply) 3687 if (want_apply)
3703 { 3688 {
3704 // clear slot unless we are in it already 3689 // clear slot unless we are in it already
3705 if (*slot != ob) 3690 if (*slot != ob)
3706 apply (*slot, AP_UNAPPLY); 3691 if (!apply (*slot, AP_UNAPPLY))
3692 return false;
3707 3693
3708 // unapply other slot, because we want to become active 3694 // unapply other slot, because we want to become active
3709 apply (oslot, AP_UNAPPLY); 3695 if (!apply (oslot, AP_UNAPPLY))
3696 return false;
3710 } 3697 }
3711 3698
3712 // clear item from slot if applied 3699 // clear item from slot if applied
3713 if (!want_apply && current_weapon == ob) 3700 if (!want_apply && current_weapon == ob)
3714 current_weapon = 0; 3701 current_weapon = 0;
3733 * Generates shop floor's item, and treasures. 3720 * Generates shop floor's item, and treasures.
3734 */ 3721 */
3735int 3722int
3736auto_apply (object *op) 3723auto_apply (object *op)
3737{ 3724{
3738 object *tmp = NULL, *tmp2; 3725 object *tmp = NULL;
3739 int i; 3726 int i;
3740 3727
3741 op->clr_flag (FLAG_AUTO_APPLY); 3728 op->clr_flag (FLAG_AUTO_APPLY);
3742 3729
3743 switch (op->type) 3730 switch (op->type)
3829 while (invtmp->stats.hp-- > 0) 3816 while (invtmp->stats.hp-- > 0)
3830 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3817 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3831 3818
3832 invtmp->randomitems = NULL; 3819 invtmp->randomitems = NULL;
3833 } 3820 }
3834 else if (invtmp && invtmp->arch 3821 else if (invtmp->arch
3835 && 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 ())
3836 { 3824 {
3837 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3825 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3838 /* Need to clear this so that we never try to create 3826 /* Need to clear this so that we never try to create
3839 * treasure again for this object 3827 * treasure again for this object
3840 */ 3828 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines