… | |
… | |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 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 | |
… | |
… | |
122 | * The # of arrows created also goes up with level, so if a 30th level mage |
123 | * The # of arrows created also goes up with level, so if a 30th level mage |
123 | * wants LOTS of arrows, and doesn't care what the plus is he could |
124 | * wants LOTS of arrows, and doesn't care what the plus is he could |
124 | * create nonnmagic arrows, or even -1, etc... |
125 | * create nonnmagic arrows, or even -1, etc... |
125 | */ |
126 | */ |
126 | int |
127 | int |
127 | cast_create_missile (object *op, object *caster, object *spell, int dir, const char *stringarg) |
128 | cast_create_missile (object *op, object *caster, object *spell, int dir, const char *spellparam) |
128 | { |
129 | { |
129 | int bonus_plus = 0; |
130 | int bonus_plus = 0; |
130 | const char *missile_name = "arrow"; |
131 | const char *missile_name = "arrow"; |
131 | |
132 | |
132 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
133 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
… | |
… | |
143 | return 0; |
144 | return 0; |
144 | } |
145 | } |
145 | |
146 | |
146 | object *missile = missile_arch->instance (); |
147 | object *missile = missile_arch->instance (); |
147 | |
148 | |
148 | if (stringarg) |
149 | if (spellparam) |
149 | { |
150 | { |
150 | /* If it starts with a letter, presume it is a description */ |
151 | /* If it starts with a letter, presume it is a description */ |
151 | if (isalpha (*stringarg)) |
152 | if (isalpha (*spellparam)) |
152 | { |
153 | { |
153 | artifact *al = find_artifactlist (missile->type)->items; |
154 | artifact *al = find_artifactlist (missile->type)->items; |
154 | |
155 | |
155 | for (; al; al = al->next) |
156 | for (; al; al = al->next) |
156 | if (!strcasecmp (al->item->name, stringarg)) |
157 | if (!strcasecmp (al->item->name, spellparam)) |
157 | break; |
158 | break; |
158 | |
159 | |
159 | if (!al) |
160 | if (!al) |
160 | { |
161 | { |
161 | missile->destroy (); |
162 | missile->destroy (); |
162 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, stringarg); |
163 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, spellparam); |
163 | return 0; |
164 | return 0; |
164 | } |
165 | } |
165 | |
166 | |
166 | if (al->item->slaying) |
167 | if (al->item->slaying) |
167 | { |
168 | { |
168 | missile->destroy (); |
169 | missile->destroy (); |
169 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, stringarg); |
170 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, spellparam); |
170 | return 0; |
171 | return 0; |
171 | } |
172 | } |
172 | |
173 | |
173 | give_artifact_abilities (missile, al->item); |
174 | give_artifact_abilities (missile, al->item); |
174 | /* These special arrows cost something extra. Don't have them also be magical - |
175 | /* These special arrows cost something extra. Don't have them also be magical - |
… | |
… | |
176 | * the parsing of having to do both plus and type. |
177 | * the parsing of having to do both plus and type. |
177 | */ |
178 | */ |
178 | bonus_plus = 1 + (al->item->value / 5); |
179 | bonus_plus = 1 + (al->item->value / 5); |
179 | missile_plus = 0; |
180 | missile_plus = 0; |
180 | } |
181 | } |
181 | else if (atoi (stringarg) < missile_plus) |
182 | else if (atoi (spellparam) < missile_plus) |
182 | missile_plus = atoi (stringarg); |
183 | missile_plus = atoi (spellparam); |
183 | } |
184 | } |
184 | |
185 | |
185 | missile_plus = clamp (missile_plus, -4, 4); |
186 | missile_plus = clamp (missile_plus, -4, 4); |
186 | |
187 | |
187 | missile->nrof = spell->duration + SP_level_duration_adjust (caster, spell); |
188 | missile->nrof = spell->duration + SP_level_duration_adjust (caster, spell); |
… | |
… | |
202 | return 1; |
203 | return 1; |
203 | } |
204 | } |
204 | |
205 | |
205 | |
206 | |
206 | /* allows the choice of what sort of food object to make. |
207 | /* allows the choice of what sort of food object to make. |
207 | * If stringarg is NULL, it will create food dependent on level --PeterM*/ |
208 | * If spellparam is NULL, it will create food dependent on level --PeterM*/ |
208 | int |
209 | int |
209 | cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *stringarg) |
210 | cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam) |
210 | { |
211 | { |
211 | int food_value; |
212 | int food_value; |
212 | archetype *at = NULL; |
213 | archetype *at = NULL; |
213 | object *new_op; |
214 | object *new_op; |
214 | |
215 | |
215 | food_value = spell_ob->stats.food + 50 * SP_level_duration_adjust (caster, spell_ob); |
216 | food_value = spell_ob->stats.food + 50 * SP_level_duration_adjust (caster, spell_ob); |
216 | |
217 | |
217 | if (stringarg) |
218 | if (spellparam) |
218 | { |
219 | { |
219 | at = find_archetype_by_object_type_name (FOOD, stringarg); |
220 | at = find_archetype_by_object_type_name (FOOD, spellparam); |
220 | if (at == NULL) |
221 | if (at == NULL) |
221 | at = find_archetype_by_object_type_name (DRINK, stringarg); |
222 | at = find_archetype_by_object_type_name (DRINK, spellparam); |
222 | if (at == NULL || at->stats.food > food_value) |
223 | if (at == NULL || at->stats.food > food_value) |
223 | stringarg = NULL; |
224 | spellparam = NULL; |
224 | } |
225 | } |
225 | |
226 | |
226 | if (!stringarg) |
227 | if (!spellparam) |
227 | { |
228 | { |
228 | archetype *at_tmp; |
229 | archetype *at_tmp; |
229 | |
230 | |
230 | /* We try to find the archetype with the maximum food value. |
231 | /* We try to find the archetype with the maximum food value. |
231 | * This removes the dependancy of hard coded food values in this |
232 | * This removes the dependancy of hard coded food values in this |
… | |
… | |
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; |
… | |
… | |
777 | |
778 | |
778 | return 1; |
779 | return 1; |
779 | } |
780 | } |
780 | |
781 | |
781 | int |
782 | int |
782 | dimension_door (object *op, object *caster, object *spob, int dir) |
783 | dimension_door (object *op, object *caster, object *spob, int dir, const char *spellparam) |
783 | { |
784 | { |
784 | uint32 dist, maxdist; |
785 | uint32 dist, maxdist; |
785 | int mflags; |
786 | int mflags; |
786 | maptile *m; |
787 | maptile *m; |
787 | sint16 sx, sy; |
788 | sint16 sx, sy; |
… | |
… | |
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. |
800 | */ |
801 | */ |
801 | maxdist = spob->range + SP_level_range_adjust (caster, spob); |
802 | maxdist = spob->range + SP_level_range_adjust (caster, spob); |
802 | |
803 | |
803 | if (op->contr->count) |
804 | if (spellparam) |
804 | { |
805 | { |
|
|
806 | int count = atoi (spellparam); |
|
|
807 | |
805 | if (op->contr->count > maxdist) |
808 | if (count > maxdist) |
806 | { |
809 | { |
807 | new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); |
810 | new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); |
808 | return 0; |
811 | return 0; |
809 | } |
812 | } |
810 | |
813 | |
811 | for (dist = 0; dist < op->contr->count; dist++) |
814 | for (dist = 0; dist < count; dist++) |
812 | { |
815 | { |
813 | mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); |
816 | mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); |
814 | |
817 | |
815 | if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) |
818 | if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) |
816 | break; |
819 | break; |
817 | |
820 | |
818 | if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) |
821 | if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) |
819 | break; |
822 | break; |
820 | } |
823 | } |
821 | |
824 | |
822 | if (dist < op->contr->count) |
825 | if (dist < count) |
823 | { |
826 | { |
824 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the spell.\n"); |
827 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the spell.\n"); |
825 | op->contr->count = 0; |
|
|
826 | return 0; |
828 | return 0; |
827 | } |
829 | } |
828 | |
|
|
829 | op->contr->count = 0; |
|
|
830 | |
830 | |
831 | /* Remove code that puts player on random space on maps. IMO, |
831 | /* Remove code that puts player on random space on maps. IMO, |
832 | * a lot of maps probably have areas the player should not get to, |
832 | * a lot of maps probably have areas the player should not get to, |
833 | * but may not be marked as NO_MAGIC (as they may be bounded |
833 | * but may not be marked as NO_MAGIC (as they may be bounded |
834 | * by such squares). Also, there are probably treasure rooms and |
834 | * by such squares). Also, there are probably treasure rooms and |
… | |
… | |
885 | |
885 | |
886 | /* Actually move the player now */ |
886 | /* Actually move the player now */ |
887 | 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))) |
888 | return 1; |
888 | return 1; |
889 | |
889 | |
890 | 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 | |
891 | return 1; |
892 | return 1; |
892 | } |
893 | } |
893 | |
894 | |
894 | /* cast_heal: Heals something. |
895 | /* cast_heal: Heals something. |
895 | * op is the caster. |
896 | * op is the caster. |
… | |
… | |
950 | if (cure_disease (tmp, op, spell)) |
951 | if (cure_disease (tmp, op, spell)) |
951 | success = 1; |
952 | success = 1; |
952 | |
953 | |
953 | if (spell->attacktype & AT_POISON) |
954 | if (spell->attacktype & AT_POISON) |
954 | { |
955 | { |
955 | at = archetype::find ("poisoning"); |
956 | at = archetype::find (shstr_poisoning); |
956 | poison = present_arch_in_ob (at, tmp); |
957 | poison = present_arch_in_ob (at, tmp); |
957 | if (poison) |
958 | if (poison) |
958 | { |
959 | { |
959 | success = 1; |
960 | success = 1; |
960 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); |
961 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); |
… | |
… | |
962 | } |
963 | } |
963 | } |
964 | } |
964 | |
965 | |
965 | if (spell->attacktype & AT_CONFUSION) |
966 | if (spell->attacktype & AT_CONFUSION) |
966 | { |
967 | { |
967 | poison = present_in_ob_by_name (FORCE, "confusion", tmp); |
968 | poison = present_in_ob_by_name (FORCE, shstr_confusion, tmp); |
968 | if (poison) |
969 | if (poison) |
969 | { |
970 | { |
970 | success = 1; |
971 | success = 1; |
971 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
972 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
972 | poison->duration = 1; |
973 | poison->duration = 1; |
973 | } |
974 | } |
974 | } |
975 | } |
975 | |
976 | |
976 | if (spell->attacktype & AT_BLIND) |
977 | if (spell->attacktype & AT_BLIND) |
977 | { |
978 | { |
978 | at = archetype::find ("blindness"); |
979 | at = archetype::find (shstr_blindness); |
979 | poison = present_arch_in_ob (at, tmp); |
980 | poison = present_arch_in_ob (at, tmp); |
980 | if (poison) |
981 | if (poison) |
981 | { |
982 | { |
982 | success = 1; |
983 | success = 1; |
983 | 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."); |
… | |
… | |
1031 | "You don't feel any more powerful." |
1032 | "You don't feel any more powerful." |
1032 | "You are no easier to look at.", |
1033 | "You are no easier to look at.", |
1033 | }; |
1034 | }; |
1034 | |
1035 | |
1035 | int |
1036 | int |
|
|
1037 | change_ability_duration (object *spell, object *caster) |
|
|
1038 | { |
|
|
1039 | return spell->duration + SP_level_duration_adjust (caster, spell) * 50; |
|
|
1040 | } |
|
|
1041 | |
|
|
1042 | int |
1036 | cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) |
1043 | cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) |
1037 | { |
1044 | { |
1038 | object *force = 0; |
1045 | object *force = 0; |
1039 | int i; |
1046 | int i; |
1040 | |
1047 | |
… | |
… | |
1057 | break; |
1064 | break; |
1058 | } |
1065 | } |
1059 | else if (spell_ob->race && spell_ob->race == tmp2->name) |
1066 | else if (spell_ob->race && spell_ob->race == tmp2->name) |
1060 | { |
1067 | { |
1061 | if (!silent) |
1068 | if (!silent) |
1062 | 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); |
1063 | |
1072 | |
1064 | return 0; |
1073 | return 0; |
1065 | } |
1074 | } |
1066 | } |
1075 | } |
1067 | } |
1076 | } |
1068 | |
1077 | |
|
|
1078 | int duration = change_ability_duration (spell_ob, caster); |
|
|
1079 | |
1069 | if (!force) |
1080 | if (force) |
1070 | { |
|
|
1071 | force = get_archetype (FORCE_NAME); |
|
|
1072 | force->subtype = FORCE_CHANGE_ABILITY; |
|
|
1073 | |
|
|
1074 | if (spell_ob->race) |
|
|
1075 | force->name = spell_ob->race; |
|
|
1076 | else |
|
|
1077 | force->name = spell_ob->name; |
|
|
1078 | |
|
|
1079 | force->name_pl = spell_ob->name; |
|
|
1080 | new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force."); |
|
|
1081 | |
|
|
1082 | } |
1081 | { |
1083 | else |
|
|
1084 | { |
|
|
1085 | int duration; |
|
|
1086 | |
|
|
1087 | duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; |
|
|
1088 | if (duration > force->duration) |
1082 | if (duration > force->duration) |
1089 | { |
1083 | { |
1090 | force->duration = duration; |
1084 | force->duration = duration; |
1091 | 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."); |
1092 | } |
1086 | } |
… | |
… | |
1094 | 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."); |
1095 | |
1089 | |
1096 | return 1; |
1090 | return 1; |
1097 | } |
1091 | } |
1098 | |
1092 | |
1099 | 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 | |
1100 | force->speed = 1.0; |
1108 | force->speed = 1.0; |
1101 | force->speed_left = -1.0; |
1109 | force->speed_left = -1.0; |
1102 | SET_FLAG (force, FLAG_APPLIED); |
1110 | SET_FLAG (force, FLAG_APPLIED); |
1103 | |
1111 | |
1104 | /* Now start processing the effects. First, protections */ |
1112 | /* Now start processing the effects. First, protections */ |
… | |
… | |
1242 | } |
1250 | } |
1243 | else |
1251 | else |
1244 | { |
1252 | { |
1245 | /* Only give out good benefits, and put a max on it */ |
1253 | /* Only give out good benefits, and put a max on it */ |
1246 | for (i = 0; i < NROFATTACKS; i++) |
1254 | for (i = 0; i < NROFATTACKS; i++) |
1247 | { |
|
|
1248 | if (god->resist[i] > 0) |
1255 | if (god->resist[i] > 0) |
1249 | { |
|
|
1250 | 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]); |
1251 | } |
1257 | |
1252 | } |
|
|
1253 | force->path_attuned |= god->path_attuned; |
1258 | force->path_attuned |= god->path_attuned; |
1254 | |
1259 | |
1255 | if (spell_ob->attacktype) |
1260 | if (spell_ob->attacktype) |
1256 | force->slaying = god->slaying; |
1261 | force->slaying = god->slaying; |
1257 | |
1262 | |
… | |
… | |
1322 | if (op->type != PLAYER) |
1327 | if (op->type != PLAYER) |
1323 | return 0; |
1328 | return 0; |
1324 | |
1329 | |
1325 | archetype *nugget[3]; |
1330 | archetype *nugget[3]; |
1326 | |
1331 | |
1327 | nugget[0] = archetype::find ("pyrite3"); |
1332 | nugget[0] = archetype::find (shstr_pyrite3); |
1328 | nugget[1] = archetype::find ("pyrite2"); |
1333 | nugget[1] = archetype::find (shstr_pyrite2); |
1329 | nugget[2] = archetype::find ("pyrite"); |
1334 | nugget[2] = archetype::find (shstr_pyrite); |
1330 | |
1335 | |
1331 | /* 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 |
1332 | * some, and also prevents people from alchemising every table/chair/clock |
1337 | * some, and also prevents people from alchemising every table/chair/clock |
1333 | * in sight |
1338 | * in sight |
1334 | */ |
1339 | */ |
… | |
… | |
1415 | * items. |
1420 | * items. |
1416 | */ |
1421 | */ |
1417 | int |
1422 | int |
1418 | remove_curse (object *op, object *caster, object *spell) |
1423 | remove_curse (object *op, object *caster, object *spell) |
1419 | { |
1424 | { |
1420 | object *tmp; |
|
|
1421 | int success = 0, was_one = 0; |
1425 | int success = 0, was_one = 0; |
1422 | |
1426 | |
1423 | for (tmp = op->inv; tmp; tmp = tmp->below) |
1427 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
1424 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && |
1428 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && |
1425 | ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) || |
1429 | ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) || |
1426 | (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED)))) |
1430 | (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED)))) |
1427 | { |
1431 | { |
1428 | was_one++; |
1432 | was_one++; |
… | |
… | |
1566 | for (tmp = last; tmp; tmp = tmp->below) |
1570 | for (tmp = last; tmp; tmp = tmp->below) |
1567 | { |
1571 | { |
1568 | /* show invisible */ |
1572 | /* show invisible */ |
1569 | if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && |
1573 | if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && |
1570 | /* Might there be other objects that we can make visible? */ |
1574 | /* Might there be other objects that we can make visible? */ |
1571 | (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) || |
1575 | (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) |
1572 | (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) |
1576 | || (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) |
1573 | || tmp->type == CF_HANDLE |
1577 | || tmp->type == T_HANDLE |
1574 | || tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE |
1578 | || tmp->type == TRAPDOOR |
|
|
1579 | || tmp->type == EXIT |
|
|
1580 | || tmp->type == HOLE |
|
|
1581 | || tmp->type == BUTTON |
1575 | || tmp->type == BUTTON || tmp->type == TELEPORTER |
1582 | || tmp->type == TELEPORTER |
|
|
1583 | || tmp->type == GATE |
1576 | || tmp->type == GATE || tmp->type == LOCKED_DOOR |
1584 | || tmp->type == LOCKED_DOOR |
1577 | || tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN |
1585 | || tmp->type == WEAPON |
|
|
1586 | || tmp->type == ALTAR |
|
|
1587 | || tmp->type == SIGN |
1578 | || tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY |
1588 | || tmp->type == TRIGGER_PEDESTAL |
1579 | || tmp->type == TREASURE || tmp->type == BOOK || tmp->type == HOLY_ALTAR))) |
1589 | || tmp->type == SPECIAL_KEY |
|
|
1590 | || tmp->type == TREASURE |
|
|
1591 | || tmp->type == BOOK |
|
|
1592 | || tmp->type == HOLY_ALTAR |
|
|
1593 | || tmp->type == CONTAINER))) |
1580 | { |
1594 | { |
1581 | if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) |
1595 | if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) |
1582 | { |
1596 | { |
1583 | tmp->invisible = 0; |
1597 | tmp->invisible = 0; |
1584 | done_one = 1; |
1598 | done_one = 1; |
… | |
… | |
2071 | |
2085 | |
2072 | /* attacktype */ |
2086 | /* attacktype */ |
2073 | if (!tmp->attacktype) |
2087 | if (!tmp->attacktype) |
2074 | tmp->attacktype = AT_PHYSICAL; |
2088 | tmp->attacktype = AT_PHYSICAL; |
2075 | |
2089 | |
2076 | if (materialtype_t *mt = name_to_material (op->materialname)) |
|
|
2077 | { |
|
|
2078 | for (i = 0; i < NROFATTACKS; i++) |
2090 | for (i = 0; i < NROFATTACKS; i++) |
2079 | tmp->resist[i] = 50 - (mt->save[i] * 5); |
2091 | tmp->resist[i] = 50 - (op->material->save[i] * 5); |
2080 | a = mt->save[0]; |
2092 | |
2081 | } |
2093 | a = op->material->save[0]; |
2082 | else |
|
|
2083 | { |
|
|
2084 | for (i = 0; i < NROFATTACKS; i++) |
|
|
2085 | tmp->resist[i] = 5; |
|
|
2086 | a = 10; |
|
|
2087 | } |
|
|
2088 | |
2094 | |
2089 | /* Set weapon's immunity */ |
2095 | /* Set weapon's immunity */ |
2090 | tmp->resist[ATNR_CONFUSION] = 100; |
2096 | tmp->resist[ATNR_CONFUSION] = 100; |
2091 | tmp->resist[ATNR_POISON] = 100; |
2097 | tmp->resist[ATNR_POISON] = 100; |
2092 | tmp->resist[ATNR_SLOW] = 100; |
2098 | tmp->resist[ATNR_SLOW] = 100; |
… | |
… | |
2119 | tmp->state = weapon->state; |
2125 | tmp->state = weapon->state; |
2120 | tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; |
2126 | tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE]; |
2121 | } |
2127 | } |
2122 | |
2128 | |
2123 | /* make experience increase in proportion to the strength of the summoned creature. */ |
2129 | /* make experience increase in proportion to the strength of the summoned creature. */ |
2124 | tmp->stats.exp *= 1 + (MAX (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); |
2130 | tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell)); |
2125 | |
2131 | |
2126 | tmp->speed_left = -1; |
2132 | tmp->speed_left = -1; |
2127 | tmp->direction = dir; |
2133 | tmp->direction = dir; |
2128 | |
2134 | |
2129 | m->insert (tmp, x, y, op); |
2135 | m->insert (tmp, x, y, op); |
… | |
… | |
2272 | continue; |
2278 | continue; |
2273 | |
2279 | |
2274 | if (victim->stats.exp == 0) |
2280 | if (victim->stats.exp == 0) |
2275 | continue; |
2281 | continue; |
2276 | |
2282 | |
2277 | def_lev = MAX (1, victim->level); |
2283 | def_lev = max (1, victim->level); |
2278 | atk_lev = MAX (1, op->level); |
2284 | atk_lev = max (1, op->level); |
2279 | |
2285 | |
2280 | if (rndm (0, atk_lev - 1) > def_lev) |
2286 | if (rndm (0, atk_lev - 1) > def_lev) |
2281 | { |
2287 | { |
2282 | /* make this sucker peaceful. */ |
2288 | /* make this sucker peaceful. */ |
2283 | |
2289 | |
… | |
… | |
2315 | { |
2321 | { |
2316 | new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); |
2322 | new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); |
2317 | return 0; |
2323 | return 0; |
2318 | } |
2324 | } |
2319 | |
2325 | |
2320 | if (strcasestr_local (msg, "endmsg")) |
2326 | if (!msg_is_safe (msg)) |
2321 | { |
2327 | { |
2322 | new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); |
2328 | new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); |
2323 | LOG (llevInfo, "write_rune: player %s tried to write bogus rune %s\n", &op->name, msg); |
2329 | LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg); |
2324 | return 0; |
2330 | return 0; |
2325 | } |
2331 | } |
2326 | |
2332 | |
2327 | if (!spell->other_arch) |
2333 | if (!spell->other_arch) |
2328 | return 0; |
2334 | return 0; |