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

Comparing deliantra/server/server/spell_effect.C (file contents):
Revision 1.27 by root, Tue Dec 26 20:04:09 2006 UTC vs.
Revision 1.50 by root, Sat May 12 08:36:35 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23 */
23 24
24#include <global.h> 25#include <global.h>
25#include <object.h> 26#include <object.h>
26#include <living.h> 27#include <living.h>
27#ifndef __CEXTRACT__
28# include <sproto.h> 28#include <sproto.h>
29#endif
30#include <spells.h> 29#include <spells.h>
31#include <sounds.h> 30#include <sounds.h>
32 31
33/* cast_magic_storm: This is really used mostly for spell 32/* cast_magic_storm: This is really used mostly for spell
34 * fumbles at the like. tmp is the object to propogate. 33 * fumbles at the like. tmp is the object to propogate.
155 /* If it starts with a letter, presume it is a description */ 154 /* If it starts with a letter, presume it is a description */
156 if (isalpha (*stringarg)) 155 if (isalpha (*stringarg))
157 { 156 {
158 artifact *al = find_artifactlist (missile->type)->items; 157 artifact *al = find_artifactlist (missile->type)->items;
159 158
160 for (; al != NULL; al = al->next) 159 for (; al; al = al->next)
161 if (!strcasecmp (al->item->name, stringarg)) 160 if (!strcasecmp (al->item->name, stringarg))
162 break; 161 break;
163 162
164 if (!al) 163 if (!al)
165 { 164 {
374 * normal applies. 373 * normal applies.
375 */ 374 */
376int 375int
377cast_invisible (object *op, object *caster, object *spell_ob) 376cast_invisible (object *op, object *caster, object *spell_ob)
378{ 377{
379 object *tmp;
380
381 if (op->invisible > 1000) 378 if (op->invisible > 1000)
382 { 379 {
383 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further"); 380 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further");
384 return 0; 381 return 0;
385 } 382 }
401 else 398 else
402 op->contr->tmp_invis = 1; 399 op->contr->tmp_invis = 1;
403 400
404 op->contr->hidden = 0; 401 op->contr->hidden = 0;
405 } 402 }
403
406 if (makes_invisible_to (op, op)) 404 if (makes_invisible_to (op, op))
407 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!"); 405 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!");
408 else 406 else
409 new_draw_info (NDI_UNIQUE, 0, op, "You feel more transparent!"); 407 new_draw_info (NDI_UNIQUE, 0, op, "You feel more transparent!");
410 408
411 update_object (op, UP_OBJ_FACE); 409 update_object (op, UP_OBJ_CHANGE);
412 410
413 /* Only search the active objects - only these should actually do 411 /* Only search the active objects - only these should actually do
414 * harm to the player. 412 * harm to the player.
415 */ 413 */
416 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next) 414 for_all_actives (tmp)
417 if (tmp->enemy == op) 415 if (tmp->enemy == op)
418 tmp->enemy = NULL; 416 tmp->enemy = 0;
417
419 return 1; 418 return 1;
420} 419}
421 420
422/* earth to dust spell. Basically destroys earthwalls in the area. 421/* earth to dust spell. Basically destroys earthwalls in the area.
423 */ 422 */
451 next = tmp->above; 450 next = tmp->above;
452 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 451 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN))
453 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 452 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
454 } 453 }
455 } 454 }
455
456 return 1; 456 return 1;
457} 457}
458
459 458
460void 459void
461execute_word_of_recall (object *op) 460execute_word_of_recall (object *op)
462{ 461{
463 object *wor = op; 462 if (object *pl = op->in_player ())
464 463 {
465 while (op != NULL && op->type != PLAYER) 464 if (pl->ms ().flags () & P_NO_CLERIC && !QUERY_FLAG (pl, FLAG_WIZCAST))
466 op = op->env;
467
468 if (op != NULL && op->map)
469 if ((get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_CLERIC) && (!QUERY_FLAG (op, FLAG_WIZCAST)))
470 new_draw_info (NDI_UNIQUE, 0, op, "You feel something fizzle inside you."); 465 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
471 else 466 else
467 {
468 // remove first so we do not call update_stats
469 op->remove ();
472 enter_exit (op, wor); 470 pl->enter_exit (op);
471 }
472 }
473 473
474 wor->destroy (); 474 op->destroy ();
475} 475}
476 476
477/* Word of recall causes the player to return 'home'. 477/* Word of recall causes the player to return 'home'.
478 * we put a force into the player object, so that there is a 478 * we put a force into the player object, so that there is a
479 * time delay effect. 479 * time delay effect.
498 { 498 {
499 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); 499 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
500 LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n"); 500 LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n");
501 return 0; 501 return 0;
502 } 502 }
503
503 time = spell_ob->duration - SP_level_duration_adjust (caster, spell_ob); 504 time = spell_ob->duration - SP_level_duration_adjust (caster, spell_ob);
504 if (time < 1) 505 if (time < 1)
505 time = 1; 506 time = 1;
506 507
507 /* value of speed really doesn't make much difference, as long as it is 508 /* value of speed really doesn't make much difference, as long as it is
515 516
516 /* If we could take advantage of enter_player_savebed() here, it would be 517 /* If we could take advantage of enter_player_savebed() here, it would be
517 * nice, but until the map load fails, we can't. 518 * nice, but until the map load fails, we can't.
518 */ 519 */
519 EXIT_PATH (dummy) = op->contr->savebed_map; 520 EXIT_PATH (dummy) = op->contr->savebed_map;
520 EXIT_X (dummy) = op->contr->bed_x; 521 EXIT_X (dummy) = op->contr->bed_x;
521 EXIT_Y (dummy) = op->contr->bed_y; 522 EXIT_Y (dummy) = op->contr->bed_y;
522 523
523 (void) insert_ob_in_ob (dummy, op); 524 op->insert (dummy);
525
524 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you."); 526 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
527
525 return 1; 528 return 1;
526} 529}
527 530
528/* cast_wonder 531/* cast_wonder
529 * wonder is really just a spell that will likely cast another 532 * wonder is really just a spell that will likely cast another
562} 565}
563 566
564int 567int
565perceive_self (object *op) 568perceive_self (object *op)
566{ 569{
570 char buf[MAX_BUF];
567 char *cp = describe_item (op, op), buf[MAX_BUF]; 571 const char *cp = describe_item (op, op);
568 archetype *at = archetype::find (ARCH_DEPLETION); 572 archetype *at = archetype::find (ARCH_DEPLETION);
569 object *tmp; 573 object *tmp;
570 int i; 574 int i;
571 575
572 tmp = find_god (determine_god (op)); 576 tmp = find_god (determine_god (op));
601 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 605 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
602 { 606 {
603 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force")) 607 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force"))
604 { 608 {
605 if (tmp->stats.exp == 0) 609 if (tmp->stats.exp == 0)
606 {
607 sprintf (buf, "Your metabolism isn't focused on anything."); 610 sprintf (buf, "Your metabolism isn't focused on anything.");
608 }
609 else 611 else
610 {
611 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 612 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
612 } 613
613 new_draw_info (NDI_UNIQUE, 0, op, buf); 614 new_draw_info (NDI_UNIQUE, 0, op, buf);
614 break; 615 break;
615 } 616 }
616 } 617 }
617 } 618 }
619
618 return 1; 620 return 1;
619} 621}
620 622
621/* int cast_create_town_portal (object *op, object *caster, int dir) 623/* int cast_create_town_portal (object *op, object *caster, int dir)
622 * 624 *
636 * Code by Tchize (david.delbecq@usa.net) 638 * Code by Tchize (david.delbecq@usa.net)
637 */ 639 */
638int 640int
639cast_create_town_portal (object *op, object *caster, object *spell, int dir) 641cast_create_town_portal (object *op, object *caster, object *spell, int dir)
640{ 642{
641 object *dummy, *force, *old_force, *tmp; 643 object *dummy, *force, *old_force;
642 archetype *perm_portal; 644 archetype *perm_portal;
643 char portal_name[1024], portal_message[1024]; 645 char portal_name[1024], portal_message[1024];
644 sint16 exitx, exity;
645 maptile *exitmap; 646 maptile *exitmap;
646 int op_level; 647 int op_level;
647 648
648 /* Check to see if the map the player is currently on is a per player unique 649 /* Check to see if the map the player is currently on is a per player unique
649 * map. This can be determined in that per player unique maps have the 650 * map. This can be determined in that per player unique maps have the
677 */ 678 */
678 dummy->name = op->map->path; 679 dummy->name = op->map->path;
679 EXIT_X (dummy) = op->x; 680 EXIT_X (dummy) = op->x;
680 EXIT_Y (dummy) = op->y; 681 EXIT_Y (dummy) = op->y;
681 insert_ob_in_ob (dummy, op); 682 insert_ob_in_ob (dummy, op);
682 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You fix this place in your mind.\nYou feel you are able to come here from anywhere."); 683 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You fix this place in your mind. You feel you are able to come here from anywhere.");
683 return 1; 684 return 1;
684 } 685 }
685 686
686 dummy->destroy (); 687 dummy->destroy ();
687 688
719 * If it has the good name, we destruct it. 720 * If it has the good name, we destruct it.
720 * -We destruct the force indicating that portal. 721 * -We destruct the force indicating that portal.
721 */ 722 */
722 while ((old_force = check_inv_recursive (op, dummy))) 723 while ((old_force = check_inv_recursive (op, dummy)))
723 { 724 {
724 exitx = EXIT_X (old_force); 725 exitmap = maptile::find_sync (old_force->race, op->map);
725 exity = EXIT_Y (old_force);
726 LOG (llevDebug, "Trying to kill a portal in %s (%d,%d)\n", &old_force->race, exitx, exity);
727
728 if (!strncmp (old_force->race, settings.localdir, strlen (settings.localdir)))
729 exitmap = ready_map_name (old_force->race, MAP_PLAYER_UNIQUE);
730 else
731 exitmap = ready_map_name (old_force->race, 0);
732 726
733 if (exitmap) 727 if (exitmap)
734 { 728 {
729 exitmap->load_sync ();
730
731 int exitx = EXIT_X (old_force);
732 int exity = EXIT_Y (old_force);
733
735 tmp = present_arch (perm_portal, exitmap, exitx, exity); 734 for (object *tmp = present_arch (perm_portal, exitmap, exitx, exity); tmp; tmp = tmp->above)
736 while (tmp)
737 { 735 {
738 if (tmp->name == old_force->name) 736 if (tmp->name == old_force->name)
739 { 737 {
740 tmp->destroy (); 738 tmp->destroy ();
741 break; 739 break;
742 } 740 }
743
744 tmp = tmp->above;
745 } 741 }
746 } 742 }
747 743
748 old_force->destroy (); 744 old_force->destroy ();
749 LOG (llevDebug, "\n");
750 } 745 }
751 746
752 dummy->destroy (); 747 dummy->destroy ();
753 748
754 /* Creating the portals. 749 /* Creating the portals.
760 * 'force' is the destination of the town portal, which we got 755 * 'force' is the destination of the town portal, which we got
761 * from the players inventory above. 756 * from the players inventory above.
762 */ 757 */
763 758
764 /* Ensure exit map is loaded */ 759 /* Ensure exit map is loaded */
765 if (!strncmp (force->name, settings.localdir, strlen (settings.localdir))) 760 exitmap = maptile::find_sync (force->name);
766 exitmap = ready_map_name (force->name, MAP_PLAYER_UNIQUE);
767 else
768 exitmap = ready_map_name (force->name, 0);
769 761
770 /* If we were unable to load (ex. random map deleted), warn player */ 762 /* If we were unable to load (ex. random map deleted), warn player */
771 if (exitmap == NULL) 763 if (!exitmap)
772 { 764 {
773 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Something strange happens.\nYou can't remember where to go!?"); 765 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Something strange happens. You can't remember where to go!?");
774 force->destroy (); 766 force->destroy ();
775 return 1; 767 return 1;
776 } 768 }
769
770 exitmap->load_sync ();
777 771
778 op_level = caster_level (caster, spell); 772 op_level = caster_level (caster, spell);
779 if (op_level < 15) 773 if (op_level < 15)
780 snprintf (portal_message, 1024, 774 snprintf (portal_message, 1024,
781 "\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n", 775 "The air moves around you and a huge smell of ammonia surounds you as you pass through %s's tiny portal. Pouah!\n",
782 &op->name); 776 &op->name);
783 else if (op_level < 30) 777 else if (op_level < 30)
784 snprintf (portal_message, 1024, 778 snprintf (portal_message, 1024,
785 "\n%s's portal smells of ozone.\nYou do a lot of movements and finally pass\nthrough the small hole in the air\n", &op->name); 779 "%s's portal smells of ozone. You do a lot of movements and finally pass through the small hole in the air\n", &op->name);
786 else if (op_level < 60) 780 else if (op_level < 60)
787 snprintf (portal_message, 1024, "\nA shining door opens in the air in front of you,\nshowing you the path to another place.\n"); 781 snprintf (portal_message, 1024, "A shining door opens in the air in front of you, showing you the path to another place.\n");
788 else 782 else
789 snprintf (portal_message, 1024, "\nAs you walk through %s's portal, flowers come out\nfrom the ground around you.\nYou feel awed.\n", 783 snprintf (portal_message, 1024, "As you walk through %s's portal, flowers come out from the ground around you. You feel awed.\n",
790 &op->name); 784 &op->name);
791 785
792 /* Create a portal in front of player 786 /* Create a portal in front of player
793 * dummy contain the portal and 787 * dummy contain the portal and
794 * force contain the track to kill it later 788 * force contain the track to kill it later
795 */ 789 */
796
797 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &force->name); 790 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &force->name);
798 dummy = get_archetype (spell->slaying); /*The portal */ 791 dummy = get_archetype (spell->slaying); /*The portal */
799 if (dummy == NULL) 792 if (dummy == NULL)
800 { 793 {
801 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); 794 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
813 806
814 /* Now we need to to create a town portal marker inside the player 807 /* Now we need to to create a town portal marker inside the player
815 * object, so on future castings, we can know that he has an active 808 * object, so on future castings, we can know that he has an active
816 * town portal. 809 * town portal.
817 */ 810 */
818 tmp = get_archetype (spell->race); 811 object *tmp = get_archetype (spell->race);
819 if (tmp == NULL) 812
813 if (!tmp)
820 { 814 {
821 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); 815 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
822 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name); 816 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
823 return 0; 817 return 0;
824 } 818 }
833 * dummy contain the portal and 827 * dummy contain the portal and
834 * force the track to kill it later 828 * force the track to kill it later
835 * the 'force' variable still contains the 'reminder' of 829 * the 'force' variable still contains the 'reminder' of
836 * where this portal goes to. 830 * where this portal goes to.
837 */ 831 */
838 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, op->map->path); 832 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &op->map->path);
839 dummy = get_archetype (spell->slaying); /*The portal */ 833 dummy = get_archetype (spell->slaying); /*The portal */
840 if (dummy == NULL) 834 if (dummy == NULL)
841 { 835 {
842 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!"); 836 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
843 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name); 837 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name);
1167 object *poison; 1161 object *poison;
1168 int heal = 0, success = 0; 1162 int heal = 0, success = 0;
1169 1163
1170 tmp = find_target_for_friendly_spell (op, dir); 1164 tmp = find_target_for_friendly_spell (op, dir);
1171 1165
1172 if (tmp == NULL) 1166 if (!tmp)
1173 return 0; 1167 return 0;
1174 1168
1175 /* Figure out how many hp this spell might cure. 1169 /* Figure out how many hp this spell might cure.
1176 * could be zero if this spell heals effects, not damage. 1170 * could be zero if this spell heals effects, not damage.
1177 */ 1171 */
1180 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp; 1174 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp;
1181 1175
1182 if (heal) 1176 if (heal)
1183 { 1177 {
1184 if (tmp->stats.hp >= tmp->stats.maxhp) 1178 if (tmp->stats.hp >= tmp->stats.maxhp)
1185 {
1186 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed."); 1179 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed.");
1187 }
1188 else 1180 else
1189 { 1181 {
1190 /* See how many points we actually heal. Instead of messages 1182 /* See how many points we actually heal. Instead of messages
1191 * based on type of spell, we instead do messages based 1183 * based on type of spell, we instead do messages based
1192 * on amount of damage healed. 1184 * on amount of damage healed.
1194 if (heal > (tmp->stats.maxhp - tmp->stats.hp)) 1186 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1195 heal = tmp->stats.maxhp - tmp->stats.hp; 1187 heal = tmp->stats.maxhp - tmp->stats.hp;
1196 tmp->stats.hp += heal; 1188 tmp->stats.hp += heal;
1197 1189
1198 if (tmp->stats.hp >= tmp->stats.maxhp) 1190 if (tmp->stats.hp >= tmp->stats.maxhp)
1199 {
1200 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!"); 1191 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!");
1201 }
1202 else if (heal > 50) 1192 else if (heal > 50)
1203 {
1204 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!"); 1193 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!");
1205 }
1206 else if (heal > 25) 1194 else if (heal > 25)
1207 {
1208 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close."); 1195 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close.");
1209 }
1210 else if (heal > 10) 1196 else if (heal > 10)
1211 {
1212 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade."); 1197 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade.");
1213 }
1214 else 1198 else
1215 {
1216 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close."); 1199 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close.");
1217 } 1200
1218 success = 1; 1201 success = 1;
1219 } 1202 }
1220 } 1203 }
1204
1221 if (spell->attacktype & AT_DISEASE) 1205 if (spell->attacktype & AT_DISEASE)
1222 if (cure_disease (tmp, op)) 1206 if (cure_disease (tmp, op))
1223 success = 1; 1207 success = 1;
1224 1208
1225 if (spell->attacktype & AT_POISON) 1209 if (spell->attacktype & AT_POISON)
1231 success = 1; 1215 success = 1;
1232 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 1216 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
1233 poison->stats.food = 1; 1217 poison->stats.food = 1;
1234 } 1218 }
1235 } 1219 }
1220
1236 if (spell->attacktype & AT_CONFUSION) 1221 if (spell->attacktype & AT_CONFUSION)
1237 { 1222 {
1238 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 1223 poison = present_in_ob_by_name (FORCE, "confusion", tmp);
1239 if (poison) 1224 if (poison)
1240 { 1225 {
1241 success = 1; 1226 success = 1;
1242 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 1227 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
1243 poison->duration = 1; 1228 poison->duration = 1;
1244 } 1229 }
1245 } 1230 }
1231
1246 if (spell->attacktype & AT_BLIND) 1232 if (spell->attacktype & AT_BLIND)
1247 { 1233 {
1248 at = archetype::find ("blindness"); 1234 at = archetype::find ("blindness");
1249 poison = present_arch_in_ob (at, tmp); 1235 poison = present_arch_in_ob (at, tmp);
1250 if (poison) 1236 if (poison)
1252 success = 1; 1238 success = 1;
1253 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 1239 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1254 poison->stats.food = 1; 1240 poison->stats.food = 1;
1255 } 1241 }
1256 } 1242 }
1243
1257 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) 1244 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp)
1258 { 1245 {
1259 tmp->stats.sp += spell->last_sp; 1246 tmp->stats.sp += spell->last_sp;
1260 if (tmp->stats.sp > tmp->stats.maxsp) 1247 if (tmp->stats.sp > tmp->stats.maxsp)
1261 tmp->stats.sp = tmp->stats.maxsp; 1248 tmp->stats.sp = tmp->stats.maxsp;
1262 success = 1; 1249 success = 1;
1263 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!"); 1250 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!");
1264 } 1251 }
1252
1265 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) 1253 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace)
1266 { 1254 {
1267 tmp->stats.grace += spell->last_grace; 1255 tmp->stats.grace += spell->last_grace;
1268 if (tmp->stats.grace > tmp->stats.maxgrace) 1256 if (tmp->stats.grace > tmp->stats.maxgrace)
1269 tmp->stats.grace = tmp->stats.maxgrace; 1257 tmp->stats.grace = tmp->stats.maxgrace;
1270 success = 1; 1258 success = 1;
1271 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 1259 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1272 } 1260 }
1261
1273 if (spell->stats.food && tmp->stats.food < 999) 1262 if (spell->stats.food && tmp->stats.food < 999)
1274 { 1263 {
1275 tmp->stats.food += spell->stats.food; 1264 tmp->stats.food += spell->stats.food;
1276 if (tmp->stats.food > 999) 1265 if (tmp->stats.food > 999)
1277 tmp->stats.food = 999; 1266 tmp->stats.food = 999;
1278 success = 1; 1267 success = 1;
1279 /* We could do something a bit better like the messages for healing above */ 1268 /* We could do something a bit better like the messages for healing above */
1280 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 1269 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1281 } 1270 }
1271
1282 return success; 1272 return success;
1283} 1273}
1284 1274
1285 1275
1286/* This is used for the spells that gain stats. There are no spells 1276/* This is used for the spells that gain stats. There are no spells
1534 change_abil (tmp, force); /* Mostly to display any messages */ 1524 change_abil (tmp, force); /* Mostly to display any messages */
1535 insert_ob_in_ob (force, tmp); 1525 insert_ob_in_ob (force, tmp);
1536 tmp->update_stats (); 1526 tmp->update_stats ();
1537 return 1; 1527 return 1;
1538} 1528}
1539
1540
1541 1529
1542/* Alchemy code by Mark Wedel 1530/* Alchemy code by Mark Wedel
1543 * 1531 *
1544 * This code adds a new spell, called alchemy. Alchemy will turn 1532 * This code adds a new spell, called alchemy. Alchemy will turn
1545 * objects to gold nuggets, the value of the gold nuggets being 1533 * objects to gold nuggets, the value of the gold nuggets being
1555 * For example, if an item is worth 110 gold, you will get 1543 * For example, if an item is worth 110 gold, you will get
1556 * 4 large nuggets, and from 0-10 small nuggets. 1544 * 4 large nuggets, and from 0-10 small nuggets.
1557 * 1545 *
1558 * There is also a chance (1:30) that you will get nothing at all 1546 * There is also a chance (1:30) that you will get nothing at all
1559 * for the object. There is also a maximum weight that will be 1547 * for the object. There is also a maximum weight that will be
1560 * alchemied. 1548 * alchemised.
1561 */ 1549 */
1562
1563/* I didn't feel like passing these as arguements to the
1564 * two functions that need them. Real values are put in them
1565 * when the spell is cast, and these are freed when the spell
1566 * is finished.
1567 */
1568static object *small, *large;
1569
1570static void 1550static void
1571alchemy_object (object *obj, int *small_nuggets, int *large_nuggets, int *weight) 1551alchemy_object (object *obj, uint64 &total_value, int &total_weight)
1572{ 1552{
1573 uint64 value = query_cost (obj, NULL, F_TRUE); 1553 uint64 value = query_cost (obj, NULL, F_TRUE);
1574 1554
1575 /* Give third price when we alchemy money (This should hopefully 1555 /* Give third price when we alchemy money (This should hopefully
1576 * make it so that it isn't worth it to alchemy money, sell 1556 * make it so that it isn't worth it to alchemy money, sell
1577 * the nuggets, alchemy the gold from that, etc. 1557 * the nuggets, alchemy the gold from that, etc.
1578 * Otherwise, give 9 silver on the gold for other objects, 1558 * Otherwise, give 9 silver on the gold for other objects,
1579 * so that it would still be more affordable to haul 1559 * so that it would still be more affordable to haul
1580 * the stuff back to town. 1560 * the stuff back to town.
1581 */ 1561 */
1582
1583 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1562 if (QUERY_FLAG (obj, FLAG_UNPAID))
1584 value = 0; 1563 value = 0;
1585 else if (obj->type == MONEY || obj->type == GEM) 1564 else if (obj->type == MONEY || obj->type == GEM)
1586 value /= 3; 1565 value /= 3;
1587 else 1566 else
1588 value = (value * 9) / 10; 1567 value = value * 9 / 10;
1589 1568
1590 value /= 4; // fix by GHJ, don't understand, pcg
1591
1592 if ((obj->value > 0) && rndm (0, 29)) 1569 if (obj->value > 0 && rndm (0, 29))
1593 { 1570 total_value += value;
1594 int count;
1595 1571
1596 count = value / large->value;
1597 *large_nuggets += count;
1598 value -= (uint64) count *(uint64) large->value;
1599
1600 count = value / small->value;
1601 *small_nuggets += count;
1602 }
1603
1604 /* Turn 25 small nuggets into 1 large nugget. If the value
1605 * of large nuggets is not evenly divisable by the small nugget
1606 * value, take off an extra small_nugget (Assuming small_nuggets!=0)
1607 */
1608 if (*small_nuggets * small->value >= large->value)
1609 {
1610 (*large_nuggets)++;
1611 *small_nuggets -= large->value / small->value;
1612 if (*small_nuggets && large->value % small->value)
1613 (*small_nuggets)--;
1614 }
1615 weight += obj->weight; 1572 total_weight += obj->total_weight ();
1573
1616 obj->destroy (); 1574 obj->destroy ();
1617} 1575}
1618 1576
1619static void 1577static void
1620update_map (object *op, maptile *m, int small_nuggets, int large_nuggets, int x, int y) 1578update_map (object *op, maptile *m, int small_nuggets, object *small, int large_nuggets, object *large, int x, int y)
1621{ 1579{
1622 object *tmp;
1623 int flag = 0; 1580 int flag = 0;
1624 1581
1625 /* Put any nuggets below the player, but we can only pass this 1582 /* Put any nuggets below the player, but we can only pass this
1626 * flag if we are on the same space as the player 1583 * flag if we are on the same space as the player
1627 */ 1584 */
1628 if (x == op->x && y == op->y && op->map == m) 1585 if (x == op->x && y == op->y && op->map == m)
1629 flag = INS_BELOW_ORIGINATOR; 1586 flag = INS_BELOW_ORIGINATOR;
1630 1587
1631 if (small_nuggets) 1588 if (small_nuggets)
1632 { 1589 {
1633 tmp = small->clone (); 1590 object *tmp = small->clone ();
1634 tmp->nrof = small_nuggets; 1591 tmp->nrof = small_nuggets;
1635 m->insert (tmp, x, y, op, flag); 1592 m->insert (tmp, x, y, op, flag);
1636 } 1593 }
1637 1594
1638 if (large_nuggets) 1595 if (large_nuggets)
1639 { 1596 {
1640 tmp = large->clone (); 1597 object *tmp = large->clone ();
1641 tmp->nrof = large_nuggets; 1598 tmp->nrof = large_nuggets;
1642 m->insert (tmp, x, y, op, flag); 1599 m->insert (tmp, x, y, op, flag);
1643 } 1600 }
1601
1602 if (object *pl = m->at (x, y).player ())
1603 if (pl->contr->ns)
1604 pl->contr->ns->look_position = 0;
1644} 1605}
1645 1606
1646int 1607int
1647alchemy (object *op, object *caster, object *spell_ob) 1608alchemy (object *op, object *caster, object *spell_ob)
1648{ 1609{
1649 int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
1650 sint16 nx, ny;
1651 object *next, *tmp;
1652 maptile *mp;
1653
1654 if (op->type != PLAYER) 1610 if (op->type != PLAYER)
1655 return 0; 1611 return 0;
1656 1612
1613 object *large = get_archetype ("largenugget");
1614 object *small = get_archetype ("smallnugget");
1615
1657 /* Put a maximum weight of items that can be alchemied. Limits the power 1616 /* Put a maximum weight of items that can be alchemised. Limits the power
1658 * some, and also prevents people from alcheming every table/chair/clock 1617 * some, and also prevents people from alchemising every table/chair/clock
1659 * in sight 1618 * in sight
1660 */ 1619 */
1661 weight_max = spell_ob->duration + +SP_level_duration_adjust (caster, spell_ob); 1620 int duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1662 weight_max *= 1000; 1621 int weight_max = duration * 1000;
1663 small = get_archetype ("smallnugget"), large = get_archetype ("largenugget"); 1622 uint64 value_max = duration * 1000;
1664 1623
1624 int weight = 0;
1625
1665 for (y = op->y - 1; y <= op->y + 1; y++) 1626 for (int y = op->y - 1; y <= op->y + 1; y++)
1666 { 1627 {
1667 for (x = op->x - 1; x <= op->x + 1; x++) 1628 for (int x = op->x - 1; x <= op->x + 1; x++)
1668 { 1629 {
1630 uint64 value = 0;
1631
1669 nx = x; 1632 sint16 nx = x;
1670 ny = y; 1633 sint16 ny = y;
1671 1634
1672 mp = op->map; 1635 maptile *mp = op->map;
1673 1636
1674 mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny); 1637 int mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny);
1675 1638
1676 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC)) 1639 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1677 continue; 1640 continue;
1678 1641
1679 /* Treat alchemy a little differently - most spell effects 1642 /* Treat alchemy a little differently - most spell effects
1681 * ground level effect. 1644 * ground level effect.
1682 */ 1645 */
1683 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK) 1646 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK)
1684 continue; 1647 continue;
1685 1648
1686 small_nuggets = 0; 1649 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1687 large_nuggets = 0;
1688
1689 for (tmp = GET_MAP_OB (mp, nx, ny); tmp != NULL; tmp = next)
1690 { 1650 {
1691 next = tmp->above; 1651 next = tmp->above;
1652
1692 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1653 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) &&
1693 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1654 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON))
1694 { 1655 {
1695
1696 if (tmp->inv) 1656 if (tmp->inv)
1697 { 1657 {
1698 object *next1, *tmp1; 1658 object *next1, *tmp1;
1699 1659
1700 for (tmp1 = tmp->inv; tmp1 != NULL; tmp1 = next1) 1660 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1701 { 1661 {
1702 next1 = tmp1->below; 1662 next1 = tmp1->below;
1703 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1663 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) &&
1704 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1664 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON))
1705 alchemy_object (tmp1, &small_nuggets, &large_nuggets, &weight); 1665 alchemy_object (tmp1, value, weight);
1706 } 1666 }
1707 } 1667 }
1668
1708 alchemy_object (tmp, &small_nuggets, &large_nuggets, &weight); 1669 alchemy_object (tmp, value, weight);
1709 1670
1710 if (weight > weight_max) 1671 if (weight > weight_max)
1711 { 1672 break;
1712 update_map (op, mp, small_nuggets, large_nuggets, nx, ny);
1713 large->destroy ();
1714 small->destroy ();
1715 return 1;
1716 } 1673 }
1717 } /* is alchemable object */ 1674 }
1718 } /* process all objects on this space */ 1675
1676 value = min (value, value_max);
1677
1678 uint64 count = value / large->value;
1679 int large_nuggets = count;
1680 value -= count * large->value;
1681
1682 count = value / small->value;
1683 int small_nuggets = count;
1719 1684
1720 /* Insert all the nuggets at one time. This probably saves time, but 1685 /* Insert all the nuggets at one time. This probably saves time, but
1721 * it also prevents us from alcheming nuggets that were just created 1686 * it also prevents us from alcheming nuggets that were just created
1722 * with this spell. 1687 * with this spell.
1723 */ 1688 */
1724 update_map (op, mp, small_nuggets, large_nuggets, nx, ny); 1689 update_map (op, mp, small_nuggets, small, large_nuggets, large, nx, ny);
1725 }
1726 }
1727 1690
1691 if (weight > weight_max)
1692 goto bailout;
1693 }
1694 }
1695
1696bailout:
1728 large->destroy (); 1697 large->destroy ();
1729 small->destroy (); 1698 small->destroy ();
1730 /* reset this so that if player standing on a big pile of stuff,
1731 * it is redrawn properly.
1732 */
1733 op->contr->ns->look_position = 0;
1734 return 1; 1699 return 1;
1735} 1700}
1736 1701
1737 1702
1738/* This function removes the cursed/damned status on equipped 1703/* This function removes the cursed/damned status on equipped
1765 } 1730 }
1766 1731
1767 if (op->type == PLAYER) 1732 if (op->type == PLAYER)
1768 { 1733 {
1769 if (success) 1734 if (success)
1770 {
1771 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1735 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now.");
1772 }
1773 else 1736 else
1774 { 1737 {
1775 if (was_one) 1738 if (was_one)
1776 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1739 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse.");
1777 else 1740 else
1801 { 1764 {
1802 identify (tmp); 1765 identify (tmp);
1803 1766
1804 if (op->type == PLAYER) 1767 if (op->type == PLAYER)
1805 { 1768 {
1806 new_draw_info_format (NDI_UNIQUE, 0, op, "You have %s.", long_desc (tmp, op)); 1769 new_draw_info_format (NDI_UNIQUE, 0, op, "You identified: %s.", long_desc (tmp, op));
1807 1770
1808 if (tmp->msg) 1771 if (tmp->msg)
1809 { 1772 {
1810 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:"); 1773 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:");
1811 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg); 1774 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg);
1823 * stuff on the floor. Only identify stuff on the floor if the spell 1786 * stuff on the floor. Only identify stuff on the floor if the spell
1824 * was not fully used. 1787 * was not fully used.
1825 */ 1788 */
1826 if (num_ident) 1789 if (num_ident)
1827 { 1790 {
1828 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 1791 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1829 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1792 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp))
1830 { 1793 {
1831 identify (tmp); 1794 identify (tmp);
1832 1795
1833 if (op->type == PLAYER) 1796 if (op->type == PLAYER)
1834 { 1797 {
1835 new_draw_info_format (NDI_UNIQUE, 0, op, "On the ground is %s.", long_desc (tmp, op)); 1798 new_draw_info_format (NDI_UNIQUE, 0, op, "On the ground you identified: %s.", long_desc (tmp, op));
1836 1799
1837 if (tmp->msg) 1800 if (tmp->msg)
1838 { 1801 {
1839 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:"); 1802 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:");
1840 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg); 1803 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg);
2190 /* Basically, if the object is magical and not counterspell, 2153 /* Basically, if the object is magical and not counterspell,
2191 * we will more or less remove the object. Don't counterspell 2154 * we will more or less remove the object. Don't counterspell
2192 * monsters either. 2155 * monsters either.
2193 */ 2156 */
2194 2157
2195 if (head->attacktype & AT_MAGIC && 2158 if (head->attacktype & AT_MAGIC
2196 !(head->attacktype & AT_COUNTERSPELL) && !QUERY_FLAG (head, FLAG_MONSTER) && (op->level > head->level)) 2159 && !(head->attacktype & AT_COUNTERSPELL)
2160 && !QUERY_FLAG (head, FLAG_MONSTER)
2161 && (op->level > head->level))
2197 head->destroy (); 2162 head->destroy ();
2198 else 2163 else
2199 switch (head->type) 2164 switch (head->type)
2200 { 2165 {
2201 case SPELL_EFFECT: 2166 case SPELL_EFFECT:
2167 // XXX: Don't affect floor spelleffects. See also XXX comment
2168 // about sanctuary in spell_util.C
2169 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
2170 continue;
2171
2202 if (op->level > head->level) 2172 if (op->level > head->level)
2203 head->destroy (); 2173 head->destroy ();
2204 2174
2205 break; 2175 break;
2206 2176
2273 * This code was very odd - code early on would only let players use the spell, 2243 * This code was very odd - code early on would only let players use the spell,
2274 * yet the code wass full of player checks. I've presumed that the code 2244 * yet the code wass full of player checks. I've presumed that the code
2275 * that only let players use it was correct, and removed all the other 2245 * that only let players use it was correct, and removed all the other
2276 * player checks. MSW 2003-01-06 2246 * player checks. MSW 2003-01-06
2277 */ 2247 */
2278
2279int 2248int
2280animate_weapon (object *op, object *caster, object *spell, int dir) 2249animate_weapon (object *op, object *caster, object *spell, int dir)
2281{ 2250{
2282 object *weapon, *tmp; 2251 object *weapon, *tmp;
2283 char buf[MAX_BUF]; 2252 char buf[MAX_BUF];
2295 /* exit if it's not a player using this spell. */ 2264 /* exit if it's not a player using this spell. */
2296 if (op->type != PLAYER) 2265 if (op->type != PLAYER)
2297 return 0; 2266 return 0;
2298 2267
2299 /* if player already has a golem, abort */ 2268 /* if player already has a golem, abort */
2300 if (op->contr->ranges[range_golem]) 2269 if (object *golem = op->contr->golem)
2301 { 2270 {
2302 control_golem (op->contr->ranges[range_golem], dir); 2271 control_golem (golem, dir);
2303 return 0; 2272 return 0;
2304 } 2273 }
2305 2274
2306 /* if no direction specified, pick one */ 2275 /* if no direction specified, pick one */
2307 if (!dir) 2276 if (!dir)
2353 /* create the golem object */ 2322 /* create the golem object */
2354 tmp = arch_to_object (spell->other_arch); 2323 tmp = arch_to_object (spell->other_arch);
2355 2324
2356 /* if animated by a player, give the player control of the golem */ 2325 /* if animated by a player, give the player control of the golem */
2357 CLEAR_FLAG (tmp, FLAG_MONSTER); 2326 CLEAR_FLAG (tmp, FLAG_MONSTER);
2358 SET_FLAG (tmp, FLAG_FRIENDLY);
2359 tmp->stats.exp = 0; 2327 tmp->stats.exp = 0;
2360 add_friendly_object (tmp); 2328 add_friendly_object (tmp);
2361 tmp->type = GOLEM; 2329 tmp->type = GOLEM;
2362 tmp->set_owner (op); 2330 tmp->set_owner (op);
2331 op->contr->golem = tmp;
2363 set_spell_skill (op, caster, spell, tmp); 2332 set_spell_skill (op, caster, spell, tmp);
2364 op->contr->ranges[range_golem] = tmp;
2365 op->contr->shoottype = range_golem;
2366 2333
2367 /* Give the weapon to the golem now. A bit of a hack to check the 2334 /* Give the weapon to the golem now. A bit of a hack to check the
2368 * removed flag - it should only be set if get_split_object was 2335 * removed flag - it should only be set if get_split_object was
2369 * used above. 2336 * used above.
2370 */ 2337 */
2371 if (!QUERY_FLAG (weapon, FLAG_REMOVED)) 2338 if (!QUERY_FLAG (weapon, FLAG_REMOVED))
2372 weapon->remove (); 2339 weapon->remove ();
2340
2373 insert_ob_in_ob (weapon, tmp); 2341 insert_ob_in_ob (weapon, tmp);
2374 esrv_send_item (op, weapon); 2342 esrv_send_item (op, weapon);
2375 /* To do everything necessary to let a golem use the weapon is a pain, 2343 /* To do everything necessary to let a golem use the weapon is a pain,
2376 * so instead, just set it as equipped (otherwise, we need to update 2344 * so instead, just set it as equipped (otherwise, we need to update
2377 * body_info, skills, etc) 2345 * body_info, skills, etc)
2477 int success; 2445 int success;
2478 2446
2479 if (!op->map) 2447 if (!op->map)
2480 return 0; /* shouldnt happen */ 2448 return 0; /* shouldnt happen */
2481 2449
2482 success = change_map_light (op->map, spell->stats.dam); 2450 success = op->map->change_map_light (spell->stats.dam);
2451
2483 if (!success) 2452 if (!success)
2484 { 2453 {
2485 if (spell->stats.dam < 0) 2454 if (spell->stats.dam < 0)
2486 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2455 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here.");
2487 else 2456 else

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines