… | |
… | |
122 | * The # of arrows created also goes up with level, so if a 30th level mage |
122 | * 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 |
123 | * wants LOTS of arrows, and doesn't care what the plus is he could |
124 | * create nonnmagic arrows, or even -1, etc... |
124 | * create nonnmagic arrows, or even -1, etc... |
125 | */ |
125 | */ |
126 | int |
126 | int |
127 | cast_create_missile (object *op, object *caster, object *spell, int dir, const char *stringarg) |
127 | cast_create_missile (object *op, object *caster, object *spell, int dir, const char *spellparam) |
128 | { |
128 | { |
129 | int bonus_plus = 0; |
129 | int bonus_plus = 0; |
130 | const char *missile_name = "arrow"; |
130 | const char *missile_name = "arrow"; |
131 | |
131 | |
132 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
132 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
… | |
… | |
143 | return 0; |
143 | return 0; |
144 | } |
144 | } |
145 | |
145 | |
146 | object *missile = missile_arch->instance (); |
146 | object *missile = missile_arch->instance (); |
147 | |
147 | |
148 | if (stringarg) |
148 | if (spellparam) |
149 | { |
149 | { |
150 | /* If it starts with a letter, presume it is a description */ |
150 | /* If it starts with a letter, presume it is a description */ |
151 | if (isalpha (*stringarg)) |
151 | if (isalpha (*spellparam)) |
152 | { |
152 | { |
153 | artifact *al = find_artifactlist (missile->type)->items; |
153 | artifact *al = find_artifactlist (missile->type)->items; |
154 | |
154 | |
155 | for (; al; al = al->next) |
155 | for (; al; al = al->next) |
156 | if (!strcasecmp (al->item->name, stringarg)) |
156 | if (!strcasecmp (al->item->name, spellparam)) |
157 | break; |
157 | break; |
158 | |
158 | |
159 | if (!al) |
159 | if (!al) |
160 | { |
160 | { |
161 | missile->destroy (); |
161 | missile->destroy (); |
162 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, stringarg); |
162 | new_draw_info_format (NDI_UNIQUE, 0, op, "No such object %ss of %s", missile_name, spellparam); |
163 | return 0; |
163 | return 0; |
164 | } |
164 | } |
165 | |
165 | |
166 | if (al->item->slaying) |
166 | if (al->item->slaying) |
167 | { |
167 | { |
168 | missile->destroy (); |
168 | missile->destroy (); |
169 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, stringarg); |
169 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are not allowed to create %ss of %s", missile_name, spellparam); |
170 | return 0; |
170 | return 0; |
171 | } |
171 | } |
172 | |
172 | |
173 | give_artifact_abilities (missile, al->item); |
173 | give_artifact_abilities (missile, al->item); |
174 | /* These special arrows cost something extra. Don't have them also be magical - |
174 | /* These special arrows cost something extra. Don't have them also be magical - |
… | |
… | |
176 | * the parsing of having to do both plus and type. |
176 | * the parsing of having to do both plus and type. |
177 | */ |
177 | */ |
178 | bonus_plus = 1 + (al->item->value / 5); |
178 | bonus_plus = 1 + (al->item->value / 5); |
179 | missile_plus = 0; |
179 | missile_plus = 0; |
180 | } |
180 | } |
181 | else if (atoi (stringarg) < missile_plus) |
181 | else if (atoi (spellparam) < missile_plus) |
182 | missile_plus = atoi (stringarg); |
182 | missile_plus = atoi (spellparam); |
183 | } |
183 | } |
184 | |
184 | |
185 | missile_plus = clamp (missile_plus, -4, 4); |
185 | missile_plus = clamp (missile_plus, -4, 4); |
186 | |
186 | |
187 | missile->nrof = spell->duration + SP_level_duration_adjust (caster, spell); |
187 | missile->nrof = spell->duration + SP_level_duration_adjust (caster, spell); |
… | |
… | |
202 | return 1; |
202 | return 1; |
203 | } |
203 | } |
204 | |
204 | |
205 | |
205 | |
206 | /* allows the choice of what sort of food object to make. |
206 | /* allows the choice of what sort of food object to make. |
207 | * If stringarg is NULL, it will create food dependent on level --PeterM*/ |
207 | * If spellparam is NULL, it will create food dependent on level --PeterM*/ |
208 | int |
208 | int |
209 | cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *stringarg) |
209 | cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam) |
210 | { |
210 | { |
211 | int food_value; |
211 | int food_value; |
212 | archetype *at = NULL; |
212 | archetype *at = NULL; |
213 | object *new_op; |
213 | object *new_op; |
214 | |
214 | |
215 | food_value = spell_ob->stats.food + 50 * SP_level_duration_adjust (caster, spell_ob); |
215 | food_value = spell_ob->stats.food + 50 * SP_level_duration_adjust (caster, spell_ob); |
216 | |
216 | |
217 | if (stringarg) |
217 | if (spellparam) |
218 | { |
218 | { |
219 | at = find_archetype_by_object_type_name (FOOD, stringarg); |
219 | at = find_archetype_by_object_type_name (FOOD, spellparam); |
220 | if (at == NULL) |
220 | if (at == NULL) |
221 | at = find_archetype_by_object_type_name (DRINK, stringarg); |
221 | at = find_archetype_by_object_type_name (DRINK, spellparam); |
222 | if (at == NULL || at->stats.food > food_value) |
222 | if (at == NULL || at->stats.food > food_value) |
223 | stringarg = NULL; |
223 | spellparam = NULL; |
224 | } |
224 | } |
225 | |
225 | |
226 | if (!stringarg) |
226 | if (!spellparam) |
227 | { |
227 | { |
228 | archetype *at_tmp; |
228 | archetype *at_tmp; |
229 | |
229 | |
230 | /* We try to find the archetype with the maximum food value. |
230 | /* We try to find the archetype with the maximum food value. |
231 | * This removes the dependancy of hard coded food values in this |
231 | * This removes the dependancy of hard coded food values in this |
… | |
… | |
777 | |
777 | |
778 | return 1; |
778 | return 1; |
779 | } |
779 | } |
780 | |
780 | |
781 | int |
781 | int |
782 | dimension_door (object *op, object *caster, object *spob, int dir) |
782 | dimension_door (object *op, object *caster, object *spob, int dir, const char *spellparam) |
783 | { |
783 | { |
784 | uint32 dist, maxdist; |
784 | uint32 dist, maxdist; |
785 | int mflags; |
785 | int mflags; |
786 | maptile *m; |
786 | maptile *m; |
787 | sint16 sx, sy; |
787 | sint16 sx, sy; |
… | |
… | |
798 | /* Given the new outdoor maps, can't let players dimension door for |
798 | /* Given the new outdoor maps, can't let players dimension door for |
799 | * ever, so put limits in. |
799 | * ever, so put limits in. |
800 | */ |
800 | */ |
801 | maxdist = spob->range + SP_level_range_adjust (caster, spob); |
801 | maxdist = spob->range + SP_level_range_adjust (caster, spob); |
802 | |
802 | |
803 | if (op->contr->count) |
803 | if (spellparam) |
804 | { |
804 | { |
|
|
805 | int count = atoi (spellparam); |
|
|
806 | |
805 | if (op->contr->count > maxdist) |
807 | if (count > maxdist) |
806 | { |
808 | { |
807 | new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); |
809 | new_draw_info (NDI_UNIQUE, 0, op, "You can't dimension door that far!"); |
808 | return 0; |
810 | return 0; |
809 | } |
811 | } |
810 | |
812 | |
811 | for (dist = 0; dist < op->contr->count; dist++) |
813 | for (dist = 0; dist < count; dist++) |
812 | { |
814 | { |
813 | mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); |
815 | mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy); |
814 | |
816 | |
815 | if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) |
817 | if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) |
816 | break; |
818 | break; |
817 | |
819 | |
818 | if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) |
820 | if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) |
819 | break; |
821 | break; |
820 | } |
822 | } |
821 | |
823 | |
822 | if (dist < op->contr->count) |
824 | if (dist < count) |
823 | { |
825 | { |
824 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the spell.\n"); |
826 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the spell.\n"); |
825 | op->contr->count = 0; |
|
|
826 | return 0; |
827 | return 0; |
827 | } |
828 | } |
828 | |
|
|
829 | op->contr->count = 0; |
|
|
830 | |
829 | |
831 | /* Remove code that puts player on random space on maps. IMO, |
830 | /* 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, |
831 | * 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 |
832 | * but may not be marked as NO_MAGIC (as they may be bounded |
834 | * by such squares). Also, there are probably treasure rooms and |
833 | * by such squares). Also, there are probably treasure rooms and |
… | |
… | |
1031 | "You don't feel any more powerful." |
1030 | "You don't feel any more powerful." |
1032 | "You are no easier to look at.", |
1031 | "You are no easier to look at.", |
1033 | }; |
1032 | }; |
1034 | |
1033 | |
1035 | int |
1034 | int |
|
|
1035 | change_ability_duration (object *spell, object *caster) |
|
|
1036 | { |
|
|
1037 | return spell->duration + SP_level_duration_adjust (caster, spell) * 50; |
|
|
1038 | } |
|
|
1039 | |
|
|
1040 | int |
1036 | cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) |
1041 | cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent) |
1037 | { |
1042 | { |
1038 | object *force = 0; |
1043 | object *force = 0; |
1039 | int i; |
1044 | int i; |
1040 | |
1045 | |
… | |
… | |
1080 | new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force."); |
1085 | new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force."); |
1081 | |
1086 | |
1082 | } |
1087 | } |
1083 | else |
1088 | else |
1084 | { |
1089 | { |
1085 | int duration; |
1090 | int duration = change_ability_duration (spell_ob, caster); |
1086 | |
1091 | |
1087 | duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50; |
|
|
1088 | if (duration > force->duration) |
1092 | if (duration > force->duration) |
1089 | { |
1093 | { |
1090 | force->duration = duration; |
1094 | force->duration = duration; |
1091 | new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); |
1095 | new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect."); |
1092 | } |
1096 | } |
… | |
… | |
1415 | * items. |
1419 | * items. |
1416 | */ |
1420 | */ |
1417 | int |
1421 | int |
1418 | remove_curse (object *op, object *caster, object *spell) |
1422 | remove_curse (object *op, object *caster, object *spell) |
1419 | { |
1423 | { |
1420 | object *tmp; |
|
|
1421 | int success = 0, was_one = 0; |
1424 | int success = 0, was_one = 0; |
1422 | |
1425 | |
1423 | for (tmp = op->inv; tmp; tmp = tmp->below) |
1426 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
1424 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && |
1427 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && |
1425 | ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) || |
1428 | ((QUERY_FLAG (tmp, FLAG_CURSED) && QUERY_FLAG (spell, FLAG_CURSED)) || |
1426 | (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED)))) |
1429 | (QUERY_FLAG (tmp, FLAG_DAMNED) && QUERY_FLAG (spell, FLAG_DAMNED)))) |
1427 | { |
1430 | { |
1428 | was_one++; |
1431 | was_one++; |