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.281 by root, Sun Jan 29 02:47:05 2017 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;
306 * Returns 0 if it was not able to work for some reason. 305 * Returns 0 if it was not able to work for some reason.
307 * 306 *
308 * Checks if weapon was prepared, if enough potions on the floor, ... 307 * Checks if weapon was prepared, if enough potions on the floor, ...
309 * 308 *
310 * We are hiding extra information about the weapon in the level and 309 * We are hiding extra information about the weapon in the level and
311 * last_eat numbers for an object. Hopefully this won't break anything ?? 310 * last_eat numbers for an object. Hopefully this won't break anything ??
312 * level == max improve last_eat == current improve 311 * level == max improve last_eat == current improve
313 */ 312 */
314static int 313static int
315improve_weapon (object *op, object *improver, object *weapon) 314improve_weapon (object *op, object *improver, object *weapon)
316{ 315{
341 "powerful for you to use. Unready it if you " 340 "powerful for you to use. Unready it if you "
342 "really want to improve it."); 341 "really want to improve it.");
343 return 0; 342 return 0;
344 } 343 }
345 344
346 /* This just increases damage by 5 points, no matter what. No sacrifice 345 /* This just increases damage by 5 points, no matter what. No sacrifice
347 * is needed. Since stats.dam is now a 16 bit value and not 8 bit, 346 * is needed. Since stats.dam is now a 16 bit value and not 8 bit,
348 * don't put any maximum value on damage - the limit is how much the 347 * don't put any maximum value on damage - the limit is how much the
349 * weapon can be improved. 348 * weapon can be improved.
350 */ 349 */
351 if (improver->stats.sp == IMPROVE_DAMAGE) 350 if (improver->stats.sp == IMPROVE_DAMAGE)
352 { 351 {
353 weapon->stats.dam += 5; 352 weapon->stats.dam += 5;
354 weapon->weight += 5000; /* 5 KG's */ 353 weapon->weight += 5000; /* 5 KG's */
477 * the stats of a player w/ armour as well as a weapon 476 * the stats of a player w/ armour as well as a weapon
478 * will probably horribly unbalance the game. Magic enchanting 477 * will probably horribly unbalance the game. Magic enchanting
479 * depends on the level of the character - ie the plus 478 * depends on the level of the character - ie the plus
480 * value (magic) of the armour can never be increased beyond 479 * value (magic) of the armour can never be increased beyond
481 * the level of the character / 10 -- rounding upish, nor may 480 * the level of the character / 10 -- rounding upish, nor may
482 * the armour value of the piece of equipment exceed either 481 * the armour value of the piece of equipment exceed either
483 * the users level or 90) 482 * the users level or 90)
484 * Modified by MSW for partial resistance. Only support 483 * Modified by MSW for partial resistance. Only support
485 * changing of physical area right now. 484 * changing of physical area right now.
486 */ 485 */
487static int 486static int
668 item->nrof *= nr; 667 item->nrof *= nr;
669 668
670 if (converter->flag [FLAG_PRECIOUS]) 669 if (converter->flag [FLAG_PRECIOUS])
671 item->set_flag (FLAG_UNPAID); 670 item->set_flag (FLAG_UNPAID);
672 671
673 if (converter->is_in_shop ()) 672 if (converter->is_in_shop ())
674 { 673 {
675 // converters on shop floors don't work anymore, bug lets check for it 674 // converters on shop floors don't work anymore, bug lets check for it
676 // and report in case someone still does it. 675 // and report in case someone still does it.
677 LOG (llevDebug, "ITEMBUG: broken converter, converters on shop floor don't work: %s\n", 676 LOG (llevDebug, "ITEMBUG: broken converter, converters on shop floor don't work: %s\n",
678 converter->debug_desc ()); 677 converter->debug_desc ());
681 else if (price_in < sint64 (item->nrof) * item->value) 680 else if (price_in < sint64 (item->nrof) * item->value)
682 { 681 {
683 LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", 682 LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n",
684 &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); 683 &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name);
685 /** 684 /**
686 * elmex: we are going to let the game continue, as the mapcreator 685 * elmex: we are going to let the game continue, as the mapcreator
687 * hopefully had something in mind when doing this. 686 * hopefully had something in mind when doing this.
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.
702 * By Eneq(@csd.uu.se). 702 * By Eneq(@csd.uu.se).
703 * Moved to own function and added many features [Tero.Haatanen@lut.fi] 703 * Moved to own function and added many features [Tero.Haatanen@lut.fi]
704 * added the alchemical cauldron to the code -b.t. 704 * added the alchemical cauldron to the code -b.t.
705 */ 705 */
706static int 706static int
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/**
968 } 972 }
969 973
970 /* Sign or magic mouth? Do we need to see it, or does it talk to us? 974 /* Sign or magic mouth? Do we need to see it, or does it talk to us?
971 * No way to know for sure. The presumption is basically that if 975 * No way to know for sure. The presumption is basically that if
972 * move_on is zero, it needs to be manually applied (doesn't talk 976 * move_on is zero, it needs to be manually applied (doesn't talk
973 * to us). 977 * to us).
974 */ 978 */
975 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ] && !sign->move_on) 979 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ] && !sign->move_on)
976 { 980 {
977 op->failmsg ("You are unable to read while blind!"); 981 op->failmsg ("You are unable to read while blind!");
978 return; 982 return;
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 }
1281 1286
1282 /* if we have an applied weapon/shield, and unapply it would free 1287 /* if we have an applied weapon/shield, and unapply it would free
1283 * enough slots to equip the new item, then just set "can 1288 * enough slots to equip the new item, then just set "can
1284 * apply unapply". We don't care about the logic below - if you have a 1289 * apply unapply". We don't care about the logic below - if you have a
1285 * shield equipped and try to equip another shield, there is only 1290 * shield equipped and try to equip another shield, there is only
1286 * one choice. However, the check for the number of body locations 1291 * one choice. However, the check for the number of body locations
1287 * does take into the account cases where what is being applied 1292 * does take into the account cases where what is being applied
1288 * may be two handed for example. 1293 * may be two handed for example.
1289 */ 1294 */
1290 if (ws) 1295 if (ws)
1291 if ((who->slot[i].used - ws->slot[i].info + op->slot[i].info) >= 0) 1296 if ((who->slot[i].used - ws->slot[i].info + op->slot[i].info) >= 0)
1310 else if (tmp != tmp1) 1315 else if (tmp != tmp1)
1311 retval |= CAN_APPLY_UNAPPLY_MULT; 1316 retval |= CAN_APPLY_UNAPPLY_MULT;
1312 1317
1313 /* This object isn't using up all the slots, so there must 1318 /* This object isn't using up all the slots, so there must
1314 * be another. If so, and it the new item doesn't need all 1319 * be another. If so, and it the new item doesn't need all
1315 * the slots, the player then has a choice. 1320 * the slots, the player then has a choice.
1316 */ 1321 */
1317 if ((who->slot[i].used - tmp1->slot[i].info != who->slot[i].info) 1322 if ((who->slot[i].used - tmp1->slot[i].info != who->slot[i].info)
1318 && abs (op->slot[i].info) < who->slot[i].info) 1323 && abs (op->slot[i].info) < who->slot[i].info)
1319 retval |= CAN_APPLY_UNAPPLY_CHOICE; 1324 retval |= CAN_APPLY_UNAPPLY_CHOICE;
1320 1325
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;
1483 return 1; 1472 return 1;
1484 } 1473 }
1485 1474
1486 /* Ok. We are now at the state where we can apply the new object. 1475 /* Ok. We are now at the state where we can apply the new object.
1487 * Note that we don't have the checks for can_use_... 1476 * Note that we don't have the checks for can_use_...
1488 * below - that is already taken care of by can_apply_object. 1477 * below - that is already taken care of by can_apply_object.
1489 */ 1478 */
1490 1479
1491 // split away all the other items from the stack, so only one item is left 1480 // split away all the other items from the stack, so only one item is left
1492 tmp = op->nrof > 1 ? op->split (op->nrof - 1) : 0; 1481 tmp = op->nrof > 1 ? op->split (op->nrof - 1) : 0;
1493 1482
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;
1719 arch_flag = 1; 1670 arch_flag = 1;
1720 name_flag = 1; 1671 name_flag = 1;
1721 race_flag = 1; 1672 race_flag = 1;
1722 } 1673 }
1723 1674
1724 /* If the director has race set, only affect objects with a arch, 1675 /* If the director has race set, only affect objects with a arch,
1725 * name or race that matches. 1676 * name or race that matches.
1726 */ 1677 */
1727 if ((op->race) && 1678 if ((op->race) &&
1728 ((!(victim->arch && arch_flag && victim->arch->archname) || op->race != victim->arch->archname)) && 1679 ((!(victim->arch && arch_flag && victim->arch->archname) || op->race != victim->arch->archname)) &&
1729 ((!(victim->name && name_flag) || op->race != victim->name)) && 1680 ((!(victim->name && name_flag) || op->race != victim->name)) &&
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.
2077 */ 2029 */
2078 if (recursion_depth >= 500) 2030 if (recursion_depth >= 500)
2079 { 2031 {
2080 LOG (llevDebug, "WARNING: move_apply(): aborting recursion " 2032 LOG (llevDebug, "WARNING: move_apply(): aborting recursion "
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;
2179 } 2128 }
2180 2129
2181 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next) 2130 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
2182 { 2131 {
2183 /* need to set this up, since if we do transfer the object, 2132 /* need to set this up, since if we do transfer the object,
2184 * ab->above would be bogus 2133 * ab->above would be bogus
2185 */ 2134 */
2186 ab_next = ab->above; 2135 ab_next = ab->above;
2187 2136
2188 if ((ab->move_type && trap->move_on) || ab->move_type == 0) 2137 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
2189 { 2138 {
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 }
2592 * 2541 *
2593 * 2- The learner's skill level in literacy adjusts the chance to learn 2542 * 2- The learner's skill level in literacy adjusts the chance to learn
2594 * a spell. 2543 * a spell.
2595 * 2544 *
2596 * 3 -Automatically fail to learn if you read while confused 2545 * 3 -Automatically fail to learn if you read while confused
2597 * 2546 *
2598 * Overall, chances are the same but a player will find having a high 2547 * Overall, chances are the same but a player will find having a high
2599 * literacy rate very useful! -b.t. 2548 * literacy rate very useful! -b.t.
2600 */ 2549 */
2601 if (op->flag [FLAG_CONFUSED]) 2550 if (op->flag [FLAG_CONFUSED])
2602 { 2551 {
2603 op->failmsg ("In your confused state you flub the wording of the text!"); 2552 op->failmsg ("In your confused state you flub the wording of the text!");
2604 scroll_failure (op, 0 - random_roll (0, spell->level, op, PREFER_LOW), max (spell->stats.sp, spell->stats.grace)); 2553 scroll_failure (op, 0 - random_roll (0, spell->level, op, PREFER_LOW), max (spell->stats.sp, spell->stats.grace));
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 */
3841 invtmp->randomitems = NULL; 3829 invtmp->randomitems = NULL;
3842 } 3830 }
3843 } 3831 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines