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 | |
565 | int |
566 | int |
566 | perceive_self (object *op) |
567 | perceive_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 | |
… | |
… | |
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."); |
… | |
… | |
1062 | break; |
1064 | break; |
1063 | } |
1065 | } |
1064 | else if (spell_ob->race && spell_ob->race == tmp2->name) |
1066 | else if (spell_ob->race && spell_ob->race == tmp2->name) |
1065 | { |
1067 | { |
1066 | if (!silent) |
1068 | 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); |
1069 | new_draw_info_format (NDI_UNIQUE, 0, op, |
|
|
1070 | "You can not cast %s while %s is in effect", |
|
|
1071 | &spell_ob->name, &tmp2->name_pl); |
1068 | |
1072 | |
1069 | return 0; |
1073 | return 0; |
1070 | } |
1074 | } |
1071 | } |
1075 | } |
1072 | } |
1076 | } |
1073 | |
1077 | |
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); |
1078 | int duration = change_ability_duration (spell_ob, caster); |
1091 | |
1079 | |
|
|
1080 | if (force) |
|
|
1081 | { |
1092 | if (duration > force->duration) |
1082 | if (duration > force->duration) |
1093 | { |
1083 | { |
1094 | force->duration = duration; |
1084 | force->duration = duration; |
1095 | new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); |
1085 | new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); |
1096 | } |
1086 | } |
… | |
… | |
1098 | new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); |
1088 | new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); |
1099 | |
1089 | |
1100 | return 1; |
1090 | return 1; |
1101 | } |
1091 | } |
1102 | |
1092 | |
1103 | force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; |
1093 | new_draw_info_format (NDI_UNIQUE, 0, op, |
|
|
1094 | "You create an aura of magical force. H<The effect will last for about %.10g seconds.>", |
|
|
1095 | TICK2TIME (duration)); |
|
|
1096 | |
|
|
1097 | force = get_archetype (FORCE_NAME); |
|
|
1098 | force->subtype = FORCE_CHANGE_ABILITY; |
|
|
1099 | force->duration = duration; |
|
|
1100 | |
|
|
1101 | if (spell_ob->race) |
|
|
1102 | force->name = spell_ob->race; |
|
|
1103 | else |
|
|
1104 | force->name = spell_ob->name; |
|
|
1105 | |
|
|
1106 | force->name_pl = spell_ob->name; |
|
|
1107 | |
1104 | force->speed = 1.0; |
1108 | force->speed = 1.0; |
1105 | force->speed_left = -1.0; |
1109 | force->speed_left = -1.0; |
1106 | SET_FLAG (force, FLAG_APPLIED); |
1110 | SET_FLAG (force, FLAG_APPLIED); |
1107 | |
1111 | |
1108 | /* Now start processing the effects. First, protections */ |
1112 | /* Now start processing the effects. First, protections */ |
… | |
… | |
1246 | } |
1250 | } |
1247 | else |
1251 | else |
1248 | { |
1252 | { |
1249 | /* Only give out good benefits, and put a max on it */ |
1253 | /* Only give out good benefits, and put a max on it */ |
1250 | for (i = 0; i < NROFATTACKS; i++) |
1254 | for (i = 0; i < NROFATTACKS; i++) |
1251 | { |
|
|
1252 | if (god->resist[i] > 0) |
1255 | if (god->resist[i] > 0) |
1253 | { |
|
|
1254 | force->resist[i] = MIN (god->resist[i], spell_ob->resist[ATNR_GODPOWER]); |
1256 | force->resist[i] = min (god->resist[i], spell_ob->resist[ATNR_GODPOWER]); |
1255 | } |
1257 | |
1256 | } |
|
|
1257 | force->path_attuned |= god->path_attuned; |
1258 | force->path_attuned |= god->path_attuned; |
1258 | |
1259 | |
1259 | if (spell_ob->attacktype) |
1260 | if (spell_ob->attacktype) |
1260 | force->slaying = god->slaying; |
1261 | force->slaying = god->slaying; |
1261 | |
1262 | |
… | |
… | |
1326 | if (op->type != PLAYER) |
1327 | if (op->type != PLAYER) |
1327 | return 0; |
1328 | return 0; |
1328 | |
1329 | |
1329 | archetype *nugget[3]; |
1330 | archetype *nugget[3]; |
1330 | |
1331 | |
1331 | nugget[0] = archetype::find ("pyrite3"); |
1332 | nugget[0] = archetype::find (shstr_pyrite3); |
1332 | nugget[1] = archetype::find ("pyrite2"); |
1333 | nugget[1] = archetype::find (shstr_pyrite2); |
1333 | nugget[2] = archetype::find ("pyrite"); |
1334 | nugget[2] = archetype::find (shstr_pyrite); |
1334 | |
1335 | |
1335 | /* Put a maximum weight of items that can be alchemised. Limits the power |
1336 | /* 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 |
1337 | * some, and also prevents people from alchemising every table/chair/clock |
1337 | * in sight |
1338 | * in sight |
1338 | */ |
1339 | */ |
… | |
… | |
1398 | for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) |
1399 | for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i) |
1399 | if (int nrof = value / nugget [i]->value) |
1400 | if (int nrof = value / nugget [i]->value) |
1400 | { |
1401 | { |
1401 | value -= nrof * nugget[i]->value; |
1402 | value -= nrof * nugget[i]->value; |
1402 | |
1403 | |
1403 | object *tmp = arch_to_object (nugget[i]); |
1404 | object *tmp = nugget[i]->instance (); |
1404 | tmp->nrof = nrof; |
1405 | tmp->nrof = nrof; |
1405 | tmp->flag [FLAG_IDENTIFIED] = true; |
1406 | tmp->flag [FLAG_IDENTIFIED] = true; |
1406 | op->map->insert (tmp, x, y, op, 0); |
1407 | op->map->insert (tmp, x, y, op, 0); |
1407 | } |
1408 | } |
1408 | |
1409 | |
… | |
… | |
1544 | range = spell->range + SP_level_range_adjust (caster, spell); |
1545 | range = spell->range + SP_level_range_adjust (caster, spell); |
1545 | |
1546 | |
1546 | if (!skill) |
1547 | if (!skill) |
1547 | skill = caster; |
1548 | skill = caster; |
1548 | |
1549 | |
|
|
1550 | dynbuf buf; |
1549 | unordered_mapwalk (op, -range, -range, range, range) |
1551 | unordered_mapwalk (buf, op, -range, -range, range, range) |
1550 | { |
1552 | { |
1551 | /* For most of the detections, we only detect objects above the |
1553 | /* For most of the detections, we only detect objects above the |
1552 | * floor. But this is not true for show invisible. |
1554 | * floor. But this is not true for show invisible. |
1553 | * Basically, we just go and find the top object and work |
1555 | * Basically, we just go and find the top object and work |
1554 | * down - that is easier than working up. |
1556 | * down - that is easier than working up. |
… | |
… | |
1567 | floor = 0; |
1569 | floor = 0; |
1568 | detect = NULL; |
1570 | detect = NULL; |
1569 | for (tmp = last; tmp; tmp = tmp->below) |
1571 | for (tmp = last; tmp; tmp = tmp->below) |
1570 | { |
1572 | { |
1571 | /* show invisible */ |
1573 | /* show invisible */ |
1572 | if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && |
1574 | if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) |
1573 | /* Might there be other objects that we can make visible? */ |
1575 | /* Might there be other objects that we can make visible? */ |
1574 | (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) |
1576 | && (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) |
1575 | || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) |
1577 | || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) |
1576 | || tmp->type == CF_HANDLE |
1578 | || tmp->type == T_HANDLE |
1577 | || tmp->type == TRAPDOOR |
1579 | || tmp->type == TRAPDOOR |
1578 | || tmp->type == EXIT |
1580 | || tmp->type == EXIT |
1579 | || tmp->type == HOLE |
1581 | || tmp->type == HOLE |
1580 | || tmp->type == BUTTON |
1582 | || tmp->type == BUTTON |
1581 | || tmp->type == TELEPORTER |
1583 | || tmp->type == TELEPORTER |
1582 | || tmp->type == GATE |
1584 | || tmp->type == GATE |
1583 | || tmp->type == LOCKED_DOOR |
1585 | || tmp->type == LOCKED_DOOR |
1584 | || tmp->type == WEAPON |
1586 | || tmp->type == WEAPON |
1585 | || tmp->type == ALTAR |
1587 | || tmp->type == ALTAR |
1586 | || tmp->type == SIGN |
1588 | || tmp->type == SIGN |
1587 | || tmp->type == TRIGGER_PEDESTAL |
1589 | || tmp->type == TRIGGER_PEDESTAL |
1588 | || tmp->type == SPECIAL_KEY |
1590 | || tmp->type == SPECIAL_KEY |
1589 | || tmp->type == TREASURE |
1591 | || tmp->type == TREASURE |
1590 | || tmp->type == BOOK |
1592 | || tmp->type == BOOK |
1591 | || tmp->type == HOLY_ALTAR |
1593 | || tmp->type == HOLY_ALTAR |
1592 | || tmp->type == CONTAINER))) |
1594 | || tmp->type == CONTAINER))) |
1593 | { |
1595 | { |
1594 | if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) |
1596 | if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) |
1595 | { |
1597 | { |
1596 | tmp->invisible = 0; |
1598 | tmp->invisible = 0; |
1597 | done_one = 1; |
1599 | done_one = 1; |
… | |
… | |
1619 | /* detect magic */ |
1621 | /* detect magic */ |
1620 | if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && |
1622 | if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && |
1621 | !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) |
1623 | !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) |
1622 | { |
1624 | { |
1623 | SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); |
1625 | SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); |
1624 | /* make runes more visibile */ |
1626 | /* make runes more visible */ |
1625 | if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) |
1627 | if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) |
1626 | tmp->stats.Cha /= 4; |
1628 | tmp->stats.Cha /= 4; |
1627 | |
1629 | |
1628 | done_one = 1; |
1630 | done_one = 1; |
1629 | } |
1631 | } |
… | |
… | |
1655 | (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) |
1657 | (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) |
1656 | { |
1658 | { |
1657 | SET_FLAG (tmp, FLAG_KNOWN_CURSED); |
1659 | SET_FLAG (tmp, FLAG_KNOWN_CURSED); |
1658 | done_one = 1; |
1660 | done_one = 1; |
1659 | } |
1661 | } |
|
|
1662 | |
|
|
1663 | // Do mining detection spell: |
|
|
1664 | if (spell->last_sp == 1) // 1 - detect any vein |
|
|
1665 | { |
|
|
1666 | if (tmp->type == VEIN) |
|
|
1667 | { |
|
|
1668 | if (tmp->other_arch) |
|
|
1669 | { |
|
|
1670 | if (!detect) |
|
|
1671 | detect = tmp->other_arch; |
|
|
1672 | done_one = 2; |
|
|
1673 | } |
|
|
1674 | else |
|
|
1675 | done_one = 1; |
|
|
1676 | } |
|
|
1677 | } |
1660 | } /* for stack of objects on this space */ |
1678 | } /* for stack of objects on this space */ |
1661 | |
1679 | |
1662 | /* Code here puts an effect of the spell on the space, so you can see |
1680 | /* Code here puts an effect of the spell on the space, so you can see |
1663 | * where the magic is. |
1681 | * where the magic is. |
1664 | */ |
1682 | */ |
1665 | if (done_one) |
1683 | if (done_one) |
1666 | { |
1684 | { |
1667 | object *detect_ob = arch_to_object (spell->other_arch); |
1685 | object *detect_ob = spell->other_arch->instance (); |
1668 | |
1686 | |
1669 | /* if this is set, we want to copy the face */ |
1687 | /* if this is set, we want to copy the face */ |
1670 | if (done_one == 2 && detect) |
1688 | if (done_one == 2 && detect) |
1671 | { |
1689 | { |
1672 | detect_ob->face = detect->face; |
1690 | detect_ob->face = detect->face; |
… | |
… | |
1676 | /* by default, the detect_ob is already animated */ |
1694 | /* by default, the detect_ob is already animated */ |
1677 | if (!QUERY_FLAG (detect, FLAG_ANIMATE)) |
1695 | if (!QUERY_FLAG (detect, FLAG_ANIMATE)) |
1678 | CLEAR_FLAG (detect_ob, FLAG_ANIMATE); |
1696 | CLEAR_FLAG (detect_ob, FLAG_ANIMATE); |
1679 | } |
1697 | } |
1680 | |
1698 | |
1681 | m->insert (detect_ob, nx, ny, op); |
1699 | m->insert (detect_ob, nx, ny, op, INS_ON_TOP); |
1682 | } |
1700 | } |
1683 | } /* for processing the surrounding spaces */ |
1701 | } /* for processing the surrounding spaces */ |
1684 | |
1702 | |
1685 | |
1703 | |
1686 | /* Now process objects in the players inventory if detect curse or magic */ |
1704 | /* Now process objects in the players inventory if detect curse or magic */ |
… | |
… | |
2029 | } |
2047 | } |
2030 | |
2048 | |
2031 | weapon = weapon->split (); |
2049 | weapon = weapon->split (); |
2032 | |
2050 | |
2033 | /* create the golem object */ |
2051 | /* create the golem object */ |
2034 | tmp = arch_to_object (spell->other_arch); |
2052 | tmp = spell->other_arch->instance (); |
2035 | |
2053 | |
2036 | /* if animated by a player, give the player control of the golem */ |
2054 | /* if animated by a player, give the player control of the golem */ |
2037 | CLEAR_FLAG (tmp, FLAG_MONSTER); |
2055 | CLEAR_FLAG (tmp, FLAG_MONSTER); |
2038 | tmp->stats.exp = 0; |
2056 | tmp->stats.exp = 0; |
2039 | add_friendly_object (tmp); |
2057 | add_friendly_object (tmp); |
… | |
… | |
2084 | |
2102 | |
2085 | /* attacktype */ |
2103 | /* attacktype */ |
2086 | if (!tmp->attacktype) |
2104 | if (!tmp->attacktype) |
2087 | tmp->attacktype = AT_PHYSICAL; |
2105 | tmp->attacktype = AT_PHYSICAL; |
2088 | |
2106 | |
2089 | if (materialtype_t *mt = name_to_material (op->materialname)) |
|
|
2090 | { |
|
|
2091 | for (i = 0; i < NROFATTACKS; i++) |
2107 | for (i = 0; i < NROFATTACKS; i++) |
2092 | tmp->resist[i] = 50 - (mt->save[i] * 5); |
2108 | tmp->resist[i] = 50 - (op->material->save[i] * 5); |
2093 | a = mt->save[0]; |
2109 | |
2094 | } |
2110 | 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 | |
2111 | |
2102 | /* Set weapon's immunity */ |
2112 | /* Set weapon's immunity */ |
2103 | tmp->resist[ATNR_CONFUSION] = 100; |
2113 | tmp->resist[ATNR_CONFUSION] = 100; |
2104 | tmp->resist[ATNR_POISON] = 100; |
2114 | tmp->resist[ATNR_POISON] = 100; |
2105 | tmp->resist[ATNR_SLOW] = 100; |
2115 | tmp->resist[ATNR_SLOW] = 100; |
… | |
… | |
2132 | tmp->state = weapon->state; |
2142 | tmp->state = weapon->state; |
2133 | tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; |
2143 | tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; |
2134 | } |
2144 | } |
2135 | |
2145 | |
2136 | /* make experience increase in proportion to the strength of the summoned creature. */ |
2146 | /* 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)); |
2147 | tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); |
2138 | |
2148 | |
2139 | tmp->speed_left = -1; |
2149 | tmp->speed_left = -1; |
2140 | tmp->direction = dir; |
2150 | tmp->direction = dir; |
2141 | |
2151 | |
2142 | m->insert (tmp, x, y, op); |
2152 | m->insert (tmp, x, y, op); |
… | |
… | |
2181 | |
2191 | |
2182 | new_aura = present_arch_in_ob (spell->other_arch, op); |
2192 | new_aura = present_arch_in_ob (spell->other_arch, op); |
2183 | if (new_aura) |
2193 | if (new_aura) |
2184 | refresh = 1; |
2194 | refresh = 1; |
2185 | else |
2195 | else |
2186 | new_aura = arch_to_object (spell->other_arch); |
2196 | new_aura = spell->other_arch->instance (); |
2187 | |
2197 | |
2188 | new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); |
2198 | new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell); |
2189 | |
2199 | |
2190 | new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
2200 | new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
2191 | |
2201 | |
… | |
… | |
2256 | if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) |
2266 | if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block))) |
2257 | { |
2267 | { |
2258 | hit_map (aura, i, aura->attacktype, 0); |
2268 | hit_map (aura, i, aura->attacktype, 0); |
2259 | |
2269 | |
2260 | if (aura->other_arch) |
2270 | if (aura->other_arch) |
2261 | pos.insert (arch_to_object (aura->other_arch), aura); |
2271 | pos.insert (aura->other_arch->instance (), aura); |
2262 | } |
2272 | } |
2263 | } |
2273 | } |
2264 | |
2274 | |
2265 | /* put the aura back in the player's inventory */ |
2275 | /* put the aura back in the player's inventory */ |
2266 | env->insert (aura); |
2276 | env->insert (aura); |
… | |
… | |
2285 | continue; |
2295 | continue; |
2286 | |
2296 | |
2287 | if (victim->stats.exp == 0) |
2297 | if (victim->stats.exp == 0) |
2288 | continue; |
2298 | continue; |
2289 | |
2299 | |
2290 | def_lev = MAX (1, victim->level); |
2300 | def_lev = max (1, victim->level); |
2291 | atk_lev = MAX (1, op->level); |
2301 | atk_lev = max (1, op->level); |
2292 | |
2302 | |
2293 | if (rndm (0, atk_lev - 1) > def_lev) |
2303 | if (rndm (0, atk_lev - 1) > def_lev) |
2294 | { |
2304 | { |
2295 | /* make this sucker peaceful. */ |
2305 | /* make this sucker peaceful. */ |
2296 | |
2306 | |
… | |
… | |
2328 | { |
2338 | { |
2329 | new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); |
2339 | new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); |
2330 | return 0; |
2340 | return 0; |
2331 | } |
2341 | } |
2332 | |
2342 | |
2333 | if (strcasestr_local (msg, "endmsg")) |
2343 | if (!msg_is_safe (msg)) |
2334 | { |
2344 | { |
2335 | new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); |
2345 | 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); |
2346 | LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg); |
2337 | return 0; |
2347 | return 0; |
2338 | } |
2348 | } |
2339 | |
2349 | |
2340 | if (!spell->other_arch) |
2350 | if (!spell->other_arch) |
2341 | return 0; |
2351 | return 0; |
2342 | |
2352 | |
2343 | object *tmp = arch_to_object (spell->other_arch); |
2353 | object *tmp = spell->other_arch->instance (); |
2344 | |
2354 | |
2345 | tmp->race = op->name; /*Save the owner of the rune */ |
2355 | tmp->race = op->name; /*Save the owner of the rune */ |
2346 | tmp->msg = msg; |
2356 | tmp->msg = msg; |
2347 | |
2357 | |
2348 | tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); |
2358 | tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); |