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.107 by elmex, Thu Sep 17 16:53:15 2009 UTC vs.
Revision 1.123 by root, Sun Apr 4 04:10:47 2010 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 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your 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 GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * 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>
22 */ 23 */
23 24
24#include <global.h> 25#include <global.h>
71 if (!(random_roll (0, 3, op, PREFER_HIGH))) 72 if (!(random_roll (0, 3, op, PREFER_HIGH)))
72 { 73 {
73 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand)); 74 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s vibrates violently, then explodes!", query_name (wand));
74 op->play_sound (sound_find ("ob_explode")); 75 op->play_sound (sound_find ("ob_explode"));
75 wand->destroy (); 76 wand->destroy ();
76 tmp = get_archetype ("fireball"); 77 tmp = get_archetype (shstr_fireball);
77 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10; 78 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10;
78 79
79 if (!tmp->stats.dam) 80 if (!tmp->stats.dam)
80 tmp->stats.dam = 1; 81 tmp->stats.dam = 1;
81 82
261 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 262 new_draw_info (NDI_UNIQUE, 0, op, "You don't have enough experience to create any food.");
262 return 0; 263 return 0;
263 } 264 }
264 265
265 food_value /= at->stats.food; 266 food_value /= at->stats.food;
266 new_op = arch_to_object (at); 267 new_op = at->instance ();
267 new_op->nrof = food_value; 268 new_op->nrof = food_value;
268 269
269 new_op->value = 0; 270 new_op->value = 0;
270 if (new_op->nrof < 1) 271 if (new_op->nrof < 1)
271 new_op->nrof = 1; 272 new_op->nrof = 1;
564 565
565int 566int
566perceive_self (object *op) 567perceive_self (object *op)
567{ 568{
568 const char *cp = describe_item (op, op); 569 const char *cp = describe_item (op, op);
569 archetype *at = archetype::find (ARCH_DEPLETION); 570 archetype *at = archetype::find (shstr_depletion);
570 571
571 dynbuf_text &buf = msg_dynbuf; buf.clear (); 572 dynbuf_text &buf = msg_dynbuf; buf.clear ();
572 573
573 if (!op->is_player ()) 574 if (!op->is_player ())
574 return 0; 575 return 0;
593 for (int i = 0; i < NUM_STATS; i++) 594 for (int i = 0; i < NUM_STATS; i++)
594 if (tmp->stats.stat (i) < 0) 595 if (tmp->stats.stat (i) < 0)
595 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i)); 596 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
596 } 597 }
597 598
598 if (is_dragon_pl (op)) 599 if (op->is_dragon ())
599 /* now grab the 'dragon_ability'-force from the player's inventory */ 600 /* now grab the 'dragon_ability'-force from the player's inventory */
600 for (tmp = op->inv; tmp; tmp = tmp->below) 601 for (tmp = op->inv; tmp; tmp = tmp->below)
601 { 602 {
602 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force) 603 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
603 { 604 {
649 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 650 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
650 return 0; 651 return 0;
651 } 652 }
652 653
653 if (spell_ob->other_arch) 654 if (spell_ob->other_arch)
654 tmp = arch_to_object (spell_ob->other_arch); 655 tmp = spell_ob->other_arch->instance ();
655 else if (spell_ob->race) 656 else if (spell_ob->race)
656 { 657 {
657 char buf1[MAX_BUF]; 658 char buf1[MAX_BUF];
658 659
659 sprintf (buf1, spell_ob->race, dir); 660 sprintf (buf1, spell_ob->race, dir);
663 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1); 664 LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1);
664 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken."); 665 new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken.");
665 return 0; 666 return 0;
666 } 667 }
667 668
668 tmp = arch_to_object (at); 669 tmp = at->instance ();
669 } 670 }
670 else 671 else
671 { 672 {
672 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name); 673 LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name);
673 return 0; 674 return 0;
717 return 0; 718 return 0;
718 } 719 }
719 720
720 /* If this is a spellcasting wall, need to insert the spell object */ 721 /* If this is a spellcasting wall, need to insert the spell object */
721 if (tmp->other_arch && tmp->other_arch->type == SPELL) 722 if (tmp->other_arch && tmp->other_arch->type == SPELL)
722 insert_ob_in_ob (arch_to_object (tmp->other_arch), tmp); 723 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
723 724
724 /* This code causes the wall to extend some distance in 725 /* This code causes the wall to extend some distance in
725 * each direction, or until an obstruction is encountered. 726 * each direction, or until an obstruction is encountered.
726 * posblocked and negblocked help determine how far the 727 * posblocked and negblocked help determine how far the
727 * created wall can extend, it won't go extend through 728 * created wall can extend, it won't go extend through
747 object *tmp2 = tmp->clone (); 748 object *tmp2 = tmp->clone ();
748 m->insert (tmp2, x, y, op); 749 m->insert (tmp2, x, y, op);
749 750
750 /* If this is a spellcasting wall, need to insert the spell object */ 751 /* If this is a spellcasting wall, need to insert the spell object */
751 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 752 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
752 tmp2->insert (arch_to_object (tmp2->other_arch)); 753 tmp2->insert (tmp2->other_arch->instance ());
753 754
754 } 755 }
755 else 756 else
756 posblocked = 1; 757 posblocked = 1;
757 758
764 { 765 {
765 object *tmp2 = tmp->clone (); 766 object *tmp2 = tmp->clone ();
766 m->insert (tmp2, x, y, op); 767 m->insert (tmp2, x, y, op);
767 768
768 if (tmp2->other_arch && tmp2->other_arch->type == SPELL) 769 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
769 tmp2->insert (arch_to_object (tmp2->other_arch)); 770 tmp2->insert (tmp2->other_arch->instance ());
770 } 771 }
771 else 772 else
772 negblocked = 1; 773 negblocked = 1;
773 } 774 }
774 775
789 if (op->type != PLAYER) 790 if (op->type != PLAYER)
790 return 0; 791 return 0;
791 792
792 if (!dir) 793 if (!dir)
793 { 794 {
794 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?"); 795 op->failmsg ("In what direction?");
795 return 0; 796 return 0;
796 } 797 }
797 798
798 /* Given the new outdoor maps, can't let players dimension door for 799 /* Given the new outdoor maps, can't let players dimension door for
799 * ever, so put limits in. 800 * ever, so put limits in.
884 885
885 /* Actually move the player now */ 886 /* Actually move the player now */
886 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op))) 887 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op)))
887 return 1; 888 return 1;
888 889
889 op->speed_left = -FABS (op->speed) * 5; /* Freeze them for a short while */ 890 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
891
890 return 1; 892 return 1;
891} 893}
892 894
893/* cast_heal: Heals something. 895/* cast_heal: Heals something.
894 * op is the caster. 896 * op is the caster.
949 if (cure_disease (tmp, op, spell)) 951 if (cure_disease (tmp, op, spell))
950 success = 1; 952 success = 1;
951 953
952 if (spell->attacktype & AT_POISON) 954 if (spell->attacktype & AT_POISON)
953 { 955 {
954 at = archetype::find ("poisoning"); 956 at = archetype::find (shstr_poisoning);
955 poison = present_arch_in_ob (at, tmp); 957 poison = present_arch_in_ob (at, tmp);
956 if (poison) 958 if (poison)
957 { 959 {
958 success = 1; 960 success = 1;
959 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 961 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
961 } 963 }
962 } 964 }
963 965
964 if (spell->attacktype & AT_CONFUSION) 966 if (spell->attacktype & AT_CONFUSION)
965 { 967 {
966 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 968 poison = present_in_ob_by_name (FORCE, shstr_confusion, tmp);
967 if (poison) 969 if (poison)
968 { 970 {
969 success = 1; 971 success = 1;
970 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 972 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
971 poison->duration = 1; 973 poison->duration = 1;
972 } 974 }
973 } 975 }
974 976
975 if (spell->attacktype & AT_BLIND) 977 if (spell->attacktype & AT_BLIND)
976 { 978 {
977 at = archetype::find ("blindness"); 979 at = archetype::find (shstr_blindness);
978 poison = present_arch_in_ob (at, tmp); 980 poison = present_arch_in_ob (at, tmp);
979 if (poison) 981 if (poison)
980 { 982 {
981 success = 1; 983 success = 1;
982 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 984 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1000 tmp->stats.grace = tmp->stats.maxgrace; 1002 tmp->stats.grace = tmp->stats.maxgrace;
1001 success = 1; 1003 success = 1;
1002 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 1004 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1003 } 1005 }
1004 1006
1005 if (spell->stats.food && tmp->stats.food < 999) 1007 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1006 { 1008 {
1007 tmp->stats.food += spell->stats.food; 1009 tmp->stats.food += spell->stats.food;
1008 1010 min_it (tmp->stats.food, MAX_FOOD);
1009 if (tmp->stats.food > 999)
1010 tmp->stats.food = 999;
1011 1011
1012 success = 1; 1012 success = 1;
1013 /* We could do something a bit better like the messages for healing above */ 1013 /* We could do something a bit better like the messages for healing above */
1014 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 1014 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1015 } 1015 }
1062 break; 1062 break;
1063 } 1063 }
1064 else if (spell_ob->race && spell_ob->race == tmp2->name) 1064 else if (spell_ob->race && spell_ob->race == tmp2->name)
1065 { 1065 {
1066 if (!silent) 1066 if (!silent)
1067 new_draw_info_format (NDI_UNIQUE, 0, op, "You can not cast %s while %s is in effect", &spell_ob->name, &tmp2->name_pl); 1067 new_draw_info_format (NDI_UNIQUE, 0, op,
1068 "You can not cast %s while %s is in effect",
1069 &spell_ob->name, &tmp2->name_pl);
1068 1070
1069 return 0; 1071 return 0;
1070 } 1072 }
1071 } 1073 }
1072 } 1074 }
1073 1075
1074 if (!force)
1075 {
1076 force = get_archetype (FORCE_NAME);
1077 force->subtype = FORCE_CHANGE_ABILITY;
1078
1079 if (spell_ob->race)
1080 force->name = spell_ob->race;
1081 else
1082 force->name = spell_ob->name;
1083
1084 force->name_pl = spell_ob->name;
1085 new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1086
1087 }
1088 else
1089 {
1090 int duration = change_ability_duration (spell_ob, caster); 1076 int duration = change_ability_duration (spell_ob, caster);
1091 1077
1078 if (force)
1079 {
1092 if (duration > force->duration) 1080 if (duration > force->duration)
1093 { 1081 {
1094 force->duration = duration; 1082 force->duration = duration;
1095 new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1083 new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1096 } 1084 }
1098 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1086 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1099 1087
1100 return 1; 1088 return 1;
1101 } 1089 }
1102 1090
1103 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; 1091 new_draw_info_format (NDI_UNIQUE, 0, op,
1092 "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1093 TICK2TIME (duration));
1094
1095 force = get_archetype (FORCE_NAME);
1096 force->subtype = FORCE_CHANGE_ABILITY;
1097 force->duration = duration;
1098
1099 if (spell_ob->race)
1100 force->name = spell_ob->race;
1101 else
1102 force->name = spell_ob->name;
1103
1104 force->name_pl = spell_ob->name;
1105
1104 force->speed = 1.0; 1106 force->speed = 1.0;
1105 force->speed_left = -1.0; 1107 force->speed_left = -1.0;
1106 SET_FLAG (force, FLAG_APPLIED); 1108 SET_FLAG (force, FLAG_APPLIED);
1107 1109
1108 /* Now start processing the effects. First, protections */ 1110 /* Now start processing the effects. First, protections */
1246 } 1248 }
1247 else 1249 else
1248 { 1250 {
1249 /* Only give out good benefits, and put a max on it */ 1251 /* Only give out good benefits, and put a max on it */
1250 for (i = 0; i < NROFATTACKS; i++) 1252 for (i = 0; i < NROFATTACKS; i++)
1251 {
1252 if (god->resist[i] > 0) 1253 if (god->resist[i] > 0)
1253 {
1254 force->resist[i] = MIN (god->resist[i], spell_ob->resist[ATNR_GODPOWER]); 1254 force->resist[i] = min (god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1255 } 1255
1256 }
1257 force->path_attuned |= god->path_attuned; 1256 force->path_attuned |= god->path_attuned;
1258 1257
1259 if (spell_ob->attacktype) 1258 if (spell_ob->attacktype)
1260 force->slaying = god->slaying; 1259 force->slaying = god->slaying;
1261 1260
1326 if (op->type != PLAYER) 1325 if (op->type != PLAYER)
1327 return 0; 1326 return 0;
1328 1327
1329 archetype *nugget[3]; 1328 archetype *nugget[3];
1330 1329
1331 nugget[0] = archetype::find ("pyrite3"); 1330 nugget[0] = archetype::find (shstr_pyrite3);
1332 nugget[1] = archetype::find ("pyrite2"); 1331 nugget[1] = archetype::find (shstr_pyrite2);
1333 nugget[2] = archetype::find ("pyrite"); 1332 nugget[2] = archetype::find (shstr_pyrite);
1334 1333
1335 /* Put a maximum weight of items that can be alchemised. Limits the power 1334 /* Put a maximum weight of items that can be alchemised. Limits the power
1336 * some, and also prevents people from alchemising every table/chair/clock 1335 * some, and also prevents people from alchemising every table/chair/clock
1337 * in sight 1336 * in sight
1338 */ 1337 */
1398 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) 1397 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i)
1399 if (int nrof = value / nugget [i]->value) 1398 if (int nrof = value / nugget [i]->value)
1400 { 1399 {
1401 value -= nrof * nugget[i]->value; 1400 value -= nrof * nugget[i]->value;
1402 1401
1403 object *tmp = arch_to_object (nugget[i]); 1402 object *tmp = nugget[i]->instance ();
1404 tmp->nrof = nrof; 1403 tmp->nrof = nrof;
1405 tmp->flag [FLAG_IDENTIFIED] = true; 1404 tmp->flag [FLAG_IDENTIFIED] = true;
1406 op->map->insert (tmp, x, y, op, 0); 1405 op->map->insert (tmp, x, y, op, 0);
1407 } 1406 }
1408 1407
1544 range = spell->range + SP_level_range_adjust (caster, spell); 1543 range = spell->range + SP_level_range_adjust (caster, spell);
1545 1544
1546 if (!skill) 1545 if (!skill)
1547 skill = caster; 1546 skill = caster;
1548 1547
1548 dynbuf buf;
1549 unordered_mapwalk (op, -range, -range, range, range) 1549 unordered_mapwalk (buf, op, -range, -range, range, range)
1550 { 1550 {
1551 /* For most of the detections, we only detect objects above the 1551 /* For most of the detections, we only detect objects above the
1552 * floor. But this is not true for show invisible. 1552 * floor. But this is not true for show invisible.
1553 * Basically, we just go and find the top object and work 1553 * Basically, we just go and find the top object and work
1554 * down - that is easier than working up. 1554 * down - that is easier than working up.
1567 floor = 0; 1567 floor = 0;
1568 detect = NULL; 1568 detect = NULL;
1569 for (tmp = last; tmp; tmp = tmp->below) 1569 for (tmp = last; tmp; tmp = tmp->below)
1570 { 1570 {
1571 /* show invisible */ 1571 /* show invisible */
1572 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1572 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS)
1573 /* Might there be other objects that we can make visible? */ 1573 /* Might there be other objects that we can make visible? */
1574 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) 1574 && (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER)
1575 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) 1575 || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ))
1576 || tmp->type == CF_HANDLE 1576 || tmp->type == T_HANDLE
1577 || tmp->type == TRAPDOOR 1577 || tmp->type == TRAPDOOR
1578 || tmp->type == EXIT 1578 || tmp->type == EXIT
1579 || tmp->type == HOLE 1579 || tmp->type == HOLE
1580 || tmp->type == BUTTON 1580 || tmp->type == BUTTON
1581 || tmp->type == TELEPORTER 1581 || tmp->type == TELEPORTER
1582 || tmp->type == GATE 1582 || tmp->type == GATE
1583 || tmp->type == LOCKED_DOOR 1583 || tmp->type == LOCKED_DOOR
1584 || tmp->type == WEAPON 1584 || tmp->type == WEAPON
1585 || tmp->type == ALTAR 1585 || tmp->type == ALTAR
1586 || tmp->type == SIGN 1586 || tmp->type == SIGN
1587 || tmp->type == TRIGGER_PEDESTAL 1587 || tmp->type == TRIGGER_PEDESTAL
1588 || tmp->type == SPECIAL_KEY 1588 || tmp->type == SPECIAL_KEY
1589 || tmp->type == TREASURE 1589 || tmp->type == TREASURE
1590 || tmp->type == BOOK 1590 || tmp->type == BOOK
1591 || tmp->type == HOLY_ALTAR 1591 || tmp->type == HOLY_ALTAR
1592 || tmp->type == CONTAINER))) 1592 || tmp->type == CONTAINER)))
1593 { 1593 {
1594 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1594 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1595 { 1595 {
1596 tmp->invisible = 0; 1596 tmp->invisible = 0;
1597 done_one = 1; 1597 done_one = 1;
1619 /* detect magic */ 1619 /* detect magic */
1620 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1620 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) &&
1621 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1621 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp))
1622 { 1622 {
1623 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1623 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
1624 /* make runes more visibile */ 1624 /* make runes more visible */
1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1625 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1626 tmp->stats.Cha /= 4; 1626 tmp->stats.Cha /= 4;
1627 1627
1628 done_one = 1; 1628 done_one = 1;
1629 } 1629 }
1655 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1655 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))
1656 { 1656 {
1657 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1657 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
1658 done_one = 1; 1658 done_one = 1;
1659 } 1659 }
1660
1661 // Do mining detection spell:
1662 if (spell->last_sp == 1) // 1 - detect any vein
1663 {
1664 if (tmp->type == VEIN)
1665 {
1666 if (tmp->other_arch)
1667 {
1668 if (!detect)
1669 detect = tmp->other_arch;
1670 done_one = 2;
1671 }
1672 else
1673 done_one = 1;
1674 }
1675 }
1660 } /* for stack of objects on this space */ 1676 } /* for stack of objects on this space */
1661 1677
1662 /* Code here puts an effect of the spell on the space, so you can see 1678 /* Code here puts an effect of the spell on the space, so you can see
1663 * where the magic is. 1679 * where the magic is.
1664 */ 1680 */
1665 if (done_one) 1681 if (done_one)
1666 { 1682 {
1667 object *detect_ob = arch_to_object (spell->other_arch); 1683 object *detect_ob = spell->other_arch->instance ();
1668 1684
1669 /* if this is set, we want to copy the face */ 1685 /* if this is set, we want to copy the face */
1670 if (done_one == 2 && detect) 1686 if (done_one == 2 && detect)
1671 { 1687 {
1672 detect_ob->face = detect->face; 1688 detect_ob->face = detect->face;
1676 /* by default, the detect_ob is already animated */ 1692 /* by default, the detect_ob is already animated */
1677 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1693 if (!QUERY_FLAG (detect, FLAG_ANIMATE))
1678 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1694 CLEAR_FLAG (detect_ob, FLAG_ANIMATE);
1679 } 1695 }
1680 1696
1681 m->insert (detect_ob, nx, ny, op); 1697 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1682 } 1698 }
1683 } /* for processing the surrounding spaces */ 1699 } /* for processing the surrounding spaces */
1684 1700
1685 1701
1686 /* Now process objects in the players inventory if detect curse or magic */ 1702 /* Now process objects in the players inventory if detect curse or magic */
2029 } 2045 }
2030 2046
2031 weapon = weapon->split (); 2047 weapon = weapon->split ();
2032 2048
2033 /* create the golem object */ 2049 /* create the golem object */
2034 tmp = arch_to_object (spell->other_arch); 2050 tmp = spell->other_arch->instance ();
2035 2051
2036 /* if animated by a player, give the player control of the golem */ 2052 /* if animated by a player, give the player control of the golem */
2037 CLEAR_FLAG (tmp, FLAG_MONSTER); 2053 CLEAR_FLAG (tmp, FLAG_MONSTER);
2038 tmp->stats.exp = 0; 2054 tmp->stats.exp = 0;
2039 add_friendly_object (tmp); 2055 add_friendly_object (tmp);
2084 2100
2085 /* attacktype */ 2101 /* attacktype */
2086 if (!tmp->attacktype) 2102 if (!tmp->attacktype)
2087 tmp->attacktype = AT_PHYSICAL; 2103 tmp->attacktype = AT_PHYSICAL;
2088 2104
2089 if (materialtype_t *mt = name_to_material (op->materialname))
2090 {
2091 for (i = 0; i < NROFATTACKS; i++) 2105 for (i = 0; i < NROFATTACKS; i++)
2092 tmp->resist[i] = 50 - (mt->save[i] * 5); 2106 tmp->resist[i] = 50 - (op->material->save[i] * 5);
2093 a = mt->save[0]; 2107
2094 } 2108 a = op->material->save[0];
2095 else
2096 {
2097 for (i = 0; i < NROFATTACKS; i++)
2098 tmp->resist[i] = 5;
2099 a = 10;
2100 }
2101 2109
2102 /* Set weapon's immunity */ 2110 /* Set weapon's immunity */
2103 tmp->resist[ATNR_CONFUSION] = 100; 2111 tmp->resist[ATNR_CONFUSION] = 100;
2104 tmp->resist[ATNR_POISON] = 100; 2112 tmp->resist[ATNR_POISON] = 100;
2105 tmp->resist[ATNR_SLOW] = 100; 2113 tmp->resist[ATNR_SLOW] = 100;
2132 tmp->state = weapon->state; 2140 tmp->state = weapon->state;
2133 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; 2141 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE];
2134 } 2142 }
2135 2143
2136 /* make experience increase in proportion to the strength of the summoned creature. */ 2144 /* make experience increase in proportion to the strength of the summoned creature. */
2137 tmp->stats.exp *= 1 + (MAX (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); 2145 tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell));
2138 2146
2139 tmp->speed_left = -1; 2147 tmp->speed_left = -1;
2140 tmp->direction = dir; 2148 tmp->direction = dir;
2141 2149
2142 m->insert (tmp, x, y, op); 2150 m->insert (tmp, x, y, op);
2181 2189
2182 new_aura = present_arch_in_ob (spell->other_arch, op); 2190 new_aura = present_arch_in_ob (spell->other_arch, op);
2183 if (new_aura) 2191 if (new_aura)
2184 refresh = 1; 2192 refresh = 1;
2185 else 2193 else
2186 new_aura = arch_to_object (spell->other_arch); 2194 new_aura = spell->other_arch->instance ();
2187 2195
2188 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); 2196 new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2189 2197
2190 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2198 new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2191 2199
2256 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) 2264 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2257 { 2265 {
2258 hit_map (aura, i, aura->attacktype, 0); 2266 hit_map (aura, i, aura->attacktype, 0);
2259 2267
2260 if (aura->other_arch) 2268 if (aura->other_arch)
2261 pos.insert (arch_to_object (aura->other_arch), aura); 2269 pos.insert (aura->other_arch->instance (), aura);
2262 } 2270 }
2263 } 2271 }
2264 2272
2265 /* put the aura back in the player's inventory */ 2273 /* put the aura back in the player's inventory */
2266 env->insert (aura); 2274 env->insert (aura);
2285 continue; 2293 continue;
2286 2294
2287 if (victim->stats.exp == 0) 2295 if (victim->stats.exp == 0)
2288 continue; 2296 continue;
2289 2297
2290 def_lev = MAX (1, victim->level); 2298 def_lev = max (1, victim->level);
2291 atk_lev = MAX (1, op->level); 2299 atk_lev = max (1, op->level);
2292 2300
2293 if (rndm (0, atk_lev - 1) > def_lev) 2301 if (rndm (0, atk_lev - 1) > def_lev)
2294 { 2302 {
2295 /* make this sucker peaceful. */ 2303 /* make this sucker peaceful. */
2296 2304
2328 { 2336 {
2329 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2337 new_draw_info (NDI_UNIQUE, 0, op, "Write what?");
2330 return 0; 2338 return 0;
2331 } 2339 }
2332 2340
2333 if (strcasestr_local (msg, "endmsg")) 2341 if (!msg_is_safe (msg))
2334 { 2342 {
2335 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2343 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?");
2336 LOG (llevInfo, "write_rune: player %s tried to write bogus rune %s\n", &op->name, msg); 2344 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2337 return 0; 2345 return 0;
2338 } 2346 }
2339 2347
2340 if (!spell->other_arch) 2348 if (!spell->other_arch)
2341 return 0; 2349 return 0;
2342 2350
2343 object *tmp = arch_to_object (spell->other_arch); 2351 object *tmp = spell->other_arch->instance ();
2344 2352
2345 tmp->race = op->name; /*Save the owner of the rune */ 2353 tmp->race = op->name; /*Save the owner of the rune */
2346 tmp->msg = msg; 2354 tmp->msg = msg;
2347 2355
2348 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2356 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines