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.250 by root, Tue Apr 6 23:36:49 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);
139 if (!item) 140 if (!item)
140 return 0; 141 return 0;
141 142
142 for (op = op->below; op; op = op->below) 143 for (op = op->below; op; op = op->below)
143 if (op->arch->archname == item) 144 if (op->arch->archname == item)
144 if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED) 145 if (!op->flag [FLAG_CURSED] && !op->flag [FLAG_DAMNED]
145 && /* Loophole bug? -FD- */ !QUERY_FLAG (op, FLAG_UNPAID)) 146 && /* Loophole bug? -FD- */ !op->flag [FLAG_UNPAID])
146 count += op->number_of (); 147 count += op->number_of ();
147 148
148 return count; 149 return count;
149} 150}
150 151
197 if (improver->slaying) 198 if (improver->slaying)
198 { 199 {
199 count = check_item (op, improver->slaying); 200 count = check_item (op, improver->slaying);
200 if (count < 1) 201 if (count < 1)
201 { 202 {
202 op->failmsg (format ("The gods want more %ss", &improver->slaying)); 203 op->failmsgf ("The gods want more %ss", &improver->slaying);
203 return 0; 204 return 0;
204 } 205 }
205 } 206 }
206 else 207 else
207 count = 1; 208 count = 1;
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;
332 { 331 {
333 op->failmsg ("This weapon cannot be improved any more."); 332 op->failmsg ("This weapon cannot be improved any more.");
334 return 0; 333 return 0;
335 } 334 }
336 335
337 if (QUERY_FLAG (weapon, FLAG_APPLIED) 336 if (weapon->flag [FLAG_APPLIED]
338 && !check_item_power (op, weapon->item_power + 1)) 337 && !check_item_power (op, weapon->item_power + 1))
339 { 338 {
340 op->failmsg ("Improving the weapon will make it too " 339 op->failmsg ("Improving the weapon will make it too "
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.");
392 sacrifice_needed *= 2; 391 sacrifice_needed *= 2;
393 392
394 sacrifice_count = check_sacrifice (op, improver); 393 sacrifice_count = check_sacrifice (op, improver);
395 if (sacrifice_count < sacrifice_needed) 394 if (sacrifice_count < sacrifice_needed)
396 { 395 {
397 op->failmsg (format ("You need at least %d %s.", sacrifice_needed, &improver->slaying)); 396 op->failmsgf ("You need at least %d %s.", sacrifice_needed, &improver->slaying);
398 return 0; 397 return 0;
399 } 398 }
400 399
401 eat_item (op, improver->slaying, sacrifice_needed); 400 eat_item (op, improver->slaying, sacrifice_needed);
402 weapon->item_power++; 401 weapon->item_power++;
424 * then calls improve_weapon to do the dirty work. 423 * then calls improve_weapon to do the dirty work.
425 */ 424 */
426static int 425static int
427check_improve_weapon (object *op, object *tmp) 426check_improve_weapon (object *op, object *tmp)
428{ 427{
429 object *otmp;
430
431 if (op->type != PLAYER) 428 if (op->type != PLAYER)
432 return 0; 429 return 0;
433 430
434 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) 431 if (!op->flag [FLAG_WIZCAST] && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
435 { 432 {
436 op->failmsg ("Something blocks the magic of the scroll!"); 433 op->failmsg ("Something blocks the magic of the scroll!");
437 return 0; 434 return 0;
438 } 435 }
439 436
440 otmp = find_marked_object (op); 437 object *otmp = op->mark ();
441 438
442 if (!otmp) 439 if (!otmp)
443 { 440 {
444 op->failmsg ("You need to mark a weapon object. H<Use the mark command or the mark option from the item popup menu.>"); 441 op->failmsg ("You need to mark a weapon object. H<Use the mark command or the mark option from the item popup menu.>");
445 return 0; 442 return 0;
446 } 443 }
447 444
448 if (otmp->type != WEAPON && otmp->type != BOW) 445 if (otmp->type != WEAPON && otmp->type != BOW)
449 { 446 {
450 op->failmsg ("Marked item is not a weapon or bow!"); 447 op->failmsg ("Marked item is not a weapon or bow!");
448 return 0;
449 }
450
451 if (!op->apply (otmp, AP_UNAPPLY))
452 {
453 op->failmsg ("You are unable to take off your weapon to improve it!");
451 return 0; 454 return 0;
452 } 455 }
453 456
454 op->statusmsg ("Applied weapon builder."); 457 op->statusmsg ("Applied weapon builder.");
455 458
481 * changing of physical area right now. 484 * changing of physical area right now.
482 */ 485 */
483static int 486static int
484improve_armour (object *op, object *improver, object *armour) 487improve_armour (object *op, object *improver, object *armour)
485{ 488{
486 object *tmp;
487
488 if (armour->magic >= settings.armor_max_enchant) 489 if (armour->magic >= settings.armor_max_enchant)
489 { 490 {
490 op->failmsg ("This armour can not be enchanted any further!"); 491 op->failmsg ("This armour can not be enchanted any further!");
491 return 0; 492 return 0;
492 } 493 }
503 } 504 }
504 505
505 /* Split objects if needed. Can't insert tmp until the 506 /* Split objects if needed. Can't insert tmp until the
506 * end of this function - otherwise it will just re-merge. 507 * end of this function - otherwise it will just re-merge.
507 */ 508 */
508 tmp = armour->nrof > 1 ? armour->split (armour->nrof - 1) : 0; 509 object *tmp = armour->nrof > 1 ? armour->split (armour->nrof - 1) : 0;
509 510
510 armour->magic++; 511 armour->magic++;
511 512
512 if (!settings.armor_speed_linear) 513 if (!settings.armor_speed_linear)
513 { 514 {
551 552
552 if (op->type == PLAYER) 553 if (op->type == PLAYER)
553 { 554 {
554 esrv_send_item (op, armour); 555 esrv_send_item (op, armour);
555 556
556 if (QUERY_FLAG (armour, FLAG_APPLIED)) 557 if (armour->flag [FLAG_APPLIED])
557 op->update_stats (); 558 op->update_stats ();
558 } 559 }
559 560
560 improver->decrease (); 561 improver->decrease ();
561 562
641 for (ob = converter->inv->below, i = 1; ob; ob = ob->below, i++) 642 for (ob = converter->inv->below, i = 1; ob; ob = ob->below, i++)
642 if (rndm (0, i) == 0) 643 if (rndm (0, i) == 0)
643 ob_to_copy = ob; 644 ob_to_copy = ob;
644 645
645 item = ob_to_copy->deep_clone (); 646 item = ob_to_copy->deep_clone ();
646 CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE); 647 item->clr_flag (FLAG_IS_A_TEMPLATE);
647 unflag_inv (item, FLAG_IS_A_TEMPLATE); 648 unflag_inv (item, FLAG_IS_A_TEMPLATE);
648 } 649 }
649 else 650 else
650 { 651 {
651 if (!conv_to) 652 if (!conv_to)
664 665
665 if (nr) 666 if (nr)
666 item->nrof *= nr; 667 item->nrof *= nr;
667 668
668 if (converter->flag [FLAG_PRECIOUS]) 669 if (converter->flag [FLAG_PRECIOUS])
669 SET_FLAG (item, FLAG_UNPAID); 670 item->set_flag (FLAG_UNPAID);
670 671
671 if (converter->is_in_shop ()) 672 if (converter->is_in_shop ())
672 { 673 {
673 // 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
674 // and report in case someone still does it. 675 // and report in case someone still does it.
675 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",
676 converter->debug_desc ()); 677 converter->debug_desc ());
677 SET_FLAG (item, FLAG_UNPAID); 678 item->set_flag (FLAG_UNPAID);
678 } 679 }
679 else if (price_in < sint64 (item->nrof) * item->value) 680 else if (price_in < sint64 (item->nrof) * item->value)
680 { 681 {
681 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",
682 &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);
686 */ 687 */
687 } 688 }
688 689
689 // 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
690 // get an 'identified' flag so easily. 691 // get an 'identified' flag so easily.
691 if (need_identify (item)) 692 if (item->need_identify ())
692 identify (item); 693 identify (item);
693 694
694 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
695 return 1; 697 return 1;
696} 698}
697 699
698/** 700/**
699 * Handle apply on containers. 701 * Handle apply on containers.
730 op->close_container (); 732 op->close_container ();
731 return 1; 733 return 1;
732 } 734 }
733 else if (!sack->env) 735 else if (!sack->env)
734 { 736 {
735 // 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.
736 op->failmsg (format ("Somebody else is using the %s already.", query_name (sack))); 740 op->failmsgf ("Somebody else is using the %s already.", query_name (sack));
737 return 1; 741 return 1;
738 } 742 }
743 }
739 744
740 // fall through to opening it (active in inv) 745 // it's locked?
746 if (sack->slaying)
741 } 747 {
742 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])
743 { 762 {
744 // 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
745 op->close_container (); 764 op->close_container ();
746 sack->flag [FLAG_APPLIED] = 1; 765 sack->flag [FLAG_APPLIED] = true;
747 esrv_update_item (UPD_FLAGS, op, sack); 766 esrv_update_item (UPD_FLAGS, op, sack);
748 op->statusmsg (format ("You ready %s.", query_name (sack))); 767 op->statusmsg (format ("You ready %s.", query_name (sack)));
749 return 1;
750 }
751
752 // it's locked?
753 if (sack->slaying)
754 { 768 }
755 if (object *tmp = find_key (op, op, sack))
756 op->statusmsg (format ("You unlock %s with %s.", query_name (sack), query_name (tmp)));
757 else 769 else
758 {
759 op->statusmsg (format ("You don't have the key to unlock %s.", query_name (sack)));
760 return 1;
761 }
762 }
763
764 op->open_container (sack); 770 op->open_container (sack);
765 771
766 return 1; 772 return 1;
767} 773}
768 774
769/** 775/**
817{ 823{
818 int rv = 0; 824 int rv = 0;
819 double opinion; 825 double opinion;
820 object *tmp, *next; 826 object *tmp, *next;
821 827
822 SET_FLAG (op, FLAG_NO_APPLY); /* prevent loops */ 828 op->set_flag (FLAG_NO_APPLY); /* prevent loops */
823 829
824 bool has_unpaid = false; 830 bool has_unpaid = false;
825 831
826 // quite inefficient to do this here twice, but the api doesn't lend itself to 832 // quite inefficient to do this here twice, but the api doesn't lend itself to
827 // a quick and small change :( 833 // a quick and small change :(
840 */ 846 */
841 for (tmp = op->inv; tmp; tmp = next) 847 for (tmp = op->inv; tmp; tmp = next)
842 { 848 {
843 next = tmp->below; 849 next = tmp->below;
844 850
845 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 851 if (tmp->flag [FLAG_UNPAID])
846 { 852 {
847 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 853 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
848 854
849 if (i >= 0) 855 if (i >= 0)
850 tmp->move (i); 856 tmp->move (i);
851 } 857 }
852 } 858 }
853 859
854 /* Don't teleport things like spell effects */ 860 /* Don't teleport things like spell effects */
855 if (QUERY_FLAG (op, FLAG_NO_PICK)) 861 if (op->flag [FLAG_NO_PICK])
856 return 0; 862 return 0;
857 863
858 /* unpaid objects, or non living objects, can't transfer by 864 /* unpaid objects, or non living objects, can't transfer by
859 * shop mats. Instead, put it on a nearby space. 865 * shop mats. Instead, put it on a nearby space.
860 */ 866 */
861 if (QUERY_FLAG (op, FLAG_UNPAID) || !QUERY_FLAG (op, FLAG_ALIVE)) 867 if (op->flag [FLAG_UNPAID] || !op->flag [FLAG_ALIVE])
862 { 868 {
863 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 869 /* Somebody dropped an unpaid item, just move to an adjacent place. */
864 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 870 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
865 871
866 if (i != -1) 872 if (i != -1)
921 op->y += freearr_y[i]; 927 op->y += freearr_y[i];
922 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; 928 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
923 } 929 }
924 } 930 }
925 931
926 CLEAR_FLAG (op, FLAG_NO_APPLY); 932 op->clr_flag (FLAG_NO_APPLY);
927 return rv; 933 return rv;
928} 934}
929 935
930/** 936/**
931 * Handles applying a sign. 937 * Handles applying a sign.
959 op->failmsg ("You cannot read it anymore."); 965 op->failmsg ("You cannot read it anymore.");
960 966
961 return; 967 return;
962 } 968 }
963 969
964 if (!QUERY_FLAG (op, FLAG_WIZPASS)) 970 if (!op->flag [FLAG_WIZPASS])
965 sign->last_eat++; 971 sign->last_eat++;
966 } 972 }
967 973
968 /* 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?
969 * 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
970 * 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
971 * to us). 977 * to us).
972 */ 978 */
973 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on) 979 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ] && !sign->move_on)
974 { 980 {
975 op->failmsg ("You are unable to read while blind!"); 981 op->failmsg ("You are unable to read while blind!");
976 return; 982 return;
977 } 983 }
978 984
1057 who->flag [FLAG_READY_WEAPON] = false; 1063 who->flag [FLAG_READY_WEAPON] = false;
1058 1064
1059 // 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
1060 // 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
1061 // be used for other reasons 1067 // be used for other reasons
1068 //TODO: really?
1062 if (who->chosen_skill) 1069 if (who->chosen_skill)
1063 if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL]) 1070 if (!who->chosen_skill->flag [FLAG_CAN_USE_SKILL])
1064 unapply_special (who, op, 0); 1071 unapply_special (who, who->chosen_skill, 0);
1065 1072
1066 break; 1073 break;
1067 1074
1075 case RANGED:
1068 case BOW: 1076 case BOW:
1069 case WAND: 1077 case WAND:
1070 case ROD: 1078 case ROD:
1071 case HORN: 1079 case HORN:
1072 case RANGED:
1073 if (player *pl = who->contr) 1080 if (player *pl = who->contr)
1074 { 1081 {
1075 who->statusmsg (format ("You unready %s.", query_name (op))); 1082 who->statusmsg (format ("You unready %s.", query_name (op)));
1076 change_abil (who, op); 1083 change_abil (who, op);
1077 } 1084 }
1078 else 1085 else
1079 { 1086 {
1080 who->change_skill (0);
1081
1082 if (op->type == BOW) 1087 if (op->type == BOW)
1083 op->flag [FLAG_READY_BOW ] = false; 1088 op->flag [FLAG_READY_BOW ] = false;
1084 else 1089 else
1085 op->flag [FLAG_READY_RANGE] = false; 1090 op->flag [FLAG_READY_RANGE] = false;
1086 } 1091 }
1167static bool 1172static bool
1168unapply_for_ob (object *who, object *op, int aflags) 1173unapply_for_ob (object *who, object *op, int aflags)
1169{ 1174{
1170 if (op->is_range ()) 1175 if (op->is_range ())
1171 for (object *tmp = who->inv; tmp; tmp = tmp->below) 1176 for (object *tmp = who->inv; tmp; tmp = tmp->below)
1172 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->is_range ()) 1177 if (tmp->flag [FLAG_APPLIED] && tmp->is_range ())
1173 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))) 1178 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!tmp->flag [FLAG_CURSED] && !tmp->flag [FLAG_DAMNED]))
1174 { 1179 {
1175 if (aflags & AP_PRINT) 1180 if (aflags & AP_PRINT)
1176 who->failmsg (query_name (tmp)); 1181 who->failmsg (query_name (tmp));
1177 else 1182 else
1178 unapply_special (who, tmp, aflags); 1183 unapply_special (who, tmp, aflags);
1181 { 1186 {
1182 /* In this case, we want to try and remove a cursed item. 1187 /* In this case, we want to try and remove a cursed item.
1183 * While we know it won't work, we want unapply_special to 1188 * While we know it won't work, we want unapply_special to
1184 * at least generate the message. 1189 * at least generate the message.
1185 */ 1190 */
1186 who->failmsg (format ("No matter how hard you try, you just can't remove the %s." CANNOT_REMOVE_CURSED, query_name (tmp))); 1191 who->failmsgf ("No matter how hard you try, you just can't remove the %s." CANNOT_REMOVE_CURSED, query_name (tmp));
1187 return 1; 1192 return 1;
1188 } 1193 }
1189 1194
1190 for (int i = 0; i < NUM_BODY_LOCATIONS; i++) 1195 for (int i = 0; i < NUM_BODY_LOCATIONS; i++)
1191 { 1196 {
1211#endif 1216#endif
1212 return 1; 1217 return 1;
1213 } 1218 }
1214 1219
1215 /* If we are just printing, we don't care about cursed status */ 1220 /* If we are just printing, we don't care about cursed status */
1216 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!(QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))) 1221 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!(tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])))
1217 { 1222 {
1218 if (aflags & AP_PRINT) 1223 if (aflags & AP_PRINT)
1219 who->failmsg (query_name (tmp)); 1224 who->failmsg (query_name (tmp));
1220 else 1225 else
1221 unapply_special (who, tmp, aflags); 1226 unapply_special (who, tmp, aflags);
1225 /* Cursed item that we can't unequip - tell the player. 1230 /* Cursed item that we can't unequip - tell the player.
1226 * Note this could be annoying if this is just one of a few, 1231 * Note this could be annoying if this is just one of a few,
1227 * so it may not be critical (eg, putting on a ring and you have 1232 * so it may not be critical (eg, putting on a ring and you have
1228 * one cursed ring.) 1233 * one cursed ring.)
1229 */ 1234 */
1230 who->failmsg (format ("The %s just won't come off." CANNOT_REMOVE_CURSED, query_name (tmp))); 1235 who->failmsgf ("The %s just won't come off." CANNOT_REMOVE_CURSED, query_name (tmp));
1231 } 1236 }
1232 1237
1233 last = tmp->below; 1238 last = tmp->below;
1234 } 1239 }
1235 /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the 1240 /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the
1333 * the weapon/shield checks, and the range checks for monsters, 1338 * the weapon/shield checks, and the range checks for monsters,
1334 * because you can't control those just by body location - bows, shields, 1339 * because you can't control those just by body location - bows, shields,
1335 * and weapons all use the same slot. Similar for horn/rod/wand - they 1340 * and weapons all use the same slot. Similar for horn/rod/wand - they
1336 * all use the same location. 1341 * all use the same location.
1337 */ 1342 */
1338 if (op->type == WEAPON && !QUERY_FLAG (who, FLAG_USE_WEAPON)) 1343 if (op->type == WEAPON && !who->flag [FLAG_USE_WEAPON])
1339 retval |= CAN_APPLY_RESTRICTION; 1344 retval |= CAN_APPLY_RESTRICTION;
1340 1345
1341 if (op->type == SHIELD && !QUERY_FLAG (who, FLAG_USE_SHIELD)) 1346 if (op->type == SHIELD && !who->flag [FLAG_USE_SHIELD])
1342 retval |= CAN_APPLY_RESTRICTION; 1347 retval |= CAN_APPLY_RESTRICTION;
1343 1348
1344 if (who->type != PLAYER) 1349 if (who->type != PLAYER)
1345 { 1350 {
1346 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE)) 1351 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !who->flag [FLAG_USE_RANGE])
1347 retval |= CAN_APPLY_RESTRICTION; 1352 retval |= CAN_APPLY_RESTRICTION;
1348 1353
1349 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 1354 if (op->type == BOW && !who->flag [FLAG_USE_BOW])
1350 retval |= CAN_APPLY_RESTRICTION; 1355 retval |= CAN_APPLY_RESTRICTION;
1351 1356
1352 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING)) 1357 if (op->type == RING && !who->flag [FLAG_USE_RING])
1353 retval |= CAN_APPLY_RESTRICTION; 1358 retval |= CAN_APPLY_RESTRICTION;
1354 1359
1355 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 1360 if (op->type == BOW && !who->flag [FLAG_USE_BOW])
1356 retval |= CAN_APPLY_RESTRICTION; 1361 retval |= CAN_APPLY_RESTRICTION;
1357 } 1362 }
1358 1363
1359 return retval; 1364 return retval;
1360} 1365}
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 (QUERY_FLAG (op, 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 1406
1412 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)))
1413 {
1414 who->failmsg (format ("No matter how hard you try, you just can't remove %s." CANNOT_REMOVE_CURSED, query_name (op)));
1415 return 1;
1416 }
1417
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;
1422 1411
1425 /* Can't just apply this object. Lets see what not and what to do */ 1414 /* Can't just apply this object. Lets see what not and what to do */
1426 if (int i = can_apply_object (who, op)) 1415 if (int i = can_apply_object (who, op))
1427 { 1416 {
1428 if (i & CAN_APPLY_NEVER) 1417 if (i & CAN_APPLY_NEVER)
1429 { 1418 {
1430 who->failmsg (format ("You don't have the body to use a %s. H<You can never apply this item.>", query_name (op))); 1419 who->failmsgf ("You don't have the body to use a %s. H<You can never apply this item.>", query_name (op));
1431 return 1; 1420 return 1;
1432 } 1421 }
1433 else if (i & CAN_APPLY_RESTRICTION) 1422 else if (i & CAN_APPLY_RESTRICTION)
1434 { 1423 {
1435 who->failmsg (format ( 1424 who->failmsgf (
1436 "You have a prohibition against using a %s. " 1425 "You have a prohibition against using a %s. "
1437 "H<Your belief, profession or class prevents you from applying this item.>", 1426 "H<Your belief, profession or class prevents you from applying this item.>",
1438 query_name (op) 1427 query_name (op)
1439 )); 1428 );
1440 return 1; 1429 return 1;
1441 } 1430 }
1442 1431
1443 if (who->type != PLAYER) 1432 if (who->type != PLAYER)
1444 { 1433 {
1465 // try to ready attached skill first 1454 // try to ready attached skill first
1466 skop = find_skill_by_name (who, op->skill); 1455 skop = find_skill_by_name (who, op->skill);
1467 1456
1468 if (!skop) 1457 if (!skop)
1469 { 1458 {
1470 who->failmsg (format ("You need the %s skill to use this item!", &op->skill)); 1459 who->failmsgf ("You need the %s skill to use this item!", &op->skill);
1471 return 1; 1460 return 1;
1472 } 1461 }
1473 else if (!who->apply (skop, AP_APPLY | AP_NO_SLOT)) 1462 else if (!who->apply (skop, AP_APPLY | AP_NO_SLOT))
1474 { 1463 {
1475 who->failmsg (format ("You can't use the required %s skill!", &op->skill)); 1464 who->failmsgf ("You can't use the required %s skill!", &op->skill);
1476 return 1; 1465 return 1;
1477 } 1466 }
1478 } 1467 }
1479 1468
1480 if (!check_item_power (who, op->item_power)) 1469 if (!check_item_power (who, op->item_power))
1512 if (player *pl = who->contr) 1501 if (player *pl = who->contr)
1513 { 1502 {
1514 who->statusmsg (format ("You wield %s.", query_name (op))); 1503 who->statusmsg (format ("You wield %s.", query_name (op)));
1515 change_abil (who, op); 1504 change_abil (who, op);
1516 } 1505 }
1517 else
1518 who->change_skill (skop);
1519 1506
1520 op->flag [FLAG_READY_WEAPON] = true; 1507 op->flag [FLAG_READY_WEAPON] = true;
1521 break; 1508 break;
1522 1509
1523 case ARMOUR: 1510 case ARMOUR:
1528 case GIRDLE: 1515 case GIRDLE:
1529 case BRACERS: 1516 case BRACERS:
1530 case CLOAK: 1517 case CLOAK:
1531 case RING: 1518 case RING:
1532 case AMULET: 1519 case AMULET:
1533 SET_FLAG (op, FLAG_APPLIED); 1520 op->set_flag (FLAG_APPLIED);
1534 who->statusmsg (format ("You wear %s.", query_name (op))); 1521 who->statusmsg (format ("You wear %s.", query_name (op)));
1535 change_abil (who, op); 1522 change_abil (who, op);
1536 break; 1523 break;
1537 1524
1538 case SKILL_TOOL: 1525 case SKILL_TOOL:
1539 // applying a skill tool does not ready the skill 1526 // applying a skill tool does not ready the skill
1540 // if something needs the skill, it has to ready it itself 1527 // if something needs the skill, it has to ready it itself
1541 //TODO: unapplying should unapply the skill, though 1528 //TODO: unapplying should unapply the skill, though
1542 SET_FLAG (op, FLAG_APPLIED); 1529 op->set_flag (FLAG_APPLIED);
1543 break; 1530 break;
1544 1531
1545 case SKILL: 1532 case SKILL:
1546 if (!(aflags & AP_NO_SLOT))
1547 {
1548 // skill is used on it's own, as opposed to being a chosen_skill
1549
1550 if (skill_flags [op->subtype] & (SF_NEED_ITEM | SF_MANA))
1551 {
1552 who->failmsg (format (
1553 "You feel as if you wanted to do something funny, but you can't remember what. "
1554 "H<The %s skill needs something else to function, for example a tool, weapon, rod, or spell. "
1555 "It cannot be used on its own.>",
1556 &op->skill
1557 ));
1558 if (tmp) who->insert (tmp);
1559 return 1;
1560 }
1561
1562 if (skill_flags [op->subtype] & SF_AUTARK
1563 || !(skill_flags [op->subtype] & (SF_COMBAT | SF_RANGED)))
1564 {
1565 if (skill_flags [op->subtype] & SF_USE)
1566 who->failmsg (format (
1567 "You feel as if you wanted to do something funny, but you can't remember what. "
1568 "H<The %s skill cannot be readied, instead, try C<use_skill %s>.>",
1569 &op->skill, &op->skill
1570 ));
1571 else
1572 who->failmsg (format (
1573 "You feel as if you wanted to do something funny, but you can't remember what. "
1574 "H<The %s skill cannot be readied or used, it is always active.>",
1575 &op->skill
1576 ));
1577
1578 if (tmp) who->insert (tmp);
1579
1580 return 1;
1581 }
1582
1583 if (who->contr) 1533 if (who->contr)
1584 if (op->invisible) 1534 if (op->invisible)
1585 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));
1586 else 1536 else
1587 who->statusmsg (format ("You ready %s.", query_name (op))); 1537 who->statusmsg (format ("You ready %s.", query_name (op)));
1588 }
1589 1538
1590 SET_FLAG (who, FLAG_READY_SKILL); 1539 who->set_flag (FLAG_READY_SKILL);
1591 SET_FLAG (op, FLAG_APPLIED); 1540 op->set_flag (FLAG_APPLIED);
1592 change_abil (who, op); 1541 change_abil (who, op);
1593 break; 1542 break;
1594 1543
1595 case BOW: 1544 case BOW:
1596 if (op->level && (!op->name.starts_with (who->name) || op->name [who->name.length ()] != '\'')) 1545 if (op->level && (!op->name.starts_with (who->name) || op->name [who->name.length ()] != '\''))
1627 1576
1628 /*FALLTHROUGH*/ 1577 /*FALLTHROUGH*/
1629 case WAND: 1578 case WAND:
1630 case ROD: 1579 case ROD:
1631 case HORN: 1580 case HORN:
1632 /* check for skill, alter player status */
1633
1634 if (!skop)
1635 {
1636 who->failmsg (format ("The %s is broken, please report this to the dungeon master!", query_name (op)));//TODO
1637 if (tmp) who->insert (tmp);
1638 return 1;
1639 }
1640
1641 op->flag [FLAG_APPLIED] = true; 1581 op->flag [FLAG_APPLIED] = true;
1642 1582
1643 if (player *pl = who->contr) 1583 if (player *pl = who->contr)
1644 { 1584 {
1645 who->statusmsg (format ("You ready %s.", query_name (op))); 1585 who->statusmsg (format ("You ready %s.", query_name (op)));
1649 1589
1650 change_abil (who, op); 1590 change_abil (who, op);
1651 } 1591 }
1652 else 1592 else
1653 { 1593 {
1654 who->change_skill (skop);
1655
1656 if (op->type == BOW) 1594 if (op->type == BOW)
1657 op->flag [FLAG_READY_BOW ] = true; 1595 op->flag [FLAG_READY_BOW ] = true;
1658 else 1596 else
1659 op->flag [FLAG_READY_RANGE] = true; 1597 op->flag [FLAG_READY_RANGE] = true;
1660 } 1598 }
1671 1609
1672 default: 1610 default:
1673 who->statusmsg (format ("You apply %s.", query_name (op))); 1611 who->statusmsg (format ("You apply %s.", query_name (op)));
1674 } 1612 }
1675 1613
1676 SET_FLAG (op, FLAG_APPLIED); 1614 op->set_flag (FLAG_APPLIED);
1677 1615
1678 if (tmp) who->insert (tmp); 1616 if (tmp) who->insert (tmp);
1679 1617
1680 who->update_stats (); 1618 who->update_stats ();
1681 1619
1682 /* We exclude spell casting objects. The fire code will set the 1620 /* We exclude spell casting objects. The fire code will set the
1683 * been applied flag when they are used - until that point, 1621 * been applied flag when they are used - until that point,
1684 * you don't know anything about them. 1622 * you don't know anything about them.
1685 */ 1623 */
1686 if (who->type == PLAYER && op->type != WAND && op->type != HORN && op->type != ROD) 1624 if (who->type == PLAYER && op->type != WAND && op->type != HORN && op->type != ROD)
1687 SET_FLAG (op, FLAG_BEEN_APPLIED); 1625 op->set_flag (FLAG_BEEN_APPLIED);
1688 1626
1689 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 1627 if (op->flag [FLAG_CURSED] || op->flag [FLAG_DAMNED])
1690 if (who->type == PLAYER) 1628 if (who->type == PLAYER)
1691 { 1629 {
1692 who->failmsg ( 1630 who->failmsg (
1693 "Oops, it feels deadly cold! " 1631 "Oops, it feels deadly cold! "
1694 "H<Maybe it wasn't such a bright idea to apply this cursed or damned item.>" 1632 "H<Maybe it wasn't such a bright idea to apply this cursed or damned item.>"
1695 ); 1633 );
1696 SET_FLAG (op, FLAG_KNOWN_CURSED); 1634 op->set_flag (FLAG_KNOWN_CURSED);
1697 } 1635 }
1698 1636
1699 if (object *pl = op->visible_to ()) 1637 if (object *pl = op->visible_to ())
1700 esrv_send_item (pl, op); 1638 esrv_send_item (pl, op);
1701 1639
1774 return 0; 1712 return 0;
1775 1713
1776 /* 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
1777 * identified. If it doesn't, then go through the player inventory. 1715 * identified. If it doesn't, then go through the player inventory.
1778 */ 1716 */
1779 if (object *marked = find_marked_object (pl)) 1717 if (object *marked = pl->mark ())
1780 if (!QUERY_FLAG (marked, FLAG_IDENTIFIED) && need_identify (marked)) 1718 if (!marked->flag [FLAG_IDENTIFIED] && marked->need_identify ())
1781 { 1719 {
1782 if (operate_altar (altar, &money, pl)) 1720 if (operate_altar (altar, &money, pl))
1783 { 1721 {
1784 identify (marked); 1722 identify (marked);
1785 1723
1791 } 1729 }
1792 } 1730 }
1793 1731
1794 for (object *id = pl->inv; id; id = id->below) 1732 for (object *id = pl->inv; id; id = id->below)
1795 { 1733 {
1796 if (!QUERY_FLAG (id, FLAG_IDENTIFIED) && !id->invisible && need_identify (id)) 1734 if (!id->flag [FLAG_IDENTIFIED] && !id->invisible && id->need_identify ())
1797 { 1735 {
1798 if (operate_altar (altar, &money, pl)) 1736 if (operate_altar (altar, &money, pl))
1799 { 1737 {
1800 identify (id); 1738 identify (id);
1801 1739
1828 * matching item. 1766 * matching item.
1829 **/ 1767 **/
1830void 1768void
1831handle_apply_yield (object *tmp) 1769handle_apply_yield (object *tmp)
1832{ 1770{
1833 if (shstr_tmp yield = tmp->kv (shstr_on_use_yield)) 1771 if (shstr_tmp yield = tmp->kv [shstr_on_use_yield])
1834 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR); 1772 archetype::get (yield)->insert_at (tmp, tmp, INS_BELOW_ORIGINATOR);
1835} 1773}
1836 1774
1837/** 1775/**
1838 * Handles applying a potion. 1776 * Handles applying a potion.
1841apply_potion (object *op, object *tmp) 1779apply_potion (object *op, object *tmp)
1842{ 1780{
1843 int got_one = 0, i; 1781 int got_one = 0, i;
1844 object *force = 0; 1782 object *force = 0;
1845 1783
1846 object *floor = GET_MAP_OB (op->map, op->x, op->y);
1847
1848 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)
1849 { 1785 {
1850 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!");
1851 1787
1852 CLEAR_FLAG (tmp, FLAG_APPLIED); 1788 tmp->clr_flag (FLAG_APPLIED);
1853 return 0; 1789 return 0;
1854 } 1790 }
1855 1791
1856 if (op->type == PLAYER) 1792 if (op->type == PLAYER)
1857 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1793 if (!tmp->flag [FLAG_IDENTIFIED])
1858 identify (tmp); 1794 identify (tmp);
1859 1795
1860 handle_apply_yield (tmp); 1796 handle_apply_yield (tmp);
1861 1797
1862 /* Potion of restoration - only for players */ 1798 /* Potion of restoration - only for players */
1863 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) 1799 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE))
1864 { 1800 {
1865 object *depl; 1801 object *depl;
1866 archetype *at; 1802 archetype *at;
1867 1803
1868 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 1804 if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
1869 { 1805 {
1870 op->drain_stat (); 1806 op->drain_stat ();
1871 op->update_stats (); 1807 op->update_stats ();
1872 tmp->decrease (); 1808 tmp->decrease ();
1873 return 1; 1809 return 1;
1900 /* improvement potion - only for players */ 1836 /* improvement potion - only for players */
1901 if (op->type == PLAYER && (tmp->attacktype & AT_GODPOWER)) 1837 if (op->type == PLAYER && (tmp->attacktype & AT_GODPOWER))
1902 { 1838 {
1903 for (i = 1; i < min (11, op->level); i++) 1839 for (i = 1; i < min (11, op->level); i++)
1904 { 1840 {
1905 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 1841 if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
1906 { 1842 {
1907 if (op->contr->levhp[i] != 1) 1843 if (op->contr->levhp[i] != 1)
1908 { 1844 {
1909 op->contr->levhp[i] = 1; 1845 op->contr->levhp[i] = 1;
1910 break; 1846 break;
1946 1882
1947 /* Just makes checking easier */ 1883 /* Just makes checking easier */
1948 if (i < min (11, op->level)) 1884 if (i < min (11, op->level))
1949 got_one = 1; 1885 got_one = 1;
1950 1886
1951 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) 1887 if (!tmp->flag [FLAG_CURSED] && !tmp->flag [FLAG_DAMNED])
1952 { 1888 {
1953 if (got_one) 1889 if (got_one)
1954 { 1890 {
1955 op->update_stats (); 1891 op->update_stats ();
1956 op->statusmsg ("The Gods smile upon you and remake you " 1892 op->statusmsg ("The Gods smile upon you and remake you "
1981 * there is no limit to the number of spells that potions can be cast, 1917 * there is no limit to the number of spells that potions can be cast,
1982 * but direction is problematic to try and imbue fireball potions for example. 1918 * but direction is problematic to try and imbue fireball potions for example.
1983 */ 1919 */
1984 if (tmp->inv) 1920 if (tmp->inv)
1985 { 1921 {
1986 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 1922 if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
1987 { 1923 {
1988 op->failmsg ("Yech! Your lungs are on fire!"); 1924 op->failmsg ("Yech! Your lungs are on fire!");
1989 create_exploding_ball_at (op, op->level); 1925 create_exploding_ball_at (op, op->level);
1990 } 1926 }
1991 else 1927 else
1992 cast_spell (op, tmp, op->facing, tmp->inv, NULL); 1928 cast_spell (op, tmp, op->facing, tmp->inv, NULL);
1993 1929
1994 tmp->decrease (); 1930 tmp->decrease ();
1995 1931
1996 /* if youre dead, no point in doing this... */ 1932 /* if youre dead, no point in doing this... */
1997 if (!QUERY_FLAG (op, FLAG_REMOVED)) 1933 if (!op->flag [FLAG_REMOVED])
1998 op->update_stats (); 1934 op->update_stats ();
1999 1935
2000 return 1; 1936 return 1;
2001 } 1937 }
2002 1938
2005 for (i = 0; i < NROFATTACKS; i++) 1941 for (i = 0; i < NROFATTACKS; i++)
2006 { 1942 {
2007 if (tmp->resist[i]) 1943 if (tmp->resist[i])
2008 { 1944 {
2009 if (!force) 1945 if (!force)
2010 force = get_archetype (FORCE_NAME); 1946 force = archetype::get (FORCE_NAME);
2011 1947
2012 memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); 1948 memcpy (force->resist, tmp->resist, sizeof (tmp->resist));
2013 force->type = POTION_EFFECT; 1949 force->type = POTION_EFFECT;
2014 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 */
2015 } 1951 }
2017 1953
2018 /* This is a protection potion */ 1954 /* This is a protection potion */
2019 if (force) 1955 if (force)
2020 { 1956 {
2021 /* cursed items last longer */ 1957 /* cursed items last longer */
2022 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 1958 if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
2023 { 1959 {
2024 force->stats.food *= 10; 1960 force->stats.food *= 10;
2025 for (i = 0; i < NROFATTACKS; i++) 1961 for (i = 0; i < NROFATTACKS; i++)
2026 if (force->resist[i] > 0) 1962 if (force->resist[i] > 0)
2027 force->resist[i] = -force->resist[i]; /* prot => vuln */ 1963 force->resist[i] = -force->resist[i]; /* prot => vuln */
2028 } 1964 }
2029 1965
2030 force->speed_left = -1; 1966 force->speed_left = -1;
2031 force = insert_ob_in_ob (force, op); 1967 force = insert_ob_in_ob (force, op);
2032 CLEAR_FLAG (tmp, FLAG_APPLIED); 1968 tmp->clr_flag (FLAG_APPLIED);
2033 SET_FLAG (force, FLAG_APPLIED); 1969 force->set_flag (FLAG_APPLIED);
2034 change_abil (op, force); 1970 change_abil (op, force);
2035 tmp->decrease (); 1971 tmp->decrease ();
2036 return 1; 1972 return 1;
2037 } 1973 }
2038 1974
2039 /* Only thing left are the stat potions */ 1975 /* Only thing left are the stat potions */
2040 if (op->type == PLAYER) 1976 if (op->type == PLAYER)
2041 { /* only for players */ 1977 { /* only for players */
2042 if ((QUERY_FLAG (tmp, FLAG_CURSED) 1978 if ((tmp->flag [FLAG_CURSED]
2043 || QUERY_FLAG (tmp, FLAG_DAMNED)) 1979 || tmp->flag [FLAG_DAMNED])
2044 && tmp->value != 0) 1980 && tmp->value != 0)
2045 CLEAR_FLAG (tmp, FLAG_APPLIED); 1981 tmp->clr_flag (FLAG_APPLIED);
2046 else 1982 else
2047 SET_FLAG (tmp, FLAG_APPLIED); 1983 tmp->set_flag (FLAG_APPLIED);
2048 1984
2049 if (!change_abil (op, tmp)) 1985 if (!change_abil (op, tmp))
2050 op->statusmsg ("Nothing happened."); 1986 op->statusmsg ("Nothing happened.");
2051 } 1987 }
2052 1988
2053 /* CLEAR_FLAG is so that if the character has other potions 1989 /* CLEAR_FLAG is so that if the character has other potions
2054 * that were grouped with the one consumed, his 1990 * that were grouped with the one consumed, his
2055 * stat will not be raised by them. fix_player just clears 1991 * stat will not be raised by them. fix_player just clears
2056 * up all the stats. 1992 * up all the stats.
2057 */ 1993 */
2058 CLEAR_FLAG (tmp, FLAG_APPLIED); 1994 tmp->clr_flag (FLAG_APPLIED);
2059 op->update_stats (); 1995 op->update_stats ();
2060 tmp->decrease (); 1996 tmp->decrease ();
2061 return 1; 1997 return 1;
2062} 1998}
2063 1999
2073void 2009void
2074move_apply (object *trap, object *victim, object *originator) 2010move_apply (object *trap, object *victim, object *originator)
2075{ 2011{
2076 static int recursion_depth = 0; 2012 static int recursion_depth = 0;
2077 2013
2014 trap = trap->head_ ();
2015
2078 /* Only exits affect DMs. */ 2016 /* Only exits affect DMs. */
2079 if (QUERY_FLAG (victim, FLAG_WIZPASS) && trap->type != EXIT && trap->type != SIGN) 2017 if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN)
2080 return; 2018 return;
2081 2019
2082 /* move_apply() is the most likely candidate for causing unwanted and 2020 /* move_apply() is the most likely candidate for causing unwanted and
2083 * possibly unlimited recursion. 2021 * possibly unlimited recursion.
2084 */ 2022 */
2023
2085 /* The following was changed because it was causing perfectly correct 2024 /* The following was changed because it was causing perfectly correct
2086 * maps to fail. 1) it's not an error to recurse: 2025 * maps to fail. 1) it's not an error to recurse:
2087 * rune detonates, summoning monster. monster lands on nearby rune. 2026 * rune detonates, summoning monster. monster lands on nearby rune.
2088 * nearby rune detonates. This sort of recursion is expected and 2027 * nearby rune detonates. This sort of recursion is expected and
2089 * proper. This code was causing needless crashes. 2028 * proper. This code was causing needless crashes.
2094 "[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);
2095 return; 2034 return;
2096 } 2035 }
2097 2036
2098 recursion_depth++; 2037 recursion_depth++;
2099 if (trap->head)
2100 trap = trap->head;
2101 2038
2102 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)))
2103 switch (trap->type) 2040 switch (trap->type)
2104 { 2041 {
2105 case PLAYERMOVER: 2042 case PLAYERMOVER:
2115 2052
2116 /* 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
2117 * above with some objects have zero speed, and thus the player 2054 * above with some objects have zero speed, and thus the player
2118 * getting permanently paralyzed. 2055 * getting permanently paralyzed.
2119 */ 2056 */
2120 if (victim->speed_left < -50.f) 2057 victim->speed_left = max (-50.f, victim->speed_left);
2121 victim->speed_left = -50.f;
2122 /* 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); */
2123 } 2059 }
2124 break; 2060 break;
2125 2061
2126 case SPINNER: 2062 case SPINNER:
2158 case ARROW: 2094 case ARROW:
2159 /* 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 ,
2160 * 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.
2161 * 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
2162 * 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
2163 * action, we avoid hits here 2099 * action, we avoid hits here
2164 */ 2100 */
2165 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->has_active_speed ()) 2101 if ((victim->flag [FLAG_ALIVE] && trap->has_active_speed ())
2166 && trap->owner != victim) 2102 && trap->owner != victim)
2167 hit_with_arrow (trap, victim); 2103 hit_with_arrow (trap, victim);
2168 break; 2104 break;
2169 2105
2170 case SPELL_EFFECT: 2106 case SPELL_EFFECT:
2214 } 2150 }
2215 2151
2216 case CONVERTER: 2152 case CONVERTER:
2217 if (convert_item (victim, trap) < 0) 2153 if (convert_item (victim, trap) < 0)
2218 { 2154 {
2219 originator->failmsg (format ("The %s seems to be broken!", query_name (trap))); 2155 originator->failmsgf ("The %s seems to be broken!", query_name (trap));
2220 archetype::get (shstr_burnout)->insert_at (trap, trap); 2156 archetype::get (shstr_burnout)->insert_at (trap, trap);
2221 } 2157 }
2222 2158
2223 break; 2159 break;
2224 2160
2278 apply_container (victim, trap); 2214 apply_container (victim, trap);
2279 break; 2215 break;
2280 2216
2281 case RUNE: 2217 case RUNE:
2282 case TRAP: 2218 case TRAP:
2283 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) 2219 if (trap->level && victim->flag [FLAG_ALIVE])
2284 spring_trap (trap, victim); 2220 spring_trap (trap, victim);
2285 break; 2221 break;
2286 2222
2287 default: 2223 default:
2288 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " 2224 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not "
2300apply_book (object *op, object *tmp) 2236apply_book (object *op, object *tmp)
2301{ 2237{
2302 int lev_diff; 2238 int lev_diff;
2303 object *skill_ob; 2239 object *skill_ob;
2304 2240
2305 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ)) 2241 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ])
2306 { 2242 {
2307 op->failmsg ("You are unable to read while blind!"); 2243 op->failmsg ("You are unable to read while blind!");
2308 return; 2244 return;
2309 } 2245 }
2310 2246
2311 if (!tmp->msg) 2247 if (!tmp->msg)
2312 { 2248 {
2313 op->failmsg (format ("The %s contains nothing but meaningless gibberish. H<There is nothing interesting to read here.>", &tmp->name)); 2249 op->failmsgf ("The %s contains nothing but meaningless gibberish. H<There is nothing interesting to read here.>", &tmp->name);
2314 return; 2250 return;
2315 } 2251 }
2316 2252
2317 /* need a literacy skill to read stuff! */ 2253 /* need a literacy skill to read stuff! */
2318 skill_ob = find_skill_by_name (op, tmp->skill); 2254 skill_ob = find_skill_by_name (op, tmp->skill);
2319 if (!skill_ob) 2255 if (!skill_ob)
2320 { 2256 {
2321 op->failmsg (format ("You are unable to decipher the strange symbols. H<You lack the %s skill to read this.>", &tmp->skill)); 2257 op->failmsgf ("You are unable to decipher the strange symbols. H<You lack the %s skill to read this.>", &tmp->skill);
2322 return; 2258 return;
2323 } 2259 }
2324 2260
2325 lev_diff = tmp->level - (skill_ob->level + 5); 2261 lev_diff = tmp->level - (skill_ob->level + 5);
2326 if (!QUERY_FLAG (op, FLAG_WIZ) && lev_diff > 0) 2262 if (!op->flag [FLAG_WIZ] && lev_diff > 0)
2327 { 2263 {
2328 op->failmsg (lev_diff < 2 ? "This book is just barely beyond your comprehension." 2264 op->failmsg (lev_diff < 2 ? "This book is just barely beyond your comprehension."
2329 : lev_diff < 3 ? "This book is slightly beyond your comprehension." 2265 : lev_diff < 3 ? "This book is slightly beyond your comprehension."
2330 : lev_diff < 5 ? "This book is beyond your comprehension." 2266 : lev_diff < 5 ? "This book is beyond your comprehension."
2331 : lev_diff < 8 ? "This book is quite a bit beyond your comprehension." 2267 : lev_diff < 8 ? "This book is quite a bit beyond your comprehension."
2342 if (player *pl = op->contr) 2278 if (player *pl = op->contr)
2343 if (client *ns = pl->ns) 2279 if (client *ns = pl->ns)
2344 pl->infobox (MSG_CHANNEL ("book"), format ("T<%s>\n\n%s", (char *)long_desc (tmp, op), &tmp->msg)); 2280 pl->infobox (MSG_CHANNEL ("book"), format ("T<%s>\n\n%s", (char *)long_desc (tmp, op), &tmp->msg));
2345 2281
2346 /* gain xp from reading */ 2282 /* gain xp from reading */
2347 if (!QUERY_FLAG (tmp, FLAG_NO_SKILL_IDENT)) 2283 if (!tmp->flag [FLAG_NO_SKILL_IDENT])
2348 { /* only if not read before */ 2284 { /* only if not read before */
2349 int exp_gain = calc_skill_exp (op, tmp, skill_ob); 2285 int exp_gain = calc_skill_exp (op, tmp, skill_ob);
2350 2286
2351 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 2287 if (!tmp->flag [FLAG_IDENTIFIED])
2352 { 2288 {
2353 /*exp_gain *= 2; because they just identified it too */ 2289 /*exp_gain *= 2; because they just identified it too */
2354 SET_FLAG (tmp, FLAG_IDENTIFIED); 2290 tmp->set_flag (FLAG_IDENTIFIED);
2355 2291
2356 if (object *pl = tmp->visible_to ()) 2292 if (object *pl = tmp->visible_to ())
2357 esrv_update_item (UPD_FLAGS | UPD_NAME, pl, tmp); 2293 esrv_update_item (UPD_FLAGS | UPD_NAME, pl, tmp);
2358 } 2294 }
2359 2295
2360 change_exp (op, exp_gain, skill_ob->skill, 0); 2296 change_exp (op, exp_gain, skill_ob->skill, 0);
2361 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */ 2297 tmp->set_flag (FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
2362 } 2298 }
2363} 2299}
2364 2300
2365/** 2301/**
2366 * op made some mistake with a scroll, this takes care of punishment. 2302 * op made some mistake with a scroll, this takes care of punishment.
2375 if (failure <= -1 && failure > -15) 2311 if (failure <= -1 && failure > -15)
2376 { /* wonder */ 2312 { /* wonder */
2377 object *tmp; 2313 object *tmp;
2378 2314
2379 op->failmsg ("Your spell warps!"); 2315 op->failmsg ("Your spell warps!");
2380 tmp = get_archetype (SPELL_WONDER); 2316 tmp = archetype::get (SPELL_WONDER);
2381 cast_wonder (op, op, 0, tmp); 2317 cast_wonder (op, op, 0, tmp);
2382 tmp->destroy (); 2318 tmp->destroy ();
2383 } 2319 }
2384 else if (failure <= -15 && failure > -35) 2320 else if (failure <= -15 && failure > -35)
2385 { /* drain mana */ 2321 { /* drain mana */
2405 op->failmsg ("The magic recoils on you!"); 2341 op->failmsg ("The magic recoils on you!");
2406 blind_player (op, op, power); 2342 blind_player (op, op, power);
2407 } 2343 }
2408 else if (failure <= -80) 2344 else if (failure <= -80)
2409 { /* blast the immediate area */ 2345 { /* blast the immediate area */
2410 object *tmp = get_archetype (LOOSE_MANA); 2346 object *tmp = archetype::get (LOOSE_MANA);
2411 cast_magic_storm (op, tmp, power); 2347 cast_magic_storm (op, tmp, power);
2412 op->failmsg ("You unleash uncontrolled mana!"); 2348 op->failmsg ("You unleash uncontrolled mana!");
2413 tmp->destroy (); 2349 tmp->destroy ();
2414 } 2350 }
2415 } 2351 }
2424{ 2360{
2425 switch (learn_skill (op, tmp)) 2361 switch (learn_skill (op, tmp))
2426 { 2362 {
2427 case 0: 2363 case 0:
2428 op->play_sound (sound_find ("generic_fail")); 2364 op->play_sound (sound_find ("generic_fail"));
2429 op->failmsg (format ("You already possess the knowledge held within the %s.", query_name (tmp))); 2365 op->failmsgf ("You already possess the knowledge held within the %s.", query_name (tmp));
2430 break; 2366 break;
2431 2367
2432 case 1: 2368 case 1:
2433 tmp->decrease (); 2369 tmp->decrease ();
2434 op->play_sound (sound_find ("skill_learn")); 2370 op->play_sound (sound_find ("skill_learn"));
2436 break; 2372 break;
2437 2373
2438 default: 2374 default:
2439 tmp->decrease (); 2375 tmp->decrease ();
2440 op->play_sound (sound_find ("generic_fail")); 2376 op->play_sound (sound_find ("generic_fail"));
2441 op->failmsg (format ("You fail to learn the knowledge of the %s.\n", query_name (tmp))); 2377 op->failmsgf ("You fail to learn the knowledge of the %s.\n", query_name (tmp));
2442 break; 2378 break;
2443 } 2379 }
2444} 2380}
2445 2381
2446/** 2382/**
2459 } 2395 }
2460 2396
2461 /* Upgrade special prayers to normal prayers */ 2397 /* Upgrade special prayers to normal prayers */
2462 if ((tmp = check_spell_known (op, spell->name)) != NULL) 2398 if ((tmp = check_spell_known (op, spell->name)) != NULL)
2463 { 2399 {
2464 if (special_prayer && !QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 2400 if (special_prayer && !tmp->flag [FLAG_STARTEQUIP])
2465 { 2401 {
2466 LOG (llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n"); 2402 LOG (llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
2467 return; 2403 return;
2468 } 2404 }
2469 return; 2405 return;
2473 2409
2474 tmp = spell->clone (); 2410 tmp = spell->clone ();
2475 insert_ob_in_ob (tmp, op); 2411 insert_ob_in_ob (tmp, op);
2476 2412
2477 if (special_prayer) 2413 if (special_prayer)
2478 SET_FLAG (tmp, FLAG_STARTEQUIP); 2414 tmp->set_flag (FLAG_STARTEQUIP);
2479 2415
2480 esrv_add_spells (op->contr, tmp); 2416 esrv_add_spells (op->contr, tmp);
2481} 2417}
2482 2418
2483/** 2419/**
2497 { 2433 {
2498 LOG (llevError, "BUG: do_forget_spell(): spell not known\n"); 2434 LOG (llevError, "BUG: do_forget_spell(): spell not known\n");
2499 return; 2435 return;
2500 } 2436 }
2501 2437
2502 op->failmsg (format ("You lose knowledge of %s.", spell)); 2438 op->failmsgf ("You lose knowledge of %s.", spell);
2503 esrv_remove_spell (op->contr, spob); 2439 esrv_remove_spell (op->contr, spob);
2504 spob->destroy (); 2440 spob->destroy ();
2505} 2441}
2506 2442
2507/** 2443/**
2512static void 2448static void
2513apply_spellbook (object *op, object *tmp) 2449apply_spellbook (object *op, object *tmp)
2514{ 2450{
2515 object *skop, *spell, *spell_skill; 2451 object *skop, *spell, *spell_skill;
2516 2452
2517 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ)) 2453 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ])
2518 { 2454 {
2519 op->failmsg ("You are unable to read while blind."); 2455 op->failmsg ("You are unable to read while blind.");
2520 return; 2456 return;
2521 } 2457 }
2522 2458
2528 { 2464 {
2529 spell = find_archetype_by_object_name (tmp->slaying)->instance (); 2465 spell = find_archetype_by_object_name (tmp->slaying)->instance ();
2530 2466
2531 if (!spell) 2467 if (!spell)
2532 { 2468 {
2533 op->failmsg (format ("The book's formula for %s is incomplete.", &tmp->slaying)); 2469 op->failmsgf ("The book's formula for %s is incomplete.", &tmp->slaying);
2534 return; 2470 return;
2535 } 2471 }
2536 else 2472 else
2537 insert_ob_in_ob (spell, tmp); 2473 insert_ob_in_ob (spell, tmp);
2538 2474
2543 2479
2544 /* need a literacy skill to learn spells. Also, having a literacy level 2480 /* need a literacy skill to learn spells. Also, having a literacy level
2545 * lower than the spell will make learning the spell more difficult */ 2481 * lower than the spell will make learning the spell more difficult */
2546 if (!skop) 2482 if (!skop)
2547 { 2483 {
2548 op->failmsg (format ("You can't read! Your attempt fails. H<You lack the %s skill.>", &tmp->skill)); 2484 op->failmsgf ("You can't read! Your attempt fails. H<You lack the %s skill.>", &tmp->skill);
2549 return; 2485 return;
2550 } 2486 }
2551 2487
2552 spell = tmp->inv; 2488 spell = tmp->inv;
2553 2489
2559 } 2495 }
2560 2496
2561 int learn_level = sqrtf (spell->level) * 1.5f; 2497 int learn_level = sqrtf (spell->level) * 1.5f;
2562 if (skop->level < learn_level) 2498 if (skop->level < learn_level)
2563 { 2499 {
2564 op->failmsg (format ("You are unable to decipher the strange symbols. H<Your %s level is too low, it must be at least %d.>", 2500 op->failmsgf ("You are unable to decipher the strange symbols. H<Your %s level is too low, it must be at least %d.>",
2565 &tmp->skill, learn_level)); 2501 &tmp->skill, learn_level);
2566 return; 2502 return;
2567 } 2503 }
2568 2504
2569 op->statusmsg (format ("The spellbook contains the %s level spell %s.", ordinal (spell->level), &spell->name)); 2505 op->statusmsg (format ("The spellbook contains the %s level spell %s.", ordinal (spell->level), &spell->name));
2570 2506
2571 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 2507 if (!tmp->flag [FLAG_IDENTIFIED])
2572 identify (tmp); 2508 identify (tmp);
2573 2509
2574 /* I removed the check for special_prayer_mark here - it didn't make 2510 /* I removed the check for special_prayer_mark here - it didn't make
2575 * a lot of sense - special prayers are not found in spellbooks, and 2511 * a lot of sense - special prayers are not found in spellbooks, and
2576 * if the player doesn't know the spell, doesn't make a lot of sense that 2512 * if the player doesn't know the spell, doesn't make a lot of sense that
2586 { 2522 {
2587 spell_skill = find_skill_by_name (op, spell->skill); 2523 spell_skill = find_skill_by_name (op, spell->skill);
2588 2524
2589 if (!spell_skill) 2525 if (!spell_skill)
2590 { 2526 {
2591 op->failmsg (format ("You lack the %s skill to use this spell.", &spell->skill)); 2527 op->failmsgf ("You lack the %s skill to use this spell.", &spell->skill);
2592 return; 2528 return;
2593 } 2529 }
2594 2530
2595 if (spell_skill->level < spell->level) 2531 if (spell_skill->level < spell->level)
2596 { 2532 {
2597 op->failmsg (format ("You need to be level %d in %s to learn this spell.", spell->level, &spell->skill)); 2533 op->failmsgf ("You need to be level %d in %s to learn this spell.", spell->level, &spell->skill);
2598 return; 2534 return;
2599 } 2535 }
2600 } 2536 }
2601 2537
2602 /* Logic as follows 2538 /* Logic as follows
2609 * 3 -Automatically fail to learn if you read while confused 2545 * 3 -Automatically fail to learn if you read while confused
2610 * 2546 *
2611 * 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
2612 * literacy rate very useful! -b.t. 2548 * literacy rate very useful! -b.t.
2613 */ 2549 */
2614 if (QUERY_FLAG (op, FLAG_CONFUSED)) 2550 if (op->flag [FLAG_CONFUSED])
2615 { 2551 {
2616 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!");
2617 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));
2618 } 2554 }
2619 else if (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || 2555 else if (tmp->flag [FLAG_STARTEQUIP] ||
2620 (random_roll (0, 100, op, PREFER_LOW) - (5 * skop->level)) < learn_spell[spell->stats.grace ? op->stats.Wis : op->stats.Int]) 2556 (random_roll (0, 100, op, PREFER_LOW) - (5 * skop->level)) < learn_spell[spell->stats.grace ? op->stats.Wis : op->stats.Int])
2621 { 2557 {
2622 op->statusmsg ("You succeed in learning the spell!", NDI_GREEN); 2558 op->statusmsg ("You succeed in learning the spell!", NDI_GREEN);
2623 do_learn_spell (op, spell, 0); 2559 do_learn_spell (op, spell, 0);
2624 2560
2625 /* xp gain to literacy for spell learning */ 2561 /* xp gain to literacy for spell learning */
2626 if (!QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 2562 if (!tmp->flag [FLAG_STARTEQUIP])
2627 change_exp (op, calc_skill_exp (op, tmp, skop), skop->skill, 0); 2563 change_exp (op, calc_skill_exp (op, tmp, skop), skop->skill, 0);
2628 } 2564 }
2629 else 2565 else
2630 { 2566 {
2631 op->contr->play_sound (sound_find ("fumble_spell")); 2567 op->contr->play_sound (sound_find ("fumble_spell"));
2641void 2577void
2642apply_scroll (object *op, object *tmp, int dir) 2578apply_scroll (object *op, object *tmp, int dir)
2643{ 2579{
2644 object *skop; 2580 object *skop;
2645 2581
2646 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ)) 2582 if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ])
2647 { 2583 {
2648 op->failmsg ("You are unable to read while blind."); 2584 op->failmsg ("You are unable to read while blind.");
2649 return; 2585 return;
2650 } 2586 }
2651 2587
2661 int exp_gain = 0; 2597 int exp_gain = 0;
2662 2598
2663 /* hard code literacy - tmp->skill points to where the exp 2599 /* hard code literacy - tmp->skill points to where the exp
2664 * should go for anything killed by the spell. 2600 * should go for anything killed by the spell.
2665 */ 2601 */
2666 skop = find_skill_by_name (op, skill_names[SK_LITERACY]); 2602 skop = find_skill_by_name (op, shstr_literacy);
2667 2603
2668 if (!skop) 2604 if (!skop)
2669 { 2605 {
2670 op->failmsg (format ("You are unable to decipher the strange symbols. H<You lack the %s skill.>", &skill_names[SK_LITERACY])); 2606 op->failmsgf ("You are unable to decipher the strange symbols. H<You lack the literacy skill.>");
2671 return; 2607 return;
2672 } 2608 }
2673 2609
2674 if ((exp_gain = calc_skill_exp (op, tmp, skop))) 2610 if ((exp_gain = calc_skill_exp (op, tmp, skop)))
2675 change_exp (op, exp_gain, skop->skill, 0); 2611 change_exp (op, exp_gain, skop->skill, 0);
2676 } 2612 }
2677 2613
2678 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 2614 if (!tmp->flag [FLAG_IDENTIFIED])
2679 identify (tmp); 2615 identify (tmp);
2680 2616
2681 op->statusmsg (format ("The scroll of %s turns to dust.", &tmp->inv->name)); 2617 op->statusmsg (format ("The scroll of %s turns to dust.", &tmp->inv->name));
2682 2618
2683 cast_spell (op, tmp, dir, tmp->inv, NULL); 2619 cast_spell (op, tmp, dir, tmp->inv, NULL);
2714 2650
2715 treas->x = op->x; 2651 treas->x = op->x;
2716 treas->y = op->y; 2652 treas->y = op->y;
2717 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR); 2653 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2718 2654
2719 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE)) 2655 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && op->flag [FLAG_ALIVE])
2720 spring_trap (treas, op); 2656 spring_trap (treas, op);
2721 2657
2722 /* If either player or container was destroyed, no need to do 2658 /* If either player or container was destroyed, no need to do
2723 * further processing. I think this should be enclused with 2659 * further processing. I think this should be enclused with
2724 * spring trap above, as I don't think there is otherwise 2660 * spring trap above, as I don't think there is otherwise
2923 : tmp->type == DRINK 2859 : tmp->type == DRINK
2924 ? sound_find ("eat_drink") 2860 ? sound_find ("eat_drink")
2925 : sound_find ("eat_food") 2861 : sound_find ("eat_food")
2926 ); 2862 );
2927 2863
2928 if (!QUERY_FLAG (tmp, FLAG_CURSED)) 2864 if (!tmp->flag [FLAG_CURSED])
2929 { 2865 {
2930 const char *buf; 2866 const char *buf;
2931 2867
2932 if (!op->is_dragon ()) 2868 if (!op->is_dragon ())
2933 { 2869 {
2953 min_it (op->stats.hp, op->stats.maxhp); 2889 min_it (op->stats.hp, op->stats.maxhp);
2954 min_it (op->stats.food, MAX_FOOD); 2890 min_it (op->stats.food, MAX_FOOD);
2955 } 2891 }
2956 2892
2957 /* special food hack -b.t. */ 2893 /* special food hack -b.t. */
2958 if (tmp->title || QUERY_FLAG (tmp, FLAG_CURSED)) 2894 if (tmp->title || tmp->flag [FLAG_CURSED])
2959 eat_special_food (op, tmp); 2895 eat_special_food (op, tmp);
2960 } 2896 }
2961 } 2897 }
2962 2898
2963 handle_apply_yield (tmp); 2899 handle_apply_yield (tmp);
2969 * Does some sanity checks, then calls improve_armour. 2905 * Does some sanity checks, then calls improve_armour.
2970 */ 2906 */
2971static void 2907static void
2972apply_armour_improver (object *op, object *tmp) 2908apply_armour_improver (object *op, object *tmp)
2973{ 2909{
2974 object *armor;
2975
2976 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, 0, op->x, op->y, 0, 0) & P_NO_MAGIC)) 2910 if (!op->flag [FLAG_WIZCAST] && (get_map_flags (op->map, 0, op->x, op->y, 0, 0) & P_NO_MAGIC))
2977 { 2911 {
2978 op->failmsg ("Something blocks the magic of the scroll. H<This area prevents magic effects.>"); 2912 op->failmsg ("Something blocks the magic of the scroll. H<This area prevents magic effects.>");
2979 return; 2913 return;
2980 } 2914 }
2981 2915
2982 armor = find_marked_object (op); 2916 object *armor = op->mark ();
2983 2917
2984 if (!armor) 2918 if (!armor)
2985 { 2919 {
2986 op->failmsg ("You need to mark an armor object. Use the right mouse button popup or the mark command to do this."); 2920 op->failmsg ("You need to mark an armor object. Use the right mouse button popup or the mark command to do this.");
2987 return; 2921 return;
2990 if (armor->type != ARMOUR 2924 if (armor->type != ARMOUR
2991 && armor->type != CLOAK 2925 && armor->type != CLOAK
2992 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET) 2926 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET)
2993 { 2927 {
2994 op->failmsg ("Your marked item is not armour!\n"); 2928 op->failmsg ("Your marked item is not armour!\n");
2929 return;
2930 }
2931
2932 if (!op->apply (armor, AP_UNAPPLY))
2933 {
2934 op->failmsg ("You are unable to take off your armour to improve it!");
2995 return; 2935 return;
2996 } 2936 }
2997 2937
2998 op->statusmsg ("Applying armour enchantment."); 2938 op->statusmsg ("Applying armour enchantment.");
2999 improve_armour (op, tmp, armor); 2939 improve_armour (op, tmp, armor);
3047 } 2987 }
3048 } 2988 }
3049 2989
3050 if (!lighter) 2990 if (!lighter)
3051 { 2991 {
3052 who->failmsg (format ( 2992 who->failmsgf (
3053 "You can't light up the %s with your bare hands! " 2993 "You can't light up the %s with your bare hands! "
3054 "H<You need a lighter in your inventory, for example a flint and steel.>", 2994 "H<You need a lighter in your inventory, for example a flint and steel.>",
3055 &op->name)); 2995 &op->name
2996 );
3056 return 0; 2997 return 0;
3057 } 2998 }
3058 } 2999 }
3059 3000
3060 // last_eat == 0 means the lighter is not being used up! 3001 // last_eat == 0 means the lighter is not being used up!
3066 who->insert (lighter); 3007 who->insert (lighter);
3067 } 3008 }
3068 else if (lighter->last_eat) 3009 else if (lighter->last_eat)
3069 { 3010 {
3070 /* no charges left in lighter */ 3011 /* no charges left in lighter */
3071 who->failmsg (format ( 3012 who->failmsgf (
3072 "You attempt to light the %s with a used up %s.", 3013 "You attempt to light the %s with a used up %s.",
3073 &op->name, &lighter->name)); 3014 &op->name, &lighter->name
3015 );
3074 return 0; 3016 return 0;
3075 } 3017 }
3076 3018
3077 return lighter; 3019 return lighter;
3078} 3020}
3083 * the selected object to "burn". -b.t. 3025 * the selected object to "burn". -b.t.
3084 */ 3026 */
3085static void 3027static void
3086apply_lighter (object *who, object *lighter) 3028apply_lighter (object *who, object *lighter)
3087{ 3029{
3088 object *item; 3030 if (object *item = who->mark ())
3089 int is_player_env = 0;
3090
3091 item = find_marked_object (who);
3092 if (item)
3093 { 3031 {
3094 if (!auto_apply_lighter (who, item, lighter)) 3032 if (!auto_apply_lighter (who, item, lighter))
3095 return; 3033 return;
3096 3034
3097 /* Perhaps we should split what we are trying to light on fire? 3035 /* Perhaps we should split what we are trying to light on fire?
3104 if (item->destroyed () 3042 if (item->destroyed ()
3105 || ((item->type == LAMP || item->type == TORCH) 3043 || ((item->type == LAMP || item->type == TORCH)
3106 && item->glow_radius > 0)) 3044 && item->glow_radius > 0))
3107 who->statusmsg (format ( 3045 who->statusmsg (format (
3108 "You light the %s with the %s.", 3046 "You light the %s with the %s.",
3109 &item->name, &lighter->name)); 3047 &item->name, &lighter->name
3048 ));
3110 else 3049 else
3111 who->failmsg (format ( 3050 who->failmsgf (
3112 "You attempt to light the %s with the %s and fail.", 3051 "You attempt to light the %s with the %s and fail.",
3113 &item->name, &lighter->name)); 3052 &item->name, &lighter->name
3053 );
3114 } 3054 }
3115 else 3055 else
3116 who->failmsg ("You need to mark a lightable object."); 3056 who->failmsg ("You need to mark a lightable object.");
3117} 3057}
3118 3058
3122static void 3062static void
3123player_apply_lamp_cursed_effect (object *who, object *op) 3063player_apply_lamp_cursed_effect (object *who, object *op)
3124{ 3064{
3125 if (op->level) 3065 if (op->level)
3126 { 3066 {
3127 who->failmsg (format ( 3067 who->failmsgf (
3128 "The %s was cursed, it explodes in a big fireball!", 3068 "The %s was cursed, it explodes in a big fireball!",
3129 &op->name)); 3069 &op->name
3070 );
3130 create_exploding_ball_at (who, op->level); 3071 create_exploding_ball_at (who, op->level);
3131 } 3072 }
3132 else 3073 else
3133 { 3074 {
3134 who->failmsg (format ( 3075 who->failmsgf (
3135 "The %s was cursed, it crumbles to dust, at least it didn't explode.!", 3076 "The %s was cursed, it crumbles to dust, at least it didn't explode.!",
3136 &op->name)); 3077 &op->name
3078 );
3137 } 3079 }
3138 3080
3139 op->destroy (); 3081 op->destroy ();
3140} 3082}
3141 3083
3159 return; 3101 return;
3160 3102
3161 if (op->stats.food < 1) 3103 if (op->stats.food < 1)
3162 { 3104 {
3163 if (op->type == LAMP) 3105 if (op->type == LAMP)
3164 who->failmsg (format ( 3106 who->failmsgf (
3165 "The %s is out of fuel! " 3107 "The %s is out of fuel! "
3166 "H<Lamps and similar items need fuel. They cannot be refilled.>", 3108 "H<Lamps and similar items need fuel. They cannot be refilled.>",
3167 &op->name)); 3109 &op->name
3110 );
3168 else 3111 else
3169 who->failmsg (format ( 3112 who->failmsgf (
3170 "The %s is burnt out! " 3113 "The %s is burnt out! "
3171 "H<Torches and similar items burn out and become worthless.>", 3114 "H<Torches and similar items burn out and become worthless.>",
3172 &op->name)); 3115 &op->name
3116 );
3173 return; 3117 return;
3174 } 3118 }
3175 3119
3176 if (op->flag [FLAG_CURSED]) 3120 if (op->flag [FLAG_CURSED])
3177 { 3121 {
3282 * The 'slaying' field for transformer is used as verb for the action. 3226 * The 'slaying' field for transformer is used as verb for the action.
3283 */ 3227 */
3284static void 3228static void
3285apply_item_transformer (object *pl, object *transformer) 3229apply_item_transformer (object *pl, object *transformer)
3286{ 3230{
3287 object *marked;
3288 object *new_item; 3231 object *new_item;
3289 const char *find; 3232 const char *find;
3290 char *separator; 3233 char *separator;
3291 int yield; 3234 int yield;
3292 char got[MAX_BUF]; 3235 char got[MAX_BUF];
3293 int len; 3236 int len;
3294 3237
3295 if (!pl || !transformer) 3238 if (!pl || !transformer)
3296 return; 3239 return;
3297 3240
3298 marked = find_marked_object (pl); 3241 object *marked = pl->mark ();
3299 3242
3300 if (!marked) 3243 if (!marked)
3301 { 3244 {
3302 pl->failmsg (format ("Use the %s with what item?", query_name (transformer))); 3245 pl->failmsgf ("Use the %s with what item?", query_name (transformer));
3303 return; 3246 return;
3304 } 3247 }
3305 3248
3306 if (!marked->slaying) 3249 if (!marked->slaying)
3307 { 3250 {
3308 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked))); 3251 pl->failmsgf ("You can't use the %s with your %s!", query_name (transformer), query_name (marked));
3309 return; 3252 return;
3310 } 3253 }
3311 3254
3312 /* check whether they are compatible or not */ 3255 /* check whether they are compatible or not */
3313 find = strstr (&marked->slaying, transformer->arch->archname); 3256 find = strstr (&marked->slaying, transformer->arch->archname);
3314 if (!find || (*(find + strlen (transformer->arch->archname)) != ':')) 3257 if (!find || (*(find + strlen (transformer->arch->archname)) != ':'))
3315 { 3258 {
3316 pl->failmsg (format ("You can't use the %s with your %s!", query_name (transformer), query_name (marked))); 3259 pl->failmsgf ("You can't use the %s with your %s!", query_name (transformer), query_name (marked));
3317 return; 3260 return;
3318 } 3261 }
3319 3262
3320 find += strlen (transformer->arch->archname) + 1; 3263 find += strlen (transformer->arch->archname) + 1;
3321 /* Item can be used, now find how many and what it yields */ 3264 /* Item can be used, now find how many and what it yields */
3348 3291
3349 strcpy (got, find); 3292 strcpy (got, find);
3350 got[len] = '\0'; 3293 got[len] = '\0';
3351 3294
3352 /* Now create new item, remove used ones when required. */ 3295 /* Now create new item, remove used ones when required. */
3353 new_item = get_archetype (got); 3296 new_item = archetype::get (got);
3354 if (!new_item) 3297 if (!new_item)
3355 { 3298 {
3356 pl->failmsg (format ("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));
3357 return; 3300 return;
3358 } 3301 }
3359 3302
3360 new_item->nrof = yield; 3303 new_item->nrof = yield;
3361 3304
3385 * them in this function - they are passed to apply_special 3328 * them in this function - they are passed to apply_special
3386 */ 3329 */
3387static bool 3330static bool
3388manual_apply (object *who, object *op, int aflag) 3331manual_apply (object *who, object *op, int aflag)
3389{ 3332{
3390 op = op->head_ ();
3391
3392 if (op->flag [FLAG_UNPAID] && !op->flag [FLAG_APPLIED])
3393 {
3394 if (who->contr)
3395 {
3396 examine (who, op);
3397 //who->failmsg ("You should pay for it first! H<You cannot use items marked as unpaid.>");//TODO remove
3398 return 1;
3399 }
3400 else
3401 return 0; /* monsters just skip unpaid items */
3402 }
3403
3404 if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who))) 3333 if (INVOKE_OBJECT (APPLY, op, ARG_OBJECT (who)))
3405 return RESULT_INT (0); 3334 return RESULT_INT (0);
3406 else if (apply_types_inv_only [op->type]) 3335 else if (apply_types_inv_only [op->type])
3407 { 3336 {
3408 // special item, using slot system, needs to be in inv 3337 // special item, using slot system, needs to be in inv
3409 if (op->env == who) 3338 if (op->env == who)
3410 return apply_special (who, op, aflag); 3339 return apply_special (who, op, aflag);
3411 3340
3412 who->failmsg (format ("You must get it first! H<You can only apply the %s if it is in your inventory.>\n", query_name (op))); 3341 who->failmsgf ("You must get it first! H<You can only apply the %s if it is in your inventory.>\n", query_name (op));
3413 } 3342 }
3414 else if (!who->contr && apply_types_player_only [op->type]) 3343 else if (!who->contr && apply_types_player_only [op->type])
3415 return 0; // monsters shouldn't try to apply player-only stuff 3344 return 0; // monsters shouldn't try to apply player-only stuff
3416 else if (apply_types [op->type]) 3345 else if (apply_types [op->type])
3417 { 3346 {
3438 3367
3439 break; 3368 break;
3440 3369
3441 case EXIT: 3370 case EXIT:
3442 if (!EXIT_PATH (op)) 3371 if (!EXIT_PATH (op))
3443 who->failmsg (format ("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));
3444 else 3373 else
3445 { 3374 {
3446 /* Don't display messages for random maps. */ 3375 /* Don't display messages for random maps. */
3447 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit) 3376 if (op->msg && EXIT_PATH (op) != shstr_random_map_exit)
3448 who->statusmsg (op->msg, NDI_NAVY); 3377 who->statusmsg (op->msg, NDI_NAVY);
3521 check_improve_weapon (who, op); 3450 check_improve_weapon (who, op);
3522 break; 3451 break;
3523 3452
3524 case CLOCK: 3453 case CLOCK:
3525 { 3454 {
3526 char buf[MAX_BUF];
3527 timeofday_t tod; 3455 timeofday_t tod;
3528 3456
3529 get_tod (&tod); 3457 get_tod (&tod);
3530 who->play_sound (sound_find ("sound_clock")); 3458 who->play_sound (sound_find ("sound_clock"));
3531 who->statusmsg (format ( 3459 who->statusmsg (format (
3555 3483
3556 return 1; 3484 return 1;
3557 } 3485 }
3558 else 3486 else
3559 { 3487 {
3560 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)));
3561 return 0; 3489 return 0;
3562 } 3490 }
3563} 3491}
3564 3492
3565/** 3493/**
3576 * item in the container. Otherwise, use the map. 3504 * item in the container. Otherwise, use the map.
3577 */ 3505 */
3578 3506
3579 // first try to apply "applyables" 3507 // first try to apply "applyables"
3580 for (object *tmp = top; tmp; tmp = tmp->below) 3508 for (object *tmp = top; tmp; tmp = tmp->below)
3581 // the tmp->cb is a hack to allow user-extendable types...
3582 if (!tmp->invisible && (apply_types [tmp->type] || tmp->cb)) 3509 if (!tmp->invisible && apply_types [tmp->type])
3583 { 3510 {
3584 // If it is visible, player can apply it. 3511 // If it is visible, player can apply it.
3585 pl->apply (tmp); 3512 pl->apply (tmp);
3586 return; 3513 return;
3587 } 3514 }
3600 case ALTAR: 3527 case ALTAR:
3601 case IDENTIFY_ALTAR: 3528 case IDENTIFY_ALTAR:
3602 case TRIGGER_ALTAR: 3529 case TRIGGER_ALTAR:
3603 case CONVERTER: 3530 case CONVERTER:
3604 //case TRIGGER_PEDESTAL: 3531 //case TRIGGER_PEDESTAL:
3605 pl->failmsg (format ( 3532 pl->failmsgf (
3606 "You see no obvious mechanism on the %s." 3533 "You see no obvious mechanism on the %s."
3607 "H<You have to drop one or more specific items here.>", 3534 "H<You have to drop one or more specific items here.>",
3608 query_short_name (top) 3535 query_short_name (top)
3609 )); 3536 );
3610 break; 3537 break;
3611 3538
3612 case BUTTON: 3539 case BUTTON:
3613 case TRIGGER_BUTTON: 3540 case TRIGGER_BUTTON:
3614 pl->failmsg (format ( 3541 pl->failmsgf (
3615 "The %s looks as if you could activate it with somehting heavy. " 3542 "The %s looks as if you could activate it with somehting heavy. "
3616 "H<You must put enough items here to activate it.>", 3543 "H<You must put enough items here to activate it.>",
3617 query_short_name (top) 3544 query_short_name (top)
3618 )); 3545 );
3619 break; 3546 break;
3620 3547
3621 default: 3548 default:
3622 examine (pl, top); 3549 examine (pl, top);
3623 break; 3550 break;
3628bool 3555bool
3629object::apply (object *ob, int aflags) 3556object::apply (object *ob, int aflags)
3630{ 3557{
3631 if (!ob) // simplifies a lot of callers 3558 if (!ob) // simplifies a lot of callers
3632 return true; 3559 return true;
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 }
3633 3574
3634 if (contr) 3575 if (contr)
3635 { 3576 {
3636 if (!ob->env && (move_type & MOVE_FLYING)) 3577 if (!ob->env && (move_type & MOVE_FLYING))
3637 { 3578 {
3651 bool want_apply = 3592 bool want_apply =
3652 aflags & AP_APPLY ? true 3593 aflags & AP_APPLY ? true
3653 : aflags & AP_UNAPPLY ? false 3594 : aflags & AP_UNAPPLY ? false
3654 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE 3595 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE
3655 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
3656 object_ptr *slot = 0; 3607 object_ptr *slot = 0;
3657 3608
3658 // detect the slot, if this is a player 3609 // detect the slot, if this is a player
3659 if (contr && !(aflags & AP_NO_SLOT)) 3610 if (contr && !(aflags & AP_NO_SLOT))
3660 { 3611 {
3665 case WEAPON: 3616 case WEAPON:
3666 slot = &contr->combat_ob; 3617 slot = &contr->combat_ob;
3667 oslot = contr->ranged_ob; 3618 oslot = contr->ranged_ob;
3668 break; 3619 break;
3669 3620
3621 case RANGED:
3670 case BOW: 3622 case BOW:
3671 case RANGED:
3672 case SPELL: 3623 case SPELL:
3673 case WAND: 3624 case WAND:
3674 case ROD: 3625 case ROD:
3675 case HORN: 3626 case HORN:
3676 case BUILDER: 3627 case BUILDER:
3678 oslot = contr->combat_ob; 3629 oslot = contr->combat_ob;
3679 break; 3630 break;
3680 3631
3681 // oh, the humanity 3632 // oh, the humanity
3682 case SKILL: 3633 case SKILL:
3683 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))
3684 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 }
3685 3665
3686 if (skill_flags [ob->subtype] & SF_NEED_ITEM) 3666 if (skill_flags [ob->subtype] & SF_NEED_ITEM)
3687 break; 3667 break;
3688 3668
3689 if (skill_flags [ob->subtype] & SF_COMBAT) 3669 if (skill_flags [ob->subtype] & SF_COMBAT)
3706 // only one slot can be active 3686 // only one slot can be active
3707 if (want_apply) 3687 if (want_apply)
3708 { 3688 {
3709 // clear slot unless we are in it already 3689 // clear slot unless we are in it already
3710 if (*slot != ob) 3690 if (*slot != ob)
3711 apply (*slot, AP_UNAPPLY); 3691 if (!apply (*slot, AP_UNAPPLY))
3692 return false;
3712 3693
3713 // unapply other slot, because we want to become active 3694 // unapply other slot, because we want to become active
3714 apply (oslot, AP_UNAPPLY); 3695 if (!apply (oslot, AP_UNAPPLY))
3696 return false;
3715 } 3697 }
3716 3698
3717 // clear item from slot if applied 3699 // clear item from slot if applied
3718 if (!want_apply && current_weapon == ob) 3700 if (!want_apply && current_weapon == ob)
3719 current_weapon = 0; 3701 current_weapon = 0;
3738 * Generates shop floor's item, and treasures. 3720 * Generates shop floor's item, and treasures.
3739 */ 3721 */
3740int 3722int
3741auto_apply (object *op) 3723auto_apply (object *op)
3742{ 3724{
3743 object *tmp = NULL, *tmp2; 3725 object *tmp = NULL;
3744 int i; 3726 int i;
3745 3727
3746 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3728 op->clr_flag (FLAG_AUTO_APPLY);
3747 3729
3748 switch (op->type) 3730 switch (op->type)
3749 { 3731 {
3750 case SHOP_FLOOR: 3732 case SHOP_FLOOR:
3751 if (!op->has_random_items ()) 3733 if (!op->has_random_items ())
3761 == NULL && --i); 3743 == NULL && --i);
3762 3744
3763 if (tmp == NULL) 3745 if (tmp == NULL)
3764 return 0; 3746 return 0;
3765 3747
3766 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3748 if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED])
3767 { 3749 {
3768 tmp->destroy (); 3750 tmp->destroy ();
3769 tmp = NULL; 3751 tmp = NULL;
3770 } 3752 }
3771 } 3753 }
3772 while (!tmp); 3754 while (!tmp);
3773 3755
3774 tmp->x = op->x; 3756 tmp->x = op->x;
3775 tmp->y = op->y; 3757 tmp->y = op->y;
3776 SET_FLAG (tmp, FLAG_UNPAID); 3758 tmp->set_flag (FLAG_UNPAID);
3777 insert_ob_in_map (tmp, op->map, NULL, 0); 3759 insert_ob_in_map (tmp, op->map, NULL, 0);
3778 identify (tmp); 3760 identify (tmp);
3779 break; 3761 break;
3780 3762
3781 case TREASURE: 3763 case TREASURE:
3782 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3764 if (op->flag [FLAG_IS_A_TEMPLATE])
3783 return 0; 3765 return 0;
3784 3766
3785 while (op->stats.hp-- > 0) 3767 while (op->stats.hp-- > 0)
3786 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3768 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3787 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); 3769 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3825 3807
3826 for (invtmp = tmp->inv; invtmp; invtmp = invnext) 3808 for (invtmp = tmp->inv; invtmp; invtmp = invnext)
3827 { 3809 {
3828 invnext = invtmp->below; 3810 invnext = invtmp->below;
3829 3811
3830 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3812 if (invtmp->flag [FLAG_AUTO_APPLY])
3831 auto_apply (invtmp); 3813 auto_apply (invtmp);
3832 else if (invtmp->type == TREASURE && invtmp->has_random_items ()) 3814 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3833 { 3815 {
3834 while (invtmp->stats.hp-- > 0) 3816 while (invtmp->stats.hp-- > 0)
3835 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3817 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3836 3818
3837 invtmp->randomitems = NULL; 3819 invtmp->randomitems = NULL;
3838 } 3820 }
3839 else if (invtmp && invtmp->arch 3821 else if (invtmp->arch
3840 && 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 ())
3841 { 3824 {
3842 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); 3825 create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0);
3843 /* Need to clear this so that we never try to create 3826 /* Need to clear this so that we never try to create
3844 * treasure again for this object 3827 * treasure again for this object
3845 */ 3828 */
3860 if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL 3843 if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL
3861 || tmp->type == HORN || tmp->type == FIREWALL || tmp->type == POTION || tmp->type == ALTAR || tmp->type == SPELLBOOK) 3844 || tmp->type == HORN || tmp->type == FIREWALL || tmp->type == POTION || tmp->type == ALTAR || tmp->type == SPELLBOOK)
3862 tmp->randomitems = NULL; 3845 tmp->randomitems = NULL;
3863 } 3846 }
3864 3847
3865 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3848 if (tmp->flag [FLAG_AUTO_APPLY])
3866 auto_apply (tmp); 3849 auto_apply (tmp);
3867 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ()) 3850 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ())
3868 { 3851 {
3869 while ((tmp->stats.hp--) > 0) 3852 while ((tmp->stats.hp--) > 0)
3870 create_treasure (tmp->randomitems, tmp, 0, difficulty, 0); 3853 create_treasure (tmp->randomitems, tmp, 0, difficulty, 0);
3872 } 3855 }
3873 else if (tmp->type == TIMED_GATE) 3856 else if (tmp->type == TIMED_GATE)
3874 { 3857 {
3875 object *head = tmp->head != NULL ? tmp->head : tmp; 3858 object *head = tmp->head != NULL ? tmp->head : tmp;
3876 3859
3877 if (QUERY_FLAG (head, FLAG_IS_LINKED)) 3860 if (head->flag [FLAG_IS_LINKED])
3878 tmp->set_speed (0); 3861 tmp->set_speed (0);
3879 } 3862 }
3880 /* This function can be called everytime a map is loaded, even when 3863 /* This function can be called everytime a map is loaded, even when
3881 * swapping back in. As such, we don't want to create the treasure 3864 * swapping back in. As such, we don't want to create the treasure
3882 * over and ove again, so after we generate the treasure, blank out 3865 * over and ove again, so after we generate the treasure, blank out
3971 } 3954 }
3972 3955
3973 /* check for hp, sp change */ 3956 /* check for hp, sp change */
3974 if (food->stats.hp != 0) 3957 if (food->stats.hp != 0)
3975 { 3958 {
3976 if (QUERY_FLAG (food, FLAG_CURSED)) 3959 if (food->flag [FLAG_CURSED])
3977 { 3960 {
3978 who->contr->killer = food; 3961 who->contr->killer = food;
3979 hit_player (who, food->stats.hp, food, AT_POISON, 1); 3962 hit_player (who, food->stats.hp, food, AT_POISON, 1);
3980 who->failmsg ("Eck!...that was poisonous!"); 3963 who->failmsg ("Eck!...that was poisonous!");
3981 } 3964 }
3990 } 3973 }
3991 } 3974 }
3992 3975
3993 if (food->stats.sp != 0) 3976 if (food->stats.sp != 0)
3994 { 3977 {
3995 if (QUERY_FLAG (food, FLAG_CURSED)) 3978 if (food->flag [FLAG_CURSED])
3996 { 3979 {
3997 who->failmsg ("You are drained of mana!"); 3980 who->failmsg ("You are drained of mana!");
3998 who->stats.sp -= food->stats.sp; 3981 who->stats.sp -= food->stats.sp;
3999 if (who->stats.sp < 0) 3982 if (who->stats.sp < 0)
4000 who->stats.sp = 0; 3983 who->stats.sp = 0;
4083 pl->animation_id = change->animation_id; 4066 pl->animation_id = change->animation_id;
4084 pl->flag [FLAG_ANIMATE] = change->flag [FLAG_ANIMATE]; 4067 pl->flag [FLAG_ANIMATE] = change->flag [FLAG_ANIMATE];
4085 } 4068 }
4086 4069
4087 /* check the special case of can't use weapons */ 4070 /* check the special case of can't use weapons */
4088 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ 4071 /*if(change->flag [FLAG_USE_WEAPON]) pl->clr_flag (FLAG_USE_WEAPON); */
4089 if (change->name == shstr_monk) 4072 if (change->name == shstr_monk)
4090 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4073 pl->clr_flag (FLAG_USE_WEAPON);
4091 4074
4092 break; 4075 break;
4093 } 4076 }
4094 } 4077 }
4095} 4078}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines