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.29 by root, Sat Dec 30 22:01:39 2006 UTC vs.
Revision 1.53 by root, Tue May 22 10:50:01 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 op->enter_exit (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.
519 */ 519 */
520 EXIT_PATH (dummy) = op->contr->savebed_map; 520 EXIT_PATH (dummy) = op->contr->savebed_map;
521 EXIT_X (dummy) = op->contr->bed_x; 521 EXIT_X (dummy) = op->contr->bed_x;
522 EXIT_Y (dummy) = op->contr->bed_y; 522 EXIT_Y (dummy) = op->contr->bed_y;
523 523
524 (void) insert_ob_in_ob (dummy, op); 524 op->insert (dummy);
525
525 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
526 return 1; 528 return 1;
527} 529}
528 530
529/* cast_wonder 531/* cast_wonder
530 * wonder is really just a spell that will likely cast another 532 * wonder is really just a spell that will likely cast another
563} 565}
564 566
565int 567int
566perceive_self (object *op) 568perceive_self (object *op)
567{ 569{
570 char buf[MAX_BUF];
568 char *cp = describe_item (op, op), buf[MAX_BUF]; 571 const char *cp = describe_item (op, op);
569 archetype *at = archetype::find (ARCH_DEPLETION); 572 archetype *at = archetype::find (ARCH_DEPLETION);
570 object *tmp; 573 object *tmp;
571 int i; 574 int i;
572 575
573 tmp = find_god (determine_god (op)); 576 tmp = find_god (determine_god (op));
582 new_draw_info (NDI_UNIQUE, 0, op, "You feel very mundane"); 585 new_draw_info (NDI_UNIQUE, 0, op, "You feel very mundane");
583 else 586 else
584 { 587 {
585 new_draw_info (NDI_UNIQUE, 0, op, "You have:"); 588 new_draw_info (NDI_UNIQUE, 0, op, "You have:");
586 new_draw_info (NDI_UNIQUE, 0, op, cp); 589 new_draw_info (NDI_UNIQUE, 0, op, cp);
590
587 if (tmp != NULL) 591 if (tmp)
588 {
589 for (i = 0; i < NUM_STATS; i++) 592 for (i = 0; i < NUM_STATS; i++)
590 { 593 if (tmp->stats.stat (i) < 0)
591 if (get_attr_value (&tmp->stats, i) < 0)
592 {
593 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is depleted by %d", statname[i], -(get_attr_value (&tmp->stats, i))); 594 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is depleted by %d", statname[i], -tmp->stats.stat (i));
594 }
595 }
596 }
597 } 595 }
598 596
599 if (is_dragon_pl (op)) 597 if (is_dragon_pl (op))
600 { 598 {
601 /* now grab the 'dragon_ability'-force from the player's inventory */ 599 /* now grab the 'dragon_ability'-force from the player's inventory */
602 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 600 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
603 { 601 {
604 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force")) 602 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force"))
605 { 603 {
606 if (tmp->stats.exp == 0) 604 if (tmp->stats.exp == 0)
607 {
608 sprintf (buf, "Your metabolism isn't focused on anything."); 605 sprintf (buf, "Your metabolism isn't focused on anything.");
609 }
610 else 606 else
611 {
612 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 607 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
613 } 608
614 new_draw_info (NDI_UNIQUE, 0, op, buf); 609 new_draw_info (NDI_UNIQUE, 0, op, buf);
615 break; 610 break;
616 } 611 }
617 } 612 }
618 } 613 }
619 return 1;
620}
621
622/* int cast_create_town_portal (object *op, object *caster, int dir)
623 *
624 * This function cast the spell of town portal for op
625 *
626 * The spell operates in two passes. During the first one a place
627 * is marked as a destination for the portal. During the second one,
628 * 2 portals are created, one in the position the player cast it and
629 * one in the destination place. The portal are synchronized and 2 forces
630 * are inserted in the player to destruct the portal next time player
631 * creates a new portal pair.
632 * This spell has a side effect that it allows people to meet each other
633 * in a permanent, private, appartements by making a town portal from it
634 * to the town or another public place. So, check if the map is unique and if
635 * so return an error
636 *
637 * Code by Tchize (david.delbecq@usa.net)
638 */
639int
640cast_create_town_portal (object *op, object *caster, object *spell, int dir)
641{
642 object *dummy, *force, *old_force, *tmp;
643 archetype *perm_portal;
644 char portal_name[1024], portal_message[1024];
645 maptile *exitmap;
646 int op_level;
647
648 /* 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 * full pathname listed.
651 */
652 if (!strncmp (op->map->path, settings.localdir, strlen (settings.localdir)) && settings.create_home_portals != TRUE)
653 {
654 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You can't cast that here.\n");
655 return 0;
656 }
657
658 /* The first thing to do is to check if we have a marked destination
659 * dummy is used to make a check inventory for the force
660 */
661 dummy = arch_to_object (spell->other_arch);
662 if (dummy == NULL)
663 {
664 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
665 LOG (llevError, "object::create failed (force in cast_create_town_portal for %s!\n", &op->name);
666 return 0;
667 }
668
669 force = check_inv_recursive (op, dummy);
670
671 if (force == NULL)
672 {
673 /* Here we know there is no destination marked up.
674 * We have 2 things to do:
675 * 1. Mark the destination in the player inventory.
676 * 2. Let the player know it worked.
677 */
678 dummy->name = op->map->path;
679 EXIT_X (dummy) = op->x;
680 EXIT_Y (dummy) = op->y;
681 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 return 1;
684 }
685
686 dummy->destroy ();
687
688 /* Here we know where the town portal should go to
689 * We should kill any existing portal associated with the player.
690 * Than we should create the 2 portals.
691 * For each of them, we need:
692 * - To create the portal with the name of the player+destination map
693 * - set the owner of the town portal
694 * - To mark the position of the portal in the player's inventory
695 * for easier destruction.
696 *
697 * The mark works has follow:
698 * slaying: Existing town portal
699 * hp, sp : x & y of the associated portal
700 * name : name of the portal
701 * race : map the portal is in
702 */
703
704 /* First step: killing existing town portals */
705 dummy = get_archetype (spell->race);
706 if (dummy == NULL)
707 {
708 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
709 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
710 return 0;
711 }
712
713 perm_portal = archetype::find (spell->slaying);
714
715 /* To kill a town portal, we go trough the player's inventory,
716 * for each marked portal in player's inventory,
717 * -We try load the associated map (if impossible, consider the portal destructed)
718 * -We find any portal in the specified location.
719 * If it has the good name, we destruct it.
720 * -We destruct the force indicating that portal.
721 */
722 while ((old_force = check_inv_recursive (op, dummy)))
723 {
724 exitmap = maptile::find_map (old_force->race, op->map);
725
726 if (exitmap)
727 {
728 int exitx = EXIT_X (old_force);
729 int exity = EXIT_Y (old_force);
730
731 tmp = present_arch (perm_portal, exitmap, exitx, exity);
732 while (tmp)
733 {
734 if (tmp->name == old_force->name)
735 {
736 tmp->destroy ();
737 break;
738 }
739
740 tmp = tmp->above;
741 }
742 }
743
744 old_force->destroy ();
745 }
746
747 dummy->destroy ();
748
749 /* Creating the portals.
750 * The very first thing to do is to ensure
751 * access to the destination map.
752 * If we can't, don't fizzle. Simply warn player.
753 * This ensure player pays his mana for the spell
754 * because HE is responsible of forgotting.
755 * 'force' is the destination of the town portal, which we got
756 * from the players inventory above.
757 */
758
759 /* Ensure exit map is loaded */
760 exitmap = maptile::find_map (force->name, 0);
761
762 /* If we were unable to load (ex. random map deleted), warn player */
763 if (!exitmap)
764 {
765 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "Something strange happens.\nYou can't remember where to go!?");
766 force->destroy ();
767 return 1;
768 }
769
770 op_level = caster_level (caster, spell);
771 if (op_level < 15)
772 snprintf (portal_message, 1024,
773 "\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n",
774 &op->name);
775 else if (op_level < 30)
776 snprintf (portal_message, 1024,
777 "\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);
778 else if (op_level < 60)
779 snprintf (portal_message, 1024, "\nA shining door opens in the air in front of you,\nshowing you the path to another place.\n");
780 else
781 snprintf (portal_message, 1024, "\nAs you walk through %s's portal, flowers come out\nfrom the ground around you.\nYou feel awed.\n",
782 &op->name);
783
784 /* Create a portal in front of player
785 * dummy contain the portal and
786 * force contain the track to kill it later
787 */
788 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &force->name);
789 dummy = get_archetype (spell->slaying); /*The portal */
790 if (dummy == NULL)
791 {
792 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
793 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name);
794 return 0;
795 }
796
797 EXIT_PATH (dummy) = force->name;
798 EXIT_X (dummy) = EXIT_X (force);
799 EXIT_Y (dummy) = EXIT_Y (force);
800 dummy->name = dummy->name_pl = portal_name;
801 dummy->msg = portal_message;
802 dummy->race = op->name; /*Save the owner of the portal */
803 cast_create_obj (op, caster, dummy, 0);
804
805 /* Now we need to to create a town portal marker inside the player
806 * object, so on future castings, we can know that he has an active
807 * town portal.
808 */
809 tmp = get_archetype (spell->race);
810 if (tmp == NULL)
811 {
812 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
813 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
814 return 0;
815 }
816
817 tmp->race = op->map->path;
818 tmp->name = portal_name;
819 EXIT_X (tmp) = dummy->x;
820 EXIT_Y (tmp) = dummy->y;
821 op->insert (tmp);
822
823 /* Create a portal in the destination map
824 * dummy contain the portal and
825 * force the track to kill it later
826 * the 'force' variable still contains the 'reminder' of
827 * where this portal goes to.
828 */
829 snprintf (portal_name, 1024, "%s's portal to %s", &op->name, &op->map->path);
830 dummy = get_archetype (spell->slaying); /*The portal */
831 if (dummy == NULL)
832 {
833 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
834 LOG (llevError, "object::create failed (perm_magic_portal) in cast_create_town_portal for %s!\n", &op->name);
835 return 0;
836 }
837
838 EXIT_PATH (dummy) = op->map->path;
839 EXIT_X (dummy) = op->x;
840 EXIT_Y (dummy) = op->y;
841 dummy->name = dummy->name_pl = portal_name;
842 dummy->msg = portal_message;
843 dummy->race = op->name; /*Save the owner of the portal */
844 exitmap->insert (dummy, EXIT_X (force), EXIT_Y (force), op);
845
846 /* Now we create another town portal marker that
847 * points back to the one we just made
848 */
849 tmp = get_archetype (spell->race);
850 if (tmp == NULL)
851 {
852 new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
853 LOG (llevError, "object::create failed (force) in cast_create_town_portal for %s!\n", &op->name);
854 return 0;
855 }
856
857 tmp->race = force->name;
858 tmp->name = portal_name;
859 EXIT_X (tmp) = dummy->x;
860 EXIT_Y (tmp) = dummy->y;
861 insert_ob_in_ob (tmp, op);
862
863 /* Describe the player what happened
864 */
865 new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, op, "You see air moving and showing you the way home.");
866 force->destroy ();
867 614
868 return 1; 615 return 1;
869} 616}
870 617
871/* This creates magic walls. Really, it can create most any object, 618/* This creates magic walls. Really, it can create most any object,
1158 object *poison; 905 object *poison;
1159 int heal = 0, success = 0; 906 int heal = 0, success = 0;
1160 907
1161 tmp = find_target_for_friendly_spell (op, dir); 908 tmp = find_target_for_friendly_spell (op, dir);
1162 909
1163 if (tmp == NULL) 910 if (!tmp)
1164 return 0; 911 return 0;
1165 912
1166 /* Figure out how many hp this spell might cure. 913 /* Figure out how many hp this spell might cure.
1167 * could be zero if this spell heals effects, not damage. 914 * could be zero if this spell heals effects, not damage.
1168 */ 915 */
1171 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp; 918 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp;
1172 919
1173 if (heal) 920 if (heal)
1174 { 921 {
1175 if (tmp->stats.hp >= tmp->stats.maxhp) 922 if (tmp->stats.hp >= tmp->stats.maxhp)
1176 {
1177 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed."); 923 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed.");
1178 }
1179 else 924 else
1180 { 925 {
1181 /* See how many points we actually heal. Instead of messages 926 /* See how many points we actually heal. Instead of messages
1182 * based on type of spell, we instead do messages based 927 * based on type of spell, we instead do messages based
1183 * on amount of damage healed. 928 * on amount of damage healed.
1185 if (heal > (tmp->stats.maxhp - tmp->stats.hp)) 930 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1186 heal = tmp->stats.maxhp - tmp->stats.hp; 931 heal = tmp->stats.maxhp - tmp->stats.hp;
1187 tmp->stats.hp += heal; 932 tmp->stats.hp += heal;
1188 933
1189 if (tmp->stats.hp >= tmp->stats.maxhp) 934 if (tmp->stats.hp >= tmp->stats.maxhp)
1190 {
1191 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!"); 935 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!");
1192 }
1193 else if (heal > 50) 936 else if (heal > 50)
1194 {
1195 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!"); 937 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!");
1196 }
1197 else if (heal > 25) 938 else if (heal > 25)
1198 {
1199 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close."); 939 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close.");
1200 }
1201 else if (heal > 10) 940 else if (heal > 10)
1202 {
1203 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade."); 941 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade.");
1204 }
1205 else 942 else
1206 {
1207 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close."); 943 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close.");
1208 } 944
1209 success = 1; 945 success = 1;
1210 } 946 }
1211 } 947 }
948
1212 if (spell->attacktype & AT_DISEASE) 949 if (spell->attacktype & AT_DISEASE)
1213 if (cure_disease (tmp, op)) 950 if (cure_disease (tmp, op))
1214 success = 1; 951 success = 1;
1215 952
1216 if (spell->attacktype & AT_POISON) 953 if (spell->attacktype & AT_POISON)
1222 success = 1; 959 success = 1;
1223 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 960 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
1224 poison->stats.food = 1; 961 poison->stats.food = 1;
1225 } 962 }
1226 } 963 }
964
1227 if (spell->attacktype & AT_CONFUSION) 965 if (spell->attacktype & AT_CONFUSION)
1228 { 966 {
1229 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 967 poison = present_in_ob_by_name (FORCE, "confusion", tmp);
1230 if (poison) 968 if (poison)
1231 { 969 {
1232 success = 1; 970 success = 1;
1233 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 971 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
1234 poison->duration = 1; 972 poison->duration = 1;
1235 } 973 }
1236 } 974 }
975
1237 if (spell->attacktype & AT_BLIND) 976 if (spell->attacktype & AT_BLIND)
1238 { 977 {
1239 at = archetype::find ("blindness"); 978 at = archetype::find ("blindness");
1240 poison = present_arch_in_ob (at, tmp); 979 poison = present_arch_in_ob (at, tmp);
1241 if (poison) 980 if (poison)
1243 success = 1; 982 success = 1;
1244 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 983 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1245 poison->stats.food = 1; 984 poison->stats.food = 1;
1246 } 985 }
1247 } 986 }
987
1248 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) 988 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp)
1249 { 989 {
1250 tmp->stats.sp += spell->last_sp; 990 tmp->stats.sp += spell->last_sp;
1251 if (tmp->stats.sp > tmp->stats.maxsp) 991 if (tmp->stats.sp > tmp->stats.maxsp)
1252 tmp->stats.sp = tmp->stats.maxsp; 992 tmp->stats.sp = tmp->stats.maxsp;
1253 success = 1; 993 success = 1;
1254 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!"); 994 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!");
1255 } 995 }
996
1256 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) 997 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace)
1257 { 998 {
1258 tmp->stats.grace += spell->last_grace; 999 tmp->stats.grace += spell->last_grace;
1259 if (tmp->stats.grace > tmp->stats.maxgrace) 1000 if (tmp->stats.grace > tmp->stats.maxgrace)
1260 tmp->stats.grace = tmp->stats.maxgrace; 1001 tmp->stats.grace = tmp->stats.maxgrace;
1261 success = 1; 1002 success = 1;
1262 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 1003 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1263 } 1004 }
1005
1264 if (spell->stats.food && tmp->stats.food < 999) 1006 if (spell->stats.food && tmp->stats.food < 999)
1265 { 1007 {
1266 tmp->stats.food += spell->stats.food; 1008 tmp->stats.food += spell->stats.food;
1267 if (tmp->stats.food > 999) 1009 if (tmp->stats.food > 999)
1268 tmp->stats.food = 999; 1010 tmp->stats.food = 999;
1269 success = 1; 1011 success = 1;
1270 /* We could do something a bit better like the messages for healing above */ 1012 /* We could do something a bit better like the messages for healing above */
1271 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 1013 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1272 } 1014 }
1015
1273 return success; 1016 return success;
1274} 1017}
1275 1018
1276 1019
1277/* This is used for the spells that gain stats. There are no spells 1020/* This is used for the spells that gain stats. There are no spells
1369 if (tmp->type == PLAYER) 1112 if (tmp->type == PLAYER)
1370 { 1113 {
1371 /* Stat adjustment spells */ 1114 /* Stat adjustment spells */
1372 for (i = 0; i < NUM_STATS; i++) 1115 for (i = 0; i < NUM_STATS; i++)
1373 { 1116 {
1374 sint8 stat = get_attr_value (&spell_ob->stats, i), k, sm; 1117 if (sint8 stat = spell_ob->stats.stat (i))
1375
1376 if (stat)
1377 { 1118 {
1378 sm = 0; 1119 sint8 sm = 0;
1379 for (k = 0; k < stat; k++) 1120 for (sint8 k = 0; k < stat; k++)
1380 sm += rndm (1, 3); 1121 sm += rndm (1, 3);
1381 1122
1382 if ((get_attr_value (&tmp->stats, i) + sm) > (15 + 5 * stat)) 1123 if (tmp->stats.stat (i) + sm > 15 + 5 * stat)
1383 { 1124 sm = max (0, (15 + 5 * stat) - tmp->stats.stat (i));
1384 sm = (15 + 5 * stat) - get_attr_value (&tmp->stats, i); 1125
1385 if (sm < 0) 1126 force->stats.stat (i) = sm;
1386 sm = 0; 1127
1387 }
1388 set_attr_value (&force->stats, i, sm);
1389 if (!sm) 1128 if (!sm)
1390 new_draw_info (NDI_UNIQUE, 0, op, no_gain_msgs[i]); 1129 new_draw_info (NDI_UNIQUE, 0, op, no_gain_msgs[i]);
1391 } 1130 }
1392 } 1131 }
1393 } 1132 }
1525 change_abil (tmp, force); /* Mostly to display any messages */ 1264 change_abil (tmp, force); /* Mostly to display any messages */
1526 insert_ob_in_ob (force, tmp); 1265 insert_ob_in_ob (force, tmp);
1527 tmp->update_stats (); 1266 tmp->update_stats ();
1528 return 1; 1267 return 1;
1529} 1268}
1530
1531
1532 1269
1533/* Alchemy code by Mark Wedel 1270/* Alchemy code by Mark Wedel
1534 * 1271 *
1535 * This code adds a new spell, called alchemy. Alchemy will turn 1272 * This code adds a new spell, called alchemy. Alchemy will turn
1536 * objects to gold nuggets, the value of the gold nuggets being 1273 * objects to gold nuggets, the value of the gold nuggets being
1546 * For example, if an item is worth 110 gold, you will get 1283 * For example, if an item is worth 110 gold, you will get
1547 * 4 large nuggets, and from 0-10 small nuggets. 1284 * 4 large nuggets, and from 0-10 small nuggets.
1548 * 1285 *
1549 * There is also a chance (1:30) that you will get nothing at all 1286 * There is also a chance (1:30) that you will get nothing at all
1550 * for the object. There is also a maximum weight that will be 1287 * for the object. There is also a maximum weight that will be
1551 * alchemied. 1288 * alchemised.
1552 */ 1289 */
1553
1554/* I didn't feel like passing these as arguements to the
1555 * two functions that need them. Real values are put in them
1556 * when the spell is cast, and these are freed when the spell
1557 * is finished.
1558 */
1559static object *small, *large;
1560
1561static void 1290static void
1562alchemy_object (object *obj, int *small_nuggets, int *large_nuggets, int *weight) 1291alchemy_object (object *obj, uint64 &total_value, int &total_weight)
1563{ 1292{
1564 uint64 value = query_cost (obj, NULL, F_TRUE); 1293 uint64 value = query_cost (obj, NULL, F_TRUE);
1565 1294
1566 /* Give third price when we alchemy money (This should hopefully 1295 /* Give third price when we alchemy money (This should hopefully
1567 * make it so that it isn't worth it to alchemy money, sell 1296 * make it so that it isn't worth it to alchemy money, sell
1568 * the nuggets, alchemy the gold from that, etc. 1297 * the nuggets, alchemy the gold from that, etc.
1569 * Otherwise, give 9 silver on the gold for other objects, 1298 * Otherwise, give 9 silver on the gold for other objects,
1570 * so that it would still be more affordable to haul 1299 * so that it would still be more affordable to haul
1571 * the stuff back to town. 1300 * the stuff back to town.
1572 */ 1301 */
1573
1574 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1302 if (QUERY_FLAG (obj, FLAG_UNPAID))
1575 value = 0; 1303 value = 0;
1576 else if (obj->type == MONEY || obj->type == GEM) 1304 else if (obj->type == MONEY || obj->type == GEM)
1577 value /= 3; 1305 value /= 3;
1578 else 1306 else
1579 value = (value * 9) / 10; 1307 value = value * 9 / 10;
1580 1308
1581 value /= 4; // fix by GHJ, don't understand, pcg
1582
1583 if ((obj->value > 0) && rndm (0, 29)) 1309 if (obj->value > 0 && rndm (0, 29))
1584 { 1310 total_value += value;
1585 int count;
1586 1311
1587 count = value / large->value;
1588 *large_nuggets += count;
1589 value -= (uint64) count *(uint64) large->value;
1590
1591 count = value / small->value;
1592 *small_nuggets += count;
1593 }
1594
1595 /* Turn 25 small nuggets into 1 large nugget. If the value
1596 * of large nuggets is not evenly divisable by the small nugget
1597 * value, take off an extra small_nugget (Assuming small_nuggets!=0)
1598 */
1599 if (*small_nuggets * small->value >= large->value)
1600 {
1601 (*large_nuggets)++;
1602 *small_nuggets -= large->value / small->value;
1603 if (*small_nuggets && large->value % small->value)
1604 (*small_nuggets)--;
1605 }
1606 weight += obj->weight; 1312 total_weight += obj->total_weight ();
1313
1607 obj->destroy (); 1314 obj->destroy ();
1608} 1315}
1609 1316
1610static void 1317static void
1611update_map (object *op, maptile *m, int small_nuggets, int large_nuggets, int x, int y) 1318update_map (object *op, maptile *m, int small_nuggets, object *small, int large_nuggets, object *large, int x, int y)
1612{ 1319{
1613 object *tmp;
1614 int flag = 0; 1320 int flag = 0;
1615 1321
1616 /* Put any nuggets below the player, but we can only pass this 1322 /* Put any nuggets below the player, but we can only pass this
1617 * flag if we are on the same space as the player 1323 * flag if we are on the same space as the player
1618 */ 1324 */
1619 if (x == op->x && y == op->y && op->map == m) 1325 if (x == op->x && y == op->y && op->map == m)
1620 flag = INS_BELOW_ORIGINATOR; 1326 flag = INS_BELOW_ORIGINATOR;
1621 1327
1622 if (small_nuggets) 1328 if (small_nuggets)
1623 { 1329 {
1624 tmp = small->clone (); 1330 object *tmp = small->clone ();
1625 tmp->nrof = small_nuggets; 1331 tmp->nrof = small_nuggets;
1626 m->insert (tmp, x, y, op, flag); 1332 m->insert (tmp, x, y, op, flag);
1627 } 1333 }
1628 1334
1629 if (large_nuggets) 1335 if (large_nuggets)
1630 { 1336 {
1631 tmp = large->clone (); 1337 object *tmp = large->clone ();
1632 tmp->nrof = large_nuggets; 1338 tmp->nrof = large_nuggets;
1633 m->insert (tmp, x, y, op, flag); 1339 m->insert (tmp, x, y, op, flag);
1634 } 1340 }
1341
1342 if (object *pl = m->at (x, y).player ())
1343 if (pl->contr->ns)
1344 pl->contr->ns->look_position = 0;
1635} 1345}
1636 1346
1637int 1347int
1638alchemy (object *op, object *caster, object *spell_ob) 1348alchemy (object *op, object *caster, object *spell_ob)
1639{ 1349{
1640 int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
1641 sint16 nx, ny;
1642 object *next, *tmp;
1643 maptile *mp;
1644
1645 if (op->type != PLAYER) 1350 if (op->type != PLAYER)
1646 return 0; 1351 return 0;
1647 1352
1353 object *large = get_archetype ("largenugget");
1354 object *small = get_archetype ("smallnugget");
1355
1648 /* Put a maximum weight of items that can be alchemied. Limits the power 1356 /* Put a maximum weight of items that can be alchemised. Limits the power
1649 * some, and also prevents people from alcheming every table/chair/clock 1357 * some, and also prevents people from alchemising every table/chair/clock
1650 * in sight 1358 * in sight
1651 */ 1359 */
1652 weight_max = spell_ob->duration + +SP_level_duration_adjust (caster, spell_ob); 1360 int duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1653 weight_max *= 1000; 1361 int weight_max = duration * 1000;
1654 small = get_archetype ("smallnugget"), large = get_archetype ("largenugget"); 1362 uint64 value_max = duration * 1000;
1655 1363
1364 int weight = 0;
1365
1656 for (y = op->y - 1; y <= op->y + 1; y++) 1366 for (int y = op->y - 1; y <= op->y + 1; y++)
1657 { 1367 {
1658 for (x = op->x - 1; x <= op->x + 1; x++) 1368 for (int x = op->x - 1; x <= op->x + 1; x++)
1659 { 1369 {
1370 uint64 value = 0;
1371
1660 nx = x; 1372 sint16 nx = x;
1661 ny = y; 1373 sint16 ny = y;
1662 1374
1663 mp = op->map; 1375 maptile *mp = op->map;
1664 1376
1665 mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny); 1377 int mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny);
1666 1378
1667 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC)) 1379 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1668 continue; 1380 continue;
1669 1381
1670 /* Treat alchemy a little differently - most spell effects 1382 /* Treat alchemy a little differently - most spell effects
1672 * ground level effect. 1384 * ground level effect.
1673 */ 1385 */
1674 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK) 1386 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK)
1675 continue; 1387 continue;
1676 1388
1677 small_nuggets = 0; 1389 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1678 large_nuggets = 0;
1679
1680 for (tmp = GET_MAP_OB (mp, nx, ny); tmp != NULL; tmp = next)
1681 { 1390 {
1682 next = tmp->above; 1391 next = tmp->above;
1392
1683 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1393 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) &&
1684 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1394 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON))
1685 { 1395 {
1686
1687 if (tmp->inv) 1396 if (tmp->inv)
1688 { 1397 {
1689 object *next1, *tmp1; 1398 object *next1, *tmp1;
1690 1399
1691 for (tmp1 = tmp->inv; tmp1 != NULL; tmp1 = next1) 1400 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1692 { 1401 {
1693 next1 = tmp1->below; 1402 next1 = tmp1->below;
1694 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1403 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) &&
1695 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1404 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON))
1696 alchemy_object (tmp1, &small_nuggets, &large_nuggets, &weight); 1405 alchemy_object (tmp1, value, weight);
1697 } 1406 }
1698 } 1407 }
1408
1699 alchemy_object (tmp, &small_nuggets, &large_nuggets, &weight); 1409 alchemy_object (tmp, value, weight);
1700 1410
1701 if (weight > weight_max) 1411 if (weight > weight_max)
1702 { 1412 break;
1703 update_map (op, mp, small_nuggets, large_nuggets, nx, ny);
1704 large->destroy ();
1705 small->destroy ();
1706 return 1;
1707 } 1413 }
1708 } /* is alchemable object */ 1414 }
1709 } /* process all objects on this space */ 1415
1416 value = min (value, value_max);
1417
1418 uint64 count = value / large->value;
1419 int large_nuggets = count;
1420 value -= count * large->value;
1421
1422 count = value / small->value;
1423 int small_nuggets = count;
1710 1424
1711 /* Insert all the nuggets at one time. This probably saves time, but 1425 /* Insert all the nuggets at one time. This probably saves time, but
1712 * it also prevents us from alcheming nuggets that were just created 1426 * it also prevents us from alcheming nuggets that were just created
1713 * with this spell. 1427 * with this spell.
1714 */ 1428 */
1715 update_map (op, mp, small_nuggets, large_nuggets, nx, ny); 1429 update_map (op, mp, small_nuggets, small, large_nuggets, large, nx, ny);
1716 }
1717 }
1718 1430
1431 if (weight > weight_max)
1432 goto bailout;
1433 }
1434 }
1435
1436bailout:
1719 large->destroy (); 1437 large->destroy ();
1720 small->destroy (); 1438 small->destroy ();
1721 /* reset this so that if player standing on a big pile of stuff,
1722 * it is redrawn properly.
1723 */
1724 op->contr->ns->look_position = 0;
1725 return 1; 1439 return 1;
1726} 1440}
1727 1441
1728 1442
1729/* This function removes the cursed/damned status on equipped 1443/* This function removes the cursed/damned status on equipped
1756 } 1470 }
1757 1471
1758 if (op->type == PLAYER) 1472 if (op->type == PLAYER)
1759 { 1473 {
1760 if (success) 1474 if (success)
1761 {
1762 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1475 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now.");
1763 }
1764 else 1476 else
1765 { 1477 {
1766 if (was_one) 1478 if (was_one)
1767 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1479 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse.");
1768 else 1480 else
1792 { 1504 {
1793 identify (tmp); 1505 identify (tmp);
1794 1506
1795 if (op->type == PLAYER) 1507 if (op->type == PLAYER)
1796 { 1508 {
1797 new_draw_info_format (NDI_UNIQUE, 0, op, "You have %s.", long_desc (tmp, op)); 1509 new_draw_info_format (NDI_UNIQUE, 0, op, "You identified: %s.", long_desc (tmp, op));
1798 1510
1799 if (tmp->msg) 1511 if (tmp->msg)
1800 { 1512 {
1801 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:"); 1513 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:");
1802 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg); 1514 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg);
1814 * stuff on the floor. Only identify stuff on the floor if the spell 1526 * stuff on the floor. Only identify stuff on the floor if the spell
1815 * was not fully used. 1527 * was not fully used.
1816 */ 1528 */
1817 if (num_ident) 1529 if (num_ident)
1818 { 1530 {
1819 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 1531 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1820 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp)) 1532 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify (tmp))
1821 { 1533 {
1822 identify (tmp); 1534 identify (tmp);
1823 1535
1824 if (op->type == PLAYER) 1536 if (op->type == PLAYER)
1825 { 1537 {
1826 new_draw_info_format (NDI_UNIQUE, 0, op, "On the ground is %s.", long_desc (tmp, op)); 1538 new_draw_info_format (NDI_UNIQUE, 0, op, "On the ground you identified: %s.", long_desc (tmp, op));
1827 1539
1828 if (tmp->msg) 1540 if (tmp->msg)
1829 { 1541 {
1830 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:"); 1542 new_draw_info (NDI_UNIQUE, 0, op, "The item has a story:");
1831 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg); 1543 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg);
2181 /* Basically, if the object is magical and not counterspell, 1893 /* Basically, if the object is magical and not counterspell,
2182 * we will more or less remove the object. Don't counterspell 1894 * we will more or less remove the object. Don't counterspell
2183 * monsters either. 1895 * monsters either.
2184 */ 1896 */
2185 1897
2186 if (head->attacktype & AT_MAGIC && 1898 if (head->attacktype & AT_MAGIC
2187 !(head->attacktype & AT_COUNTERSPELL) && !QUERY_FLAG (head, FLAG_MONSTER) && (op->level > head->level)) 1899 && !(head->attacktype & AT_COUNTERSPELL)
1900 && !QUERY_FLAG (head, FLAG_MONSTER)
1901 && (op->level > head->level))
2188 head->destroy (); 1902 head->destroy ();
2189 else 1903 else
2190 switch (head->type) 1904 switch (head->type)
2191 { 1905 {
2192 case SPELL_EFFECT: 1906 case SPELL_EFFECT:
1907 // XXX: Don't affect floor spelleffects. See also XXX comment
1908 // about sanctuary in spell_util.C
1909 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
1910 continue;
1911
2193 if (op->level > head->level) 1912 if (op->level > head->level)
2194 head->destroy (); 1913 head->destroy ();
2195 1914
2196 break; 1915 break;
2197 1916
2264 * This code was very odd - code early on would only let players use the spell, 1983 * This code was very odd - code early on would only let players use the spell,
2265 * yet the code wass full of player checks. I've presumed that the code 1984 * yet the code wass full of player checks. I've presumed that the code
2266 * that only let players use it was correct, and removed all the other 1985 * that only let players use it was correct, and removed all the other
2267 * player checks. MSW 2003-01-06 1986 * player checks. MSW 2003-01-06
2268 */ 1987 */
2269
2270int 1988int
2271animate_weapon (object *op, object *caster, object *spell, int dir) 1989animate_weapon (object *op, object *caster, object *spell, int dir)
2272{ 1990{
2273 object *weapon, *tmp; 1991 object *weapon, *tmp;
2274 char buf[MAX_BUF]; 1992 char buf[MAX_BUF];
2286 /* exit if it's not a player using this spell. */ 2004 /* exit if it's not a player using this spell. */
2287 if (op->type != PLAYER) 2005 if (op->type != PLAYER)
2288 return 0; 2006 return 0;
2289 2007
2290 /* if player already has a golem, abort */ 2008 /* if player already has a golem, abort */
2291 if (op->contr->ranges[range_golem]) 2009 if (object *golem = op->contr->golem)
2292 { 2010 {
2293 control_golem (op->contr->ranges[range_golem], dir); 2011 control_golem (golem, dir);
2294 return 0; 2012 return 0;
2295 } 2013 }
2296 2014
2297 /* if no direction specified, pick one */ 2015 /* if no direction specified, pick one */
2298 if (!dir) 2016 if (!dir)
2344 /* create the golem object */ 2062 /* create the golem object */
2345 tmp = arch_to_object (spell->other_arch); 2063 tmp = arch_to_object (spell->other_arch);
2346 2064
2347 /* if animated by a player, give the player control of the golem */ 2065 /* if animated by a player, give the player control of the golem */
2348 CLEAR_FLAG (tmp, FLAG_MONSTER); 2066 CLEAR_FLAG (tmp, FLAG_MONSTER);
2349 SET_FLAG (tmp, FLAG_FRIENDLY);
2350 tmp->stats.exp = 0; 2067 tmp->stats.exp = 0;
2351 add_friendly_object (tmp); 2068 add_friendly_object (tmp);
2352 tmp->type = GOLEM; 2069 tmp->type = GOLEM;
2353 tmp->set_owner (op); 2070 tmp->set_owner (op);
2071 op->contr->golem = tmp;
2354 set_spell_skill (op, caster, spell, tmp); 2072 set_spell_skill (op, caster, spell, tmp);
2355 op->contr->ranges[range_golem] = tmp;
2356 op->contr->shoottype = range_golem;
2357 2073
2358 /* Give the weapon to the golem now. A bit of a hack to check the 2074 /* Give the weapon to the golem now. A bit of a hack to check the
2359 * removed flag - it should only be set if get_split_object was 2075 * removed flag - it should only be set if get_split_object was
2360 * used above. 2076 * used above.
2361 */ 2077 */
2362 if (!QUERY_FLAG (weapon, FLAG_REMOVED)) 2078 if (!QUERY_FLAG (weapon, FLAG_REMOVED))
2363 weapon->remove (); 2079 weapon->remove ();
2080
2364 insert_ob_in_ob (weapon, tmp); 2081 insert_ob_in_ob (weapon, tmp);
2365 esrv_send_item (op, weapon); 2082 esrv_send_item (op, weapon);
2366 /* To do everything necessary to let a golem use the weapon is a pain, 2083 /* To do everything necessary to let a golem use the weapon is a pain,
2367 * so instead, just set it as equipped (otherwise, we need to update 2084 * so instead, just set it as equipped (otherwise, we need to update
2368 * body_info, skills, etc) 2085 * body_info, skills, etc)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines