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.259 by root, Fri Apr 16 23:32:07 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
251 */ 251 */
252static int 252static int
253prepare_weapon (object *op, object *improver, object *weapon) 253prepare_weapon (object *op, object *improver, object *weapon)
254{ 254{
255 int sacrifice_count, i; 255 int sacrifice_count, i;
256 char buf[MAX_BUF];
257 256
258 if (weapon->level != 0) 257 if (weapon->level != 0)
259 { 258 {
260 op->failmsg ("Weapon is already prepared!"); 259 op->failmsg ("Weapon is already prepared!");
261 return 0; 260 return 0;
290 "Your sacrifice was accepted." 289 "Your sacrifice was accepted."
291 "Your *%s may be improved %d times.", 290 "Your *%s may be improved %d times.",
292 &weapon->name, weapon->level 291 &weapon->name, weapon->level
293 )); 292 ));
294 293
295 sprintf (buf, "%s's %s", &op->name, &weapon->name); 294 weapon->name = weapon->name_pl = format ("%s's %s", &op->name, &weapon->name);
296 weapon->name = weapon->name_pl = buf;
297 weapon->nrof = 0; /* prevents preparing n weapons in the same 295 weapon->nrof = 0; /* prevents preparing n weapons in the same
298 slot at once! */ 296 slot at once! */
299 improver->decrease (); 297 improver->decrease ();
300 weapon->last_eat = 0; 298 weapon->last_eat = 0;
301 return 1; 299 return 1;
692 // 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
693 // get an 'identified' flag so easily. 691 // get an 'identified' flag so easily.
694 if (item->need_identify ()) 692 if (item->need_identify ())
695 identify (item); 693 identify (item);
696 694
697 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
698 return 1; 697 return 1;
699} 698}
700 699
701/** 700/**
702 * Handle apply on containers. 701 * Handle apply on containers.
733 op->close_container (); 732 op->close_container ();
734 return 1; 733 return 1;
735 } 734 }
736 else if (!sack->env) 735 else if (!sack->env)
737 { 736 {
738 // 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.
739 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));
740 return 1; 741 return 1;
741 } 742 }
743 }
742 744
743 // fall through to opening it (active in inv) 745 // it's locked?
746 if (sack->slaying)
744 } 747 {
745 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])
746 { 762 {
747 // 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
748 op->close_container (); 764 op->close_container ();
749 sack->flag [FLAG_APPLIED] = 1; 765 sack->flag [FLAG_APPLIED] = true;
750 esrv_update_item (UPD_FLAGS, op, sack); 766 esrv_update_item (UPD_FLAGS, op, sack);
751 op->statusmsg (format ("You ready %s.", query_name (sack))); 767 op->statusmsg (format ("You ready %s.", query_name (sack)));
752 return 1;
753 }
754
755 // it's locked?
756 if (sack->slaying)
757 { 768 }
758 if (object *tmp = find_key (op, op, sack))
759 op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp)));
760 else 769 else
761 {
762 op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack)));
763 return 1;
764 }
765 }
766
767 op->open_container (sack); 770 op->open_container (sack);
768 771
769 return 1; 772 return 1;
770} 773}
771 774
772/** 775/**
1060 who->flag [FLAG_READY_WEAPON] = false; 1063 who->flag [FLAG_READY_WEAPON] = false;
1061 1064
1062 // 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
1063 // 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
1064 // be used for other reasons 1067 // be used for other reasons
1068 //TODO: really?
1065 if (who->chosen_skill) 1069 if (who->chosen_skill)
1066 if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) 1070 if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL])
1067 unapply_special (who, op, 0); 1071 unapply_special (who, who->chosen_skill, 0);
1068 1072
1069 break; 1073 break;
1070 1074
1075 case RANGED:
1071 case BOW: 1076 case BOW:
1072 case WAND: 1077 case WAND:
1073 case ROD: 1078 case ROD:
1074 case HORN: 1079 case HORN:
1075 case RANGED:
1076 if (player *pl = who->contr) 1080 if (player *pl = who->contr)
1077 { 1081 {
1078 who->statusmsg (format ("You unready %s.", query_name (op))); 1082 who->statusmsg (format ("You unready %s.", query_name (op)));
1079 change_abil (who, op); 1083 change_abil (who, op);
1080 } 1084 }
1389 1393
1390static bool 1394static bool
1391apply_special (object *who, object *op, int aflags) 1395apply_special (object *who, object *op, int aflags)
1392{ 1396{
1393 int basic_flag = aflags & AP_MODE; 1397 int basic_flag = aflags & AP_MODE;
1394 object *tmp, *tmp2, *skop = NULL; 1398 object *tmp, *skop = NULL;
1395
1396 if (who == NULL)
1397 {
1398 LOG (llevError, "apply_special() from object without environment.\n");
1399 return 1;
1400 }
1401
1402 //TODO: remove these when apply_special is no longer exposed
1403 if (op->env != who)
1404 return 1; /* op is not in inventory */
1405 1399
1406 /* trying to unequip op */ 1400 /* trying to unequip op */
1407 if (op->flag [FLAG_APPLIED]) 1401 if (op->flag [FLAG_APPLIED])
1408 { 1402 {
1409 /* always apply, so no reason to unapply */ 1403 /* always apply, so no reason to unapply */
1410 if (basic_flag == AP_APPLY) 1404 if (basic_flag == AP_APPLY)
1411 return 0; 1405 return 0;
1412
1413 if (!(aflags & AP_IGNORE_CURSE) && (op->flag [FLAG_CURSED] || op->flag [FLAG_DAMNED]))
1414 {
1415 who->failmsgf ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, query_name (op));
1416 return 1;
1417 }
1418 1406
1419 return unapply_special (who, op, aflags); 1407 return unapply_special (who, op, aflags);
1420 } 1408 }
1421 else if (basic_flag == AP_UNAPPLY) 1409 else if (basic_flag == AP_UNAPPLY)
1422 return 0; 1410 return 0;
1540 //TODO: unapplying should unapply the skill, though 1528 //TODO: unapplying should unapply the skill, though
1541 op->set_flag (FLAG_APPLIED); 1529 op->set_flag (FLAG_APPLIED);
1542 break; 1530 break;
1543 1531
1544 case SKILL: 1532 case SKILL:
1545 if (!(aflags & AP_NO_SLOT))
1546 {
1547 // skill is used on it's own, as opposed to being a chosen_skill
1548
1549 if (skill_flags [op->subtype] & (SF_NEED_ITEM | SF_MANA))
1550 {
1551 who->failmsgf (
1552 "You feel as if you wanted to do something funny, but you can't remember what. "
1553 "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. "
1554 "It cannot be used on its own.>",
1555 &op->skill
1556 );
1557 if (tmp) who->insert (tmp);
1558 return 1;
1559 }
1560
1561 if (skill_flags [op->subtype] & SF_AUTARK
1562 || !(skill_flags [op->subtype] & (SF_COMBAT | SF_RANGED)))
1563 {
1564 if (skill_flags [op->subtype] & SF_USE)
1565 who->failmsgf (
1566 "You feel as if you wanted to do something funny, but you can't remember what. "
1567 "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>",
1568 &op->skill, &op->skill
1569 );
1570 else
1571 who->failmsgf (
1572 "You feel as if you wanted to do something funny, but you can't remember what. "
1573 "H<The %s skill cannot be readied or used, it is always active.>",
1574 &op->skill
1575 );
1576
1577 if (tmp) who->insert (tmp);
1578
1579 return 1;
1580 }
1581
1582 if (who->contr) 1533 if (who->contr)
1583 if (op->invisible) 1534 if (op->invisible)
1584 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));
1585 else 1536 else
1586 who->statusmsg (format ("You ready %s.", query_name (op))); 1537 who->statusmsg (format ("You ready %s.", query_name (op)));
1587 }
1588 1538
1589 who->set_flag (FLAG_READY_SKILL); 1539 who->set_flag (FLAG_READY_SKILL);
1590 op->set_flag (FLAG_APPLIED); 1540 op->set_flag (FLAG_APPLIED);
1591 change_abil (who, op); 1541 change_abil (who, op);
1592 break; 1542 break;
1816 * matching item. 1766 * matching item.
1817 **/ 1767 **/
1818void 1768void
1819handle_apply_yield (object *tmp) 1769handle_apply_yield (object *tmp)
1820{ 1770{
1821 if (shstr_tmp yield = tmp->kv (shstr_on_use_yield)) 1771 if (shstr_tmp yield = tmp->kv [shstr_on_use_yield])
1822 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); 1772 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR);
1823} 1773}
1824 1774
1825/** 1775/**
1826 * Handles applying a potion. 1776 * Handles applying a potion.
1828int 1778int
1829apply_potion (object *op, object *tmp) 1779apply_potion (object *op, object *tmp)
1830{ 1780{
1831 int got_one = 0, i; 1781 int got_one = 0, i;
1832 object *force = 0; 1782 object *force = 0;
1833
1834 object *floor = GET_MAP_OB (op->map, op->x, op->y);
1835 1783
1836 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)
1837 { 1785 {
1838 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!");
1839 1787
1993 for (i = 0; i < NROFATTACKS; i++) 1941 for (i = 0; i < NROFATTACKS; i++)
1994 { 1942 {
1995 if (tmp->resist[i]) 1943 if (tmp->resist[i])
1996 { 1944 {
1997 if (!force) 1945 if (!force)
1998 force = get_archetype (FORCE_NAME); 1946 force = archetype::get (FORCE_NAME);
1999 1947
2000 memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); 1948 memcpy (force->resist, tmp->resist, sizeof (tmp->resist));
2001 force->type = POTION_EFFECT; 1949 force->type = POTION_EFFECT;
2002 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 */
2003 } 1951 }
2061void 2009void
2062move_apply (object *trap, object *victim, object *originator) 2010move_apply (object *trap, object *victim, object *originator)
2063{ 2011{
2064 static int recursion_depth = 0; 2012 static int recursion_depth = 0;
2065 2013
2014 trap = trap->head_ ();
2015
2066 /* Only exits affect DMs. */ 2016 /* Only exits affect DMs. */
2067 if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) 2017 if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN)
2068 return; 2018 return;
2069 2019
2070 /* move_apply() is the most likely candidate for causing unwanted and 2020 /* move_apply() is the most likely candidate for causing unwanted and
2071 * possibly unlimited recursion. 2021 * possibly unlimited recursion.
2072 */ 2022 */
2023
2073 /* The following was changed because it was causing perfectly correct 2024 /* The following was changed because it was causing perfectly correct
2074 * maps to fail. 1) it's not an error to recurse: 2025 * maps to fail. 1) it's not an error to recurse:
2075 * rune detonates, summoning monster. monster lands on nearby rune. 2026 * rune detonates, summoning monster. monster lands on nearby rune.
2076 * nearby rune detonates. This sort of recursion is expected and 2027 * nearby rune detonates. This sort of recursion is expected and
2077 * proper. This code was causing needless crashes. 2028 * proper. This code was causing needless crashes.
2082 "[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);
2083 return; 2034 return;
2084 } 2035 }
2085 2036
2086 recursion_depth++; 2037 recursion_depth++;
2087 if (trap->head)
2088 trap = trap->head;
2089 2038
2090 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)))
2091 switch (trap->type) 2040 switch (trap->type)
2092 { 2041 {
2093 case PLAYERMOVER: 2042 case PLAYERMOVER:
2103 2052
2104 /* 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
2105 * above with some objects have zero speed, and thus the player 2054 * above with some objects have zero speed, and thus the player
2106 * getting permanently paralyzed. 2055 * getting permanently paralyzed.
2107 */ 2056 */
2108 if (victim->speed_left < -50.f) 2057 victim->speed_left = max (-50.f, victim->speed_left);
2109 victim->speed_left = -50.f;
2110 /* 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); */
2111 } 2059 }
2112 break; 2060 break;
2113 2061
2114 case SPINNER: 2062 case SPINNER:
2146 case ARROW: 2094 case ARROW:
2147 /* 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 ,
2148 * 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.
2149 * 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
2150 * 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
2151 * action, we avoid hits here 2099 * action, we avoid hits here
2152 */ 2100 */
2153 if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ()) 2101 if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ())
2154 && trap->owner != victim) 2102 && trap->owner != victim)
2155 hit_with_arrow (trap, victim); 2103 hit_with_arrow (trap, victim);
2156 break; 2104 break;
2363 if (failure <= -1 && failure > -15) 2311 if (failure <= -1 && failure > -15)
2364 { /* wonder */ 2312 { /* wonder */
2365 object *tmp; 2313 object *tmp;
2366 2314
2367 op->failmsg ("Your spell warps!"); 2315 op->failmsg ("Your spell warps!");
2368 tmp = get_archetype (SPELL_WONDER); 2316 tmp = archetype::get (SPELL_WONDER);
2369 cast_wonder (op, op, 0, tmp); 2317 cast_wonder (op, op, 0, tmp);
2370 tmp->destroy (); 2318 tmp->destroy ();
2371 } 2319 }
2372 else if (failure <= -15 && failure > -35) 2320 else if (failure <= -15 && failure > -35)
2373 { /* drain mana */ 2321 { /* drain mana */
2393 op->failmsg ("The magic recoils on you!"); 2341 op->failmsg ("The magic recoils on you!");
2394 blind_player (op, op, power); 2342 blind_player (op, op, power);
2395 } 2343 }
2396 else if (failure <= -80) 2344 else if (failure <= -80)
2397 { /* blast the immediate area */ 2345 { /* blast the immediate area */
2398 object *tmp = get_archetype (LOOSE_MANA); 2346 object *tmp = archetype::get (LOOSE_MANA);
2399 cast_magic_storm (op, tmp, power); 2347 cast_magic_storm (op, tmp, power);
2400 op->failmsg ("You unleash uncontrolled mana!"); 2348 op->failmsg ("You unleash uncontrolled mana!");
2401 tmp->destroy (); 2349 tmp->destroy ();
2402 } 2350 }
2403 } 2351 }
3077 * the selected object to "burn". -b.t. 3025 * the selected object to "burn". -b.t.
3078 */ 3026 */
3079static void 3027static void
3080apply_lighter (object *who, object *lighter) 3028apply_lighter (object *who, object *lighter)
3081{ 3029{
3082 int is_player_env = 0;
3083
3084 if (object *item = who->mark ()) 3030 if (object *item = who->mark ())
3085 { 3031 {
3086 if (!auto_apply_lighter (who, item, lighter)) 3032 if (!auto_apply_lighter (who, item, lighter))
3087 return; 3033 return;
3088 3034
3345 3291
3346 strcpy (got, find); 3292 strcpy (got, find);
3347 got[len] = '\0'; 3293 got[len] = '\0';
3348 3294
3349 /* Now create new item, remove used ones when required. */ 3295 /* Now create new item, remove used ones when required. */
3350 new_item = get_archetype (got); 3296 new_item = archetype::get (got);
3351 if (!new_item) 3297 if (!new_item)
3352 { 3298 {
3353 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));
3354 return; 3300 return;
3355 } 3301 }
3382 * them in this function - they are passed to apply_special 3328 * them in this function - they are passed to apply_special
3383 */ 3329 */
3384static bool 3330static bool
3385manual_apply (object *who, object *op, int aflag) 3331manual_apply (object *who, object *op, int aflag)
3386{ 3332{
3387 op = op->head_ ();
3388
3389 if (op->flag [FLAG_UNPAID] && !op->flag [FLAG_APPLIED])
3390 {
3391 if (who->contr)
3392 {
3393 examine (who, op);
3394 //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove
3395 return 1;
3396 }
3397 else
3398 return 0; /* monsters just skip unpaid items */
3399 }
3400
3401 if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) 3333 if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who)))
3402 return RESULT_INT (0); 3334 return RESULT_INT (0);
3403 else if (apply_types_inv_only [op->type]) 3335 else if (apply_types_inv_only [op->type])
3404 { 3336 {
3405 // special item, using slot system, needs to be in inv 3337 // special item, using slot system, needs to be in inv
3435 3367
3436 break; 3368 break;
3437 3369
3438 case EXIT: 3370 case EXIT:
3439 if (!EXIT_PATH (op)) 3371 if (!EXIT_PATH (op))
3440 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));
3441 else 3373 else
3442 { 3374 {
3443 /* Don't display messages for random maps. */ 3375 /* Don't display messages for random maps. */
3444 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) 3376 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit)
3445 who->statusmsg (op->msg, NDI_NAVY); 3377 who->statusmsg (op->msg, NDI_NAVY);
3518 check_improve_weapon (who, op); 3450 check_improve_weapon (who, op);
3519 break; 3451 break;
3520 3452
3521 case CLOCK: 3453 case CLOCK:
3522 { 3454 {
3523 char buf[MAX_BUF];
3524 timeofday_t tod; 3455 timeofday_t tod;
3525 3456
3526 get_tod (&tod); 3457 get_tod (&tod);
3527 who->play_sound (sound_find ("sound_clock")); 3458 who->play_sound (sound_find ("sound_clock"));
3528 who->statusmsg (format ( 3459 who->statusmsg (format (
3552 3483
3553 return 1; 3484 return 1;
3554 } 3485 }
3555 else 3486 else
3556 { 3487 {
3557 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)));
3558 return 0; 3489 return 0;
3559 } 3490 }
3560} 3491}
3561 3492
3562/** 3493/**
3625object::apply (object *ob, int aflags) 3556object::apply (object *ob, int aflags)
3626{ 3557{
3627 if (!ob) // simplifies a lot of callers 3558 if (!ob) // simplifies a lot of callers
3628 return true; 3559 return true;
3629 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
3630 if (contr) 3575 if (contr)
3631 { 3576 {
3632 if (!ob->env && (move_type & MOVE_FLYING)) 3577 if (!ob->env && (move_type & MOVE_FLYING))
3633 { 3578 {
3634 /* player is flying and applying object not in inventory */ 3579 /* player is flying and applying object not in inventory */
3647 bool want_apply = 3592 bool want_apply =
3648 aflags & AP_APPLY ? true 3593 aflags & AP_APPLY ? true
3649 : aflags & AP_UNAPPLY ? false 3594 : aflags & AP_UNAPPLY ? false
3650 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE 3595 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE
3651 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
3652 object_ptr *slot = 0; 3607 object_ptr *slot = 0;
3653 3608
3654 // detect the slot, if this is a player 3609 // detect the slot, if this is a player
3655 if (contr && !(aflags & AP_NO_SLOT)) 3610 if (contr && !(aflags & AP_NO_SLOT))
3656 { 3611 {
3661 case WEAPON: 3616 case WEAPON:
3662 slot = &contr->combat_ob; 3617 slot = &contr->combat_ob;
3663 oslot = contr->ranged_ob; 3618 oslot = contr->ranged_ob;
3664 break; 3619 break;
3665 3620
3621 case RANGED:
3666 case BOW: 3622 case BOW:
3667 case RANGED:
3668 case SPELL: 3623 case SPELL:
3669 case WAND: 3624 case WAND:
3670 case ROD: 3625 case ROD:
3671 case HORN: 3626 case HORN:
3672 case BUILDER: 3627 case BUILDER:
3674 oslot = contr->combat_ob; 3629 oslot = contr->combat_ob;
3675 break; 3630 break;
3676 3631
3677 // oh, the humanity 3632 // oh, the humanity
3678 case SKILL: 3633 case SKILL:
3679 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))
3680 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 }
3681 3665
3682 if (skill_flags [ob->subtype] & SF_NEED_ITEM) 3666 if (skill_flags [ob->subtype] & SF_NEED_ITEM)
3683 break; 3667 break;
3684 3668
3685 if (skill_flags [ob->subtype] & SF_COMBAT) 3669 if (skill_flags [ob->subtype] & SF_COMBAT)
3702 // only one slot can be active 3686 // only one slot can be active
3703 if (want_apply) 3687 if (want_apply)
3704 { 3688 {
3705 // clear slot unless we are in it already 3689 // clear slot unless we are in it already
3706 if (*slot != ob) 3690 if (*slot != ob)
3707 apply (*slot, AP_UNAPPLY); 3691 if (!apply (*slot, AP_UNAPPLY))
3692 return false;
3708 3693
3709 // unapply other slot, because we want to become active 3694 // unapply other slot, because we want to become active
3710 apply (oslot, AP_UNAPPLY); 3695 if (!apply (oslot, AP_UNAPPLY))
3696 return false;
3711 } 3697 }
3712 3698
3713 // clear item from slot if applied 3699 // clear item from slot if applied
3714 if (!want_apply && current_weapon == ob) 3700 if (!want_apply && current_weapon == ob)
3715 current_weapon = 0; 3701 current_weapon = 0;
3734 * Generates shop floor's item, and treasures. 3720 * Generates shop floor's item, and treasures.
3735 */ 3721 */
3736int 3722int
3737auto_apply (object *op) 3723auto_apply (object *op)
3738{ 3724{
3739 object *tmp = NULL, *tmp2; 3725 object *tmp = NULL;
3740 int i; 3726 int i;
3741 3727
3742 op->clr_flag (FLAG_AUTO_APPLY); 3728 op->clr_flag (FLAG_AUTO_APPLY);
3743 3729
3744 switch (op->type) 3730 switch (op->type)
3830 while (invtmp->stats.hp-- > 0) 3816 while (invtmp->stats.hp-- > 0)
3831 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3817 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3832 3818
3833 invtmp->randomitems = NULL; 3819 invtmp->randomitems = NULL;
3834 } 3820 }
3835 else if (invtmp && invtmp->arch 3821 else if (invtmp->arch
3836 && 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 ())
3837 { 3824 {
3838 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3825 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3839 /* Need to clear this so that we never try to create 3826 /* Need to clear this so that we never try to create
3840 * treasure again for this object 3827 * treasure again for this object
3841 */ 3828 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines