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.4 by root, Tue Aug 29 07:34:00 2006 UTC vs.
Revision 1.5 by root, Tue Aug 29 08:01:38 2006 UTC

1/* 1/*
2 * static char *rcsid_spell_effect_c = 2 * static char *rcsid_spell_effect_c =
3 * "$Id: spell_effect.C,v 1.4 2006/08/29 07:34:00 root Exp $"; 3 * "$Id: spell_effect.C,v 1.5 2006/08/29 08:01:38 root Exp $";
4 */ 4 */
5 5
6 6
7/* 7/*
8 CrossFire, A Multiplayer game for X-windows 8 CrossFire, A Multiplayer game for X-windows
66 object *wand, *tmp; 66 object *wand, *tmp;
67 int ncharges; 67 int ncharges;
68 68
69 wand = find_marked_object(op); 69 wand = find_marked_object(op);
70 if(wand == NULL || wand->type != WAND) { 70 if(wand == NULL || wand->type != WAND) {
71 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge."); 71 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge.");
72 return 0; 72 return 0;
73 } 73 }
74 if(!(random_roll(0, 3, op, PREFER_HIGH))) { 74 if(!(random_roll(0, 3, op, PREFER_HIGH))) {
75 new_draw_info_format(NDI_UNIQUE, 0, op, 75 new_draw_info_format(NDI_UNIQUE, 0, op,
76 "The %s vibrates violently, then explodes!",query_name(wand)); 76 "The %s vibrates violently, then explodes!",query_name(wand));
77 play_sound_map(op->map, op->x, op->y, SOUND_OB_EXPLODE); 77 play_sound_map(op->map, op->x, op->y, SOUND_OB_EXPLODE);
78 esrv_del_item(op->contr, wand->count); 78 esrv_del_item(op->contr, wand->count);
79 remove_ob(wand); 79 remove_ob(wand);
80 free_object(wand); 80 free_object(wand);
81 tmp = get_archetype("fireball"); 81 tmp = get_archetype("fireball");
82 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)) / 10; 82 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)) / 10;
83 if (!tmp->stats.dam) tmp->stats.dam = 1; 83 if (!tmp->stats.dam) tmp->stats.dam = 1;
84 tmp->stats.hp = tmp->stats.dam / 2; 84 tmp->stats.hp = tmp->stats.dam / 2;
85 if (tmp->stats.hp < 2) tmp->stats.hp = 2; 85 if (tmp->stats.hp < 2) tmp->stats.hp = 2;
86 tmp->x = op->x; 86 tmp->x = op->x;
87 tmp->y = op->y; 87 tmp->y = op->y;
88 insert_ob_in_map(tmp, op->map, NULL, 0); 88 insert_ob_in_map(tmp, op->map, NULL, 0);
89 return 1; 89 return 1;
90 } 90 }
91 91
92 ncharges = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)); 92 ncharges = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob));
93 if (wand->inv && wand->inv->level) 93 if (wand->inv && wand->inv->level)
94 ncharges /= wand->inv->level; 94 ncharges /= wand->inv->level;
95 else { 95 else {
96 new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", 96 new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.",
97 query_name(wand)); 97 query_name(wand));
98 return 0; 98 return 0;
99 } 99 }
100 if (!ncharges) ncharges = 1; 100 if (!ncharges) ncharges = 1;
101 101
102 wand->stats.food += ncharges; 102 wand->stats.food += ncharges;
103 new_draw_info_format(NDI_UNIQUE, 0, op, 103 new_draw_info_format(NDI_UNIQUE, 0, op,
104 "The %s glows with power.",query_name(wand)); 104 "The %s glows with power.",query_name(wand));
105 if(wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) { 105 if(wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) {
106 SET_FLAG(wand, FLAG_ANIMATE); 106 SET_FLAG(wand, FLAG_ANIMATE);
107 wand->speed = wand->arch->clone.speed; 107 wand->speed = wand->arch->clone.speed;
108 update_ob_speed(wand); 108 update_ob_speed(wand);
109 } 109 }
110 return 1; 110 return 1;
111} 111}
112 112
113/* Create a missile (nonmagic - magic +4). Will either create bolts or arrows 113/* Create a missile (nonmagic - magic +4). Will either create bolts or arrows
129 tag_t tag; 129 tag_t tag;
130 130
131 missile_name = "arrow"; 131 missile_name = "arrow";
132 132
133 for (tmp=op->inv; tmp != NULL; tmp=tmp->below) 133 for (tmp=op->inv; tmp != NULL; tmp=tmp->below)
134 if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED)) { 134 if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED)) {
135 missile_name=tmp->race; 135 missile_name=tmp->race;
136 } 136 }
137 137
138 missile_plus = spell->stats.dam + SP_level_dam_adjust(caster, spell); 138 missile_plus = spell->stats.dam + SP_level_dam_adjust(caster, spell);
139 139
140 if (find_archetype(missile_name)==NULL) { 140 if (find_archetype(missile_name)==NULL) {
141 LOG(llevDebug, "Cast create_missile: could not find archetype %s\n", 141 LOG(llevDebug, "Cast create_missile: could not find archetype %s\n",
142 missile_name); 142 missile_name);
143 return 0; 143 return 0;
144 } 144 }
145 missile = get_archetype(missile_name); 145 missile = get_archetype(missile_name);
146 146
147 if (stringarg) { 147 if (stringarg) {
148 /* If it starts with a letter, presume it is a description */ 148 /* If it starts with a letter, presume it is a description */
149 if (isalpha(*stringarg)) { 149 if (isalpha(*stringarg)) {
150 artifact *al = find_artifactlist(missile->type)->items; 150 artifact *al = find_artifactlist(missile->type)->items;
151 151
152 for ( ; al != NULL; al=al->next) 152 for ( ; al != NULL; al=al->next)
153 if (!strcasecmp(al->item->name, stringarg)) break; 153 if (!strcasecmp(al->item->name, stringarg)) break;
154 154
155 if (!al) { 155 if (!al) {
156 free_object(missile); 156 free_object(missile);
157 new_draw_info_format(NDI_UNIQUE, 0, op ,"No such object %ss of %s", missile_name, 157 new_draw_info_format(NDI_UNIQUE, 0, op ,"No such object %ss of %s", missile_name,
158 stringarg); 158 stringarg);
159 return 0; 159 return 0;
160 } 160 }
161 if (al->item->slaying) { 161 if (al->item->slaying) {
162 free_object(missile); 162 free_object(missile);
163 new_draw_info_format(NDI_UNIQUE, 0, op ,"You are not allowed to create %ss of %s", 163 new_draw_info_format(NDI_UNIQUE, 0, op ,"You are not allowed to create %ss of %s",
164 missile_name, stringarg); 164 missile_name, stringarg);
165 return 0; 165 return 0;
166 } 166 }
167 give_artifact_abilities(missile, al->item); 167 give_artifact_abilities(missile, al->item);
168 /* These special arrows cost something extra. Don't have them also be magical - 168 /* These special arrows cost something extra. Don't have them also be magical -
169 * otherwise, in most cases, not enough will be created. I don't want to get into 169 * otherwise, in most cases, not enough will be created. I don't want to get into
170 * the parsing of having to do both plus and type. 170 * the parsing of having to do both plus and type.
171 */ 171 */
172 bonus_plus = 1 + (al->item->value / 5); 172 bonus_plus = 1 + (al->item->value / 5);
173 missile_plus=0; 173 missile_plus=0;
174 } else 174 } else
175 if (atoi(stringarg) < missile_plus) 175 if (atoi(stringarg) < missile_plus)
176 missile_plus = atoi(stringarg); 176 missile_plus = atoi(stringarg);
177 } 177 }
178 if (missile_plus > 4) 178 if (missile_plus > 4)
179 missile_plus = 4; 179 missile_plus = 4;
180 else if (missile_plus < -4) 180 else if (missile_plus < -4)
181 missile_plus = -4; 181 missile_plus = -4;
182 182
183 missile->nrof = spell->duration + SP_level_duration_adjust(caster, spell); 183 missile->nrof = spell->duration + SP_level_duration_adjust(caster, spell);
184 missile->nrof -= 3 * (missile_plus + bonus_plus); 184 missile->nrof -= 3 * (missile_plus + bonus_plus);
185 if (missile->nrof < 1) 185 if (missile->nrof < 1)
186 missile->nrof=1; 186 missile->nrof=1;
187 187
188 missile->magic = missile_plus; 188 missile->magic = missile_plus;
189 /* Can't get any money for these objects */ 189 /* Can't get any money for these objects */
190 missile->value=0; 190 missile->value=0;
191 191
193 tag = missile->count; 193 tag = missile->count;
194 194
195 if ( ! cast_create_obj (op, caster, missile, dir) && op->type == PLAYER 195 if ( ! cast_create_obj (op, caster, missile, dir) && op->type == PLAYER
196 && ! was_destroyed (missile, tag)) 196 && ! was_destroyed (missile, tag))
197 { 197 {
198 pick_up(op, missile); 198 pick_up(op, missile);
199 } 199 }
200 return 1; 200 return 1;
201} 201}
202 202
203 203
211 211
212 food_value=spell_ob->stats.food + 212 food_value=spell_ob->stats.food +
213 + 50 * SP_level_duration_adjust(caster,spell_ob); 213 + 50 * SP_level_duration_adjust(caster,spell_ob);
214 214
215 if(stringarg) { 215 if(stringarg) {
216 at = find_archetype_by_object_type_name(FOOD, stringarg); 216 at = find_archetype_by_object_type_name(FOOD, stringarg);
217 if (at == NULL) 217 if (at == NULL)
218 at = find_archetype_by_object_type_name(DRINK, stringarg); 218 at = find_archetype_by_object_type_name(DRINK, stringarg);
219 if (at == NULL || at->clone.stats.food > food_value) 219 if (at == NULL || at->clone.stats.food > food_value)
220 stringarg = NULL; 220 stringarg = NULL;
221 } 221 }
222 222
223 if(!stringarg) { 223 if(!stringarg) {
224 archetype *at_tmp; 224 archetype *at_tmp;
225 225
226 /* We try to find the archetype with the maximum food value. 226 /* We try to find the archetype with the maximum food value.
227 * This removes the dependancy of hard coded food values in this 227 * This removes the dependancy of hard coded food values in this
228 * function, and addition of new food types is automatically added. 228 * function, and addition of new food types is automatically added.
229 * We don't use flesh types because the weight values of those need 229 * We don't use flesh types because the weight values of those need
230 * to be altered from the donor. 230 * to be altered from the donor.
231 */ 231 */
232 232
233 /* We assume the food items don't have multiple parts */ 233 /* We assume the food items don't have multiple parts */
234 for (at_tmp=first_archetype; at_tmp!=NULL; at_tmp=at_tmp->next) { 234 for (at_tmp=first_archetype; at_tmp!=NULL; at_tmp=at_tmp->next) {
235 if (at_tmp->clone.type==FOOD || at_tmp->clone.type==DRINK) { 235 if (at_tmp->clone.type==FOOD || at_tmp->clone.type==DRINK) {
236 /* Basically, if the food value is something that is creatable 236 /* Basically, if the food value is something that is creatable
237 * under the limits of the spell and it is higher than 237 * under the limits of the spell and it is higher than
238 * the item we have now, take it instead. 238 * the item we have now, take it instead.
239 */ 239 */
240 if (at_tmp->clone.stats.food<=food_value && 240 if (at_tmp->clone.stats.food<=food_value &&
241 (!at || at_tmp->clone.stats.food>at->clone.stats.food)) 241 (!at || at_tmp->clone.stats.food>at->clone.stats.food))
242 at=at_tmp; 242 at=at_tmp;
243 } 243 }
244 } 244 }
245 } 245 }
246 /* Pretty unlikely (there are some very low food items), but you never 246 /* Pretty unlikely (there are some very low food items), but you never
247 * know 247 * know
248 */ 248 */
249 if (!at) { 249 if (!at) {
250 new_draw_info(NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 250 new_draw_info(NDI_UNIQUE, 0, op, "You don't have enough experience to create any food.");
251 return 0; 251 return 0;
252 } 252 }
253 253
254 food_value/=at->clone.stats.food; 254 food_value/=at->clone.stats.food;
255 new_op = arch_to_object (at); 255 new_op = arch_to_object (at);
256 new_op->nrof = food_value; 256 new_op->nrof = food_value;
267 object *tmp; 267 object *tmp;
268 mapstruct *m; 268 mapstruct *m;
269 269
270 270
271 if(!dir) { 271 if(!dir) {
272 examine_monster(op,op); 272 examine_monster(op,op);
273 return 1; 273 return 1;
274 } 274 }
275 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob); 275 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob);
276 for(r=1;r < maxrange; r++) { 276 for(r=1;r < maxrange; r++) {
277 sint16 x=op->x+r*freearr_x[dir],y=op->y+r*freearr_y[dir]; 277 sint16 x=op->x+r*freearr_x[dir],y=op->y+r*freearr_y[dir];
278 278
279 m = op->map; 279 m = op->map;
280 mflags = get_map_flags(m, &m, x, y, &x, &y); 280 mflags = get_map_flags(m, &m, x, y, &x, &y);
281 281
282 if (mflags & P_OUT_OF_MAP) break; 282 if (mflags & P_OUT_OF_MAP) break;
283 283
284 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) { 284 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) {
285 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks your magic."); 285 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks your magic.");
286 return 0; 286 return 0;
287 } 287 }
288 if (mflags & P_IS_ALIVE) { 288 if (mflags & P_IS_ALIVE) {
289 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) 289 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above)
290 if(QUERY_FLAG(tmp, FLAG_ALIVE)&&(tmp->type==PLAYER||QUERY_FLAG(tmp, FLAG_MONSTER))) { 290 if(QUERY_FLAG(tmp, FLAG_ALIVE)&&(tmp->type==PLAYER||QUERY_FLAG(tmp, FLAG_MONSTER))) {
291 new_draw_info(NDI_UNIQUE, 0,op,"You detect something."); 291 new_draw_info(NDI_UNIQUE, 0,op,"You detect something.");
292 if(tmp->head!=NULL) 292 if(tmp->head!=NULL)
293 tmp=tmp->head; 293 tmp=tmp->head;
294 examine_monster(op,tmp); 294 examine_monster(op,tmp);
295 return 1; 295 return 1;
296 } 296 }
297 } 297 }
298 } 298 }
299 new_draw_info(NDI_UNIQUE, 0,op,"You detect nothing."); 299 new_draw_info(NDI_UNIQUE, 0,op,"You detect nothing.");
300 return 1; 300 return 1;
301} 301}
302 302
311int makes_invisible_to(object *pl, object *mon) 311int makes_invisible_to(object *pl, object *mon)
312{ 312{
313 313
314 if (!pl->invisible) return 0; 314 if (!pl->invisible) return 0;
315 if (pl->type == PLAYER ) { 315 if (pl->type == PLAYER ) {
316 /* If race isn't set, then invisible unless it is undead */ 316 /* If race isn't set, then invisible unless it is undead */
317 if (!pl->contr->invis_race) { 317 if (!pl->contr->invis_race) {
318 if (QUERY_FLAG(mon, FLAG_UNDEAD)) return 0; 318 if (QUERY_FLAG(mon, FLAG_UNDEAD)) return 0;
319 return 1; 319 return 1;
320 } 320 }
321 /* invis_race is set if we get here */ 321 /* invis_race is set if we get here */
322 if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon)) 322 if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon))
323 return 1; 323 return 1;
324 /* No race, can't be invisible to it */ 324 /* No race, can't be invisible to it */
325 if (!mon->race) return 0; 325 if (!mon->race) return 0;
326 if (strstr(mon->race, pl->contr->invis_race)) return 1; 326 if (strstr(mon->race, pl->contr->invis_race)) return 1;
327 /* Nothing matched above, return 0 */ 327 /* Nothing matched above, return 0 */
328 return 0; 328 return 0;
329 } else { 329 } else {
330 /* monsters are invisible to everything */ 330 /* monsters are invisible to everything */
331 return 1; 331 return 1;
332 } 332 }
333} 333}
334 334
335/* Makes the player or character invisible. 335/* Makes the player or character invisible.
336 * Note the spells to 'stack', but perhaps in odd ways. 336 * Note the spells to 'stack', but perhaps in odd ways.
343 */ 343 */
344int cast_invisible(object *op, object *caster, object *spell_ob) { 344int cast_invisible(object *op, object *caster, object *spell_ob) {
345 object *tmp; 345 object *tmp;
346 346
347 if(op->invisible>1000) { 347 if(op->invisible>1000) {
348 new_draw_info(NDI_UNIQUE, 0,op,"You can not extend the duration of your invisibility any further"); 348 new_draw_info(NDI_UNIQUE, 0,op,"You can not extend the duration of your invisibility any further");
349 return 0; 349 return 0;
350 } 350 }
351 351
352 /* Remove the switch with 90% duplicate code - just handle the differences with 352 /* Remove the switch with 90% duplicate code - just handle the differences with
353 * and if statement or two. 353 * and if statement or two.
354 */ 354 */
355 op->invisible += spell_ob->duration + SP_level_duration_adjust(caster, spell_ob); 355 op->invisible += spell_ob->duration + SP_level_duration_adjust(caster, spell_ob);
356 /* max duration */ 356 /* max duration */
357 if(op->invisible>1000) op->invisible = 1000; 357 if(op->invisible>1000) op->invisible = 1000;
358 358
359 if (op->type == PLAYER) { 359 if (op->type == PLAYER) {
360 if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race); 360 if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race);
361 if (spell_ob->race) 361 if (spell_ob->race)
362 op->contr->invis_race = add_refcount(spell_ob->race); 362 op->contr->invis_race = add_refcount(spell_ob->race);
363 if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS)) 363 if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS))
364 op->contr->tmp_invis=0; 364 op->contr->tmp_invis=0;
365 else 365 else
366 op->contr->tmp_invis=1; 366 op->contr->tmp_invis=1;
367 367
368 op->contr->hidden = 0; 368 op->contr->hidden = 0;
369 } 369 }
370 if (makes_invisible_to(op, op)) 370 if (makes_invisible_to(op, op))
371 new_draw_info(NDI_UNIQUE, 0,op,"You can't see your hands!"); 371 new_draw_info(NDI_UNIQUE, 0,op,"You can't see your hands!");
372 else 372 else
373 new_draw_info(NDI_UNIQUE, 0,op,"You feel more transparent!"); 373 new_draw_info(NDI_UNIQUE, 0,op,"You feel more transparent!");
374 374
375 update_object(op,UP_OBJ_FACE); 375 update_object(op,UP_OBJ_FACE);
376 376
377 /* Only search the active objects - only these should actually do 377 /* Only search the active objects - only these should actually do
378 * harm to the player. 378 * harm to the player.
379 */ 379 */
380 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next) 380 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next)
381 if (tmp->enemy == op) 381 if (tmp->enemy == op)
382 tmp->enemy = NULL; 382 tmp->enemy = NULL;
383 return 1; 383 return 1;
384} 384}
385 385
386/* earth to dust spell. Basically destroys earthwalls in the area. 386/* earth to dust spell. Basically destroys earthwalls in the area.
387 */ 387 */
390 int range,i,j, mflags; 390 int range,i,j, mflags;
391 sint16 sx, sy; 391 sint16 sx, sy;
392 mapstruct *m; 392 mapstruct *m;
393 393
394 if(op->type!=PLAYER) 394 if(op->type!=PLAYER)
395 return 0; 395 return 0;
396 396
397 range=spell_ob->range + SP_level_range_adjust(caster, spell_ob); 397 range=spell_ob->range + SP_level_range_adjust(caster, spell_ob);
398 398
399 for(i= -range;i<=range;i++) 399 for(i= -range;i<=range;i++)
400 for(j= -range;j<=range;j++) { 400 for(j= -range;j<=range;j++) {
401 sx = op->x + i; 401 sx = op->x + i;
402 sy = op->y + j; 402 sy = op->y + j;
403 m = op->map; 403 m = op->map;
404 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy); 404 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
405 405
406 if (mflags & P_OUT_OF_MAP) continue; 406 if (mflags & P_OUT_OF_MAP) continue;
407 407
408 // earth to dust tears down everything that can be teared down 408 // earth to dust tears down everything that can be teared down
409 for (tmp = get_map_ob(m, sx, sy); tmp != NULL; tmp = next) 409 for (tmp = get_map_ob(m, sx, sy); tmp != NULL; tmp = next)
410 { 410 {
411 next = tmp->above; 411 next = tmp->above;
412 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 412 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN))
413 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 413 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
414 } 414 }
415 } 415 }
416 return 1; 416 return 1;
417} 417}
418 418
419 419
420void execute_word_of_recall(object *op) { 420void execute_word_of_recall(object *op) {
421 object *wor=op; 421 object *wor=op;
422 while(op!=NULL && op->type!=PLAYER) 422 while(op!=NULL && op->type!=PLAYER)
423 op=op->env; 423 op=op->env;
424 424
425 if(op!=NULL && op->map) { 425 if(op!=NULL && op->map) {
426 if ((get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_CLERIC) && (!QUERY_FLAG(op,FLAG_WIZCAST))) 426 if ((get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_CLERIC) && (!QUERY_FLAG(op,FLAG_WIZCAST)))
427 new_draw_info(NDI_UNIQUE, 0,op,"You feel something fizzle inside you."); 427 new_draw_info(NDI_UNIQUE, 0,op,"You feel something fizzle inside you.");
428 else 428 else
429 enter_exit(op,wor); 429 enter_exit(op,wor);
430 } 430 }
431 remove_ob(wor); 431 remove_ob(wor);
432 free_object(wor); 432 free_object(wor);
433} 433}
434 434
439int cast_word_of_recall(object *op, object *caster, object *spell_ob) { 439int cast_word_of_recall(object *op, object *caster, object *spell_ob) {
440 object *dummy; 440 object *dummy;
441 int time; 441 int time;
442 442
443 if(op->type!=PLAYER) 443 if(op->type!=PLAYER)
444 return 0; 444 return 0;
445 445
446 if (find_obj_by_type_subtype(op,SPELL_EFFECT, SP_WORD_OF_RECALL)) 446 if (find_obj_by_type_subtype(op,SPELL_EFFECT, SP_WORD_OF_RECALL))
447 { 447 {
448 new_draw_info(NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you." ); 448 new_draw_info(NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you." );
449 return 1; 449 return 1;
450 } 450 }
451 451
452 dummy=get_archetype(FORCE_NAME); 452 dummy=get_archetype(FORCE_NAME);
453 if(dummy == NULL){ 453 if(dummy == NULL){
454 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 454 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
455 LOG(llevError,"cast_word_of_recall: get_archetype(force) failed!\n"); 455 LOG(llevError,"cast_word_of_recall: get_archetype(force) failed!\n");
456 return 0; 456 return 0;
457 } 457 }
458 time = spell_ob->duration - SP_level_duration_adjust(caster, spell_ob); 458 time = spell_ob->duration - SP_level_duration_adjust(caster, spell_ob);
459 if (time <1 ) time=1; 459 if (time <1 ) time=1;
460 460
461 /* value of speed really doesn't make much difference, as long as it is 461 /* value of speed really doesn't make much difference, as long as it is
486 */ 486 */
487int cast_wonder(object *op, object *caster, int dir, object *spell_ob) { 487int cast_wonder(object *op, object *caster, int dir, object *spell_ob) {
488 object *newspell; 488 object *newspell;
489 489
490 if(!rndm(0, 3)) 490 if(!rndm(0, 3))
491 return cast_cone(op,caster,dir, spell_ob); 491 return cast_cone(op,caster,dir, spell_ob);
492 492
493 if (spell_ob->randomitems) { 493 if (spell_ob->randomitems) {
494 newspell = generate_treasure(spell_ob->randomitems, caster->level); 494 newspell = generate_treasure(spell_ob->randomitems, caster->level);
495 if (!newspell) { 495 if (!newspell) {
496 LOG(llevError,"cast_wonder: Unable to get a spell!\n"); 496 LOG(llevError,"cast_wonder: Unable to get a spell!\n");
497 return 0; 497 return 0;
498 } 498 }
499 if (newspell->type != SPELL) { 499 if (newspell->type != SPELL) {
500 LOG(llevError,"cast_wonder: spell returned is not a spell (%d, %s)!\n", 500 LOG(llevError,"cast_wonder: spell returned is not a spell (%d, %s)!\n",
501 newspell->type, newspell->name); 501 newspell->type, newspell->name);
502 return 0; 502 return 0;
503 } 503 }
504 /* Prevent inifinit recursion */ 504 /* Prevent inifinit recursion */
505 if (newspell->subtype == SP_WONDER) { 505 if (newspell->subtype == SP_WONDER) {
506 LOG(llevError,"cast_wonder: spell returned is another wonder spell!\n"); 506 LOG(llevError,"cast_wonder: spell returned is another wonder spell!\n");
507 return 0; 507 return 0;
508 } 508 }
509 return cast_spell(op,caster,dir,newspell, NULL); 509 return cast_spell(op,caster,dir,newspell, NULL);
510 } 510 }
511 return 1; 511 return 1;
512} 512}
513 513
514 514
518 object *tmp; 518 object *tmp;
519 int i; 519 int i;
520 520
521 tmp=find_god(determine_god(op)); 521 tmp=find_god(determine_god(op));
522 if (tmp) 522 if (tmp)
523 new_draw_info_format(NDI_UNIQUE, 0, op, "You worship %s", tmp->name); 523 new_draw_info_format(NDI_UNIQUE, 0, op, "You worship %s", tmp->name);
524 else 524 else
525 new_draw_info(NDI_UNIQUE, 0,op,"You worship no god"); 525 new_draw_info(NDI_UNIQUE, 0,op,"You worship no god");
526 526
527 tmp=present_arch_in_ob(at,op); 527 tmp=present_arch_in_ob(at,op);
528 528
529 if(*cp=='\0' && tmp==NULL) 529 if(*cp=='\0' && tmp==NULL)
530 new_draw_info(NDI_UNIQUE, 0,op,"You feel very mundane"); 530 new_draw_info(NDI_UNIQUE, 0,op,"You feel very mundane");
531 else { 531 else {
532 new_draw_info(NDI_UNIQUE, 0,op,"You have:"); 532 new_draw_info(NDI_UNIQUE, 0,op,"You have:");
533 new_draw_info(NDI_UNIQUE, 0,op,cp); 533 new_draw_info(NDI_UNIQUE, 0,op,cp);
534 if (tmp!=NULL) { 534 if (tmp!=NULL) {
535 for (i=0; i<NUM_STATS; i++) { 535 for (i=0; i<NUM_STATS; i++) {
536 if (get_attr_value(&tmp->stats, i)<0) { 536 if (get_attr_value(&tmp->stats, i)<0) {
537 new_draw_info_format(NDI_UNIQUE, 0,op, 537 new_draw_info_format(NDI_UNIQUE, 0,op,
538 "Your %s is depleted by %d", statname[i], 538 "Your %s is depleted by %d", statname[i],
539 -(get_attr_value(&tmp->stats,i))); 539 -(get_attr_value(&tmp->stats,i)));
540 } 540 }
541 } 541 }
542 } 542 }
543 } 543 }
544 544
545 if (is_dragon_pl(op)) { 545 if (is_dragon_pl(op)) {
546 /* now grab the 'dragon_ability'-force from the player's inventory */ 546 /* now grab the 'dragon_ability'-force from the player's inventory */
547 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) { 547 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) {
548 if (tmp->type == FORCE && !strcmp(tmp->arch->name, "dragon_ability_force")) { 548 if (tmp->type == FORCE && !strcmp(tmp->arch->name, "dragon_ability_force")) {
549 if(tmp->stats.exp == 0) { 549 if(tmp->stats.exp == 0) {
550 sprintf(buf, "Your metabolism isn't focused on anything."); 550 sprintf(buf, "Your metabolism isn't focused on anything.");
551 } else { 551 } else {
552 sprintf(buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 552 sprintf(buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
553 } 553 }
554 new_draw_info(NDI_UNIQUE, 0,op, buf); 554 new_draw_info(NDI_UNIQUE, 0,op, buf);
555 break; 555 break;
556 } 556 }
557 } 557 }
558 } 558 }
559 return 1; 559 return 1;
560} 560}
561 561
562/* int cast_create_town_portal (object *op, object *caster, int dir) 562/* int cast_create_town_portal (object *op, object *caster, int dir)
589 /* Check to see if the map the player is currently on is a per player unique 589 /* Check to see if the map the player is currently on is a per player unique
590 * map. This can be determined in that per player unique maps have the 590 * map. This can be determined in that per player unique maps have the
591 * full pathname listed. 591 * full pathname listed.
592 */ 592 */
593 if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir)) && 593 if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir)) &&
594 settings.create_home_portals != TRUE ) 594 settings.create_home_portals != TRUE )
595 { 595 {
596 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n"); 596 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n");
597 return 0; 597 return 0;
598 } 598 }
599 599
600 /* The first thing to do is to check if we have a marked destination 600 /* The first thing to do is to check if we have a marked destination
601 * dummy is used to make a check inventory for the force 601 * dummy is used to make a check inventory for the force
602 */ 602 */
603 dummy=arch_to_object(spell->other_arch); 603 dummy=arch_to_object(spell->other_arch);
604 if(dummy == NULL){ 604 if(dummy == NULL){
605 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 605 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
606 LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name); 606 LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name);
607 return 0; 607 return 0;
608 } 608 }
609 force=check_inv_recursive (op,dummy); 609 force=check_inv_recursive (op,dummy);
610 610
611 if (force==NULL) { 611 if (force==NULL) {
612 /* Here we know there is no destination marked up. 612 /* Here we know there is no destination marked up.
613 * We have 2 things to do: 613 * We have 2 things to do:
614 * 1. Mark the destination in the player inventory. 614 * 1. Mark the destination in the player inventory.
615 * 2. Let the player know it worked. 615 * 2. Let the player know it worked.
616 */ 616 */
617 free_string (dummy->name); 617 free_string (dummy->name);
618 dummy->name = add_string (op->map->path); 618 dummy->name = add_string (op->map->path);
619 EXIT_X(dummy)= op->x; 619 EXIT_X(dummy)= op->x;
620 EXIT_Y(dummy)= op->y; 620 EXIT_Y(dummy)= op->y;
621 insert_ob_in_ob (dummy,op); 621 insert_ob_in_ob (dummy,op);
622 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere."); 622 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere.");
623 return 1; 623 return 1;
624 } 624 }
625 free_object (dummy); 625 free_object (dummy);
626 626
627 /* Here we know where the town portal should go to 627 /* Here we know where the town portal should go to
628 * We should kill any existing portal associated with the player. 628 * We should kill any existing portal associated with the player.
641 */ 641 */
642 642
643 /* First step: killing existing town portals */ 643 /* First step: killing existing town portals */
644 dummy=get_archetype(spell->race); 644 dummy=get_archetype(spell->race);
645 if(dummy == NULL){ 645 if(dummy == NULL){
646 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 646 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
647 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 647 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
648 return 0; 648 return 0;
649 } 649 }
650 perm_portal = find_archetype (spell->slaying); 650 perm_portal = find_archetype (spell->slaying);
651 651
652 /* To kill a town portal, we go trough the player's inventory, 652 /* To kill a town portal, we go trough the player's inventory,
653 * for each marked portal in player's inventory, 653 * for each marked portal in player's inventory,
655 * -We find any portal in the specified location. 655 * -We find any portal in the specified location.
656 * If it has the good name, we destruct it. 656 * If it has the good name, we destruct it.
657 * -We destruct the force indicating that portal. 657 * -We destruct the force indicating that portal.
658 */ 658 */
659 while ( (old_force=check_inv_recursive (op,dummy))) { 659 while ( (old_force=check_inv_recursive (op,dummy))) {
660 exitx=EXIT_X(old_force); 660 exitx=EXIT_X(old_force);
661 exity=EXIT_Y(old_force); 661 exity=EXIT_Y(old_force);
662 LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",old_force->race,exitx,exity); 662 LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",old_force->race,exitx,exity);
663 663
664 if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir))) 664 if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
665 exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE); 665 exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
666 else exitmap = ready_map_name(old_force->race, 0); 666 else exitmap = ready_map_name(old_force->race, 0);
667 667
668 if (exitmap) { 668 if (exitmap) {
669 tmp=present_arch (perm_portal,exitmap,exitx,exity); 669 tmp=present_arch (perm_portal,exitmap,exitx,exity);
670 while (tmp) { 670 while (tmp) {
671 if (tmp->name == old_force->name) { 671 if (tmp->name == old_force->name) {
672 remove_ob (tmp); 672 remove_ob (tmp);
673 free_object (tmp); 673 free_object (tmp);
674 break; 674 break;
675 } else { 675 } else {
676 tmp = tmp->above; 676 tmp = tmp->above;
677 } 677 }
678 } 678 }
679 } 679 }
680 remove_ob (old_force); 680 remove_ob (old_force);
681 free_object (old_force); 681 free_object (old_force);
682 LOG (llevDebug,"\n"); 682 LOG (llevDebug,"\n");
683 } 683 }
684 free_object (dummy); 684 free_object (dummy);
685 685
686 /* Creating the portals. 686 /* Creating the portals.
687 * The very first thing to do is to ensure 687 * The very first thing to do is to ensure
693 * from the players inventory above. 693 * from the players inventory above.
694 */ 694 */
695 695
696 /* Ensure exit map is loaded*/ 696 /* Ensure exit map is loaded*/
697 if (!strncmp(force->name, settings.localdir, strlen(settings.localdir))) 697 if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
698 exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE); 698 exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
699 else 699 else
700 exitmap = ready_map_name(force->name, 0); 700 exitmap = ready_map_name(force->name, 0);
701 701
702 /* If we were unable to load (ex. random map deleted), warn player*/ 702 /* If we were unable to load (ex. random map deleted), warn player*/
703 if (exitmap==NULL) { 703 if (exitmap==NULL) {
704 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?"); 704 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?");
705 remove_ob(force); 705 remove_ob(force);
706 free_object(force); 706 free_object(force);
707 return 1; 707 return 1;
708 } 708 }
709 709
710 op_level = caster_level(caster, spell); 710 op_level = caster_level(caster, spell);
711 if (op_level<15) 711 if (op_level<15)
712 snprintf (portal_message,1024,"\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n",op->name); 712 snprintf (portal_message,1024,"\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n",op->name);
722 */ 722 */
723 723
724 snprintf (portal_name,1024,"%s's portal to %s",op->name,force->name); 724 snprintf (portal_name,1024,"%s's portal to %s",op->name,force->name);
725 dummy=get_archetype(spell->slaying); /*The portal*/ 725 dummy=get_archetype(spell->slaying); /*The portal*/
726 if(dummy == NULL) { 726 if(dummy == NULL) {
727 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 727 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
728 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); 728 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name);
729 return 0; 729 return 0;
730 } 730 }
731 EXIT_PATH(dummy) = add_string (force->name); 731 EXIT_PATH(dummy) = add_string (force->name);
732 EXIT_X(dummy)=EXIT_X(force); 732 EXIT_X(dummy)=EXIT_X(force);
733 EXIT_Y(dummy)=EXIT_Y(force); 733 EXIT_Y(dummy)=EXIT_Y(force);
734 FREE_AND_COPY(dummy->name, portal_name); 734 FREE_AND_COPY(dummy->name, portal_name);
741 * object, so on future castings, we can know that he has an active 741 * object, so on future castings, we can know that he has an active
742 * town portal. 742 * town portal.
743 */ 743 */
744 tmp=get_archetype(spell->race); 744 tmp=get_archetype(spell->race);
745 if(tmp == NULL){ 745 if(tmp == NULL){
746 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 746 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
747 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 747 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
748 return 0; 748 return 0;
749 } 749 }
750 tmp->race=add_string (op->map->path); 750 tmp->race=add_string (op->map->path);
751 FREE_AND_COPY(tmp->name, portal_name); 751 FREE_AND_COPY(tmp->name, portal_name);
752 EXIT_X(tmp)=dummy->x; 752 EXIT_X(tmp)=dummy->x;
753 EXIT_Y(tmp)=dummy->y; 753 EXIT_Y(tmp)=dummy->y;
760 * where this portal goes to. 760 * where this portal goes to.
761 */ 761 */
762 snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path); 762 snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path);
763 dummy=get_archetype (spell->slaying); /*The portal*/ 763 dummy=get_archetype (spell->slaying); /*The portal*/
764 if(dummy == NULL) { 764 if(dummy == NULL) {
765 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 765 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
766 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); 766 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name);
767 return 0; 767 return 0;
768 } 768 }
769 EXIT_PATH(dummy) = add_string (op->map->path); 769 EXIT_PATH(dummy) = add_string (op->map->path);
770 EXIT_X(dummy)=op->x; 770 EXIT_X(dummy)=op->x;
771 EXIT_Y(dummy)=op->y; 771 EXIT_Y(dummy)=op->y;
772 FREE_AND_COPY(dummy->name, portal_name); 772 FREE_AND_COPY(dummy->name, portal_name);
780 /* Now we create another town portal marker that 780 /* Now we create another town portal marker that
781 * points back to the one we just made 781 * points back to the one we just made
782 */ 782 */
783 tmp=get_archetype(spell->race); 783 tmp=get_archetype(spell->race);
784 if(tmp == NULL){ 784 if(tmp == NULL){
785 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 785 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
786 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 786 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
787 return 0; 787 return 0;
788 } 788 }
789 tmp->race=add_string(force->name); 789 tmp->race=add_string(force->name);
790 FREE_AND_COPY(tmp->name, portal_name); 790 FREE_AND_COPY(tmp->name, portal_name);
791 EXIT_X(tmp)=dummy->x; 791 EXIT_X(tmp)=dummy->x;
792 EXIT_Y(tmp)=dummy->y; 792 EXIT_Y(tmp)=dummy->y;
812 mapstruct *m; 812 mapstruct *m;
813 const char *name; 813 const char *name;
814 archetype *at; 814 archetype *at;
815 815
816 if(!dir) { 816 if(!dir) {
817 dir=op->facing; 817 dir=op->facing;
818 x = op->x; 818 x = op->x;
819 y = op->y; 819 y = op->y;
820 } else { 820 } else {
821 x = op->x+freearr_x[dir]; 821 x = op->x+freearr_x[dir];
822 y = op->y+freearr_y[dir]; 822 y = op->y+freearr_y[dir];
823 } 823 }
824 m = op->map; 824 m = op->map;
825 825
826 if ((spell_ob->move_block || x != op->x || y != op->y) && 826 if ((spell_ob->move_block || x != op->x || y != op->y) &&
827 (get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE) || 827 (get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE) ||
828 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) { 828 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
829 new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way."); 829 new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way.");
830 return 0; 830 return 0;
831 } 831 }
832 if (spell_ob->other_arch) { 832 if (spell_ob->other_arch) {
833 tmp = arch_to_object(spell_ob->other_arch); 833 tmp = arch_to_object(spell_ob->other_arch);
834 } else if (spell_ob->race) { 834 } else if (spell_ob->race) {
835 char buf1[MAX_BUF]; 835 char buf1[MAX_BUF];
836 836
837 sprintf(buf1,spell_ob->race,dir); 837 sprintf(buf1,spell_ob->race,dir);
838 at = find_archetype(buf1); 838 at = find_archetype(buf1);
839 if (!at) { 839 if (!at) {
840 LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1); 840 LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
841 new_draw_info(NDI_UNIQUE, 0,op,"This spell is broken."); 841 new_draw_info(NDI_UNIQUE, 0,op,"This spell is broken.");
842 return 0; 842 return 0;
843 } 843 }
844 tmp = arch_to_object(at); 844 tmp = arch_to_object(at);
845 } else { 845 } else {
846 LOG(llevError,"magic_wall: spell %s lacks other_arch\n", 846 LOG(llevError,"magic_wall: spell %s lacks other_arch\n",
847 spell_ob->name); 847 spell_ob->name);
848 return 0; 848 return 0;
849 } 849 }
850 850
851 if (tmp->type == SPELL_EFFECT) { 851 if (tmp->type == SPELL_EFFECT) {
852 tmp->attacktype = spell_ob->attacktype; 852 tmp->attacktype = spell_ob->attacktype;
853 tmp->duration = spell_ob->duration + 853 tmp->duration = spell_ob->duration +
854 SP_level_duration_adjust(caster, spell_ob); 854 SP_level_duration_adjust(caster, spell_ob);
855 tmp->stats.dam = spell_ob->stats.dam + 855 tmp->stats.dam = spell_ob->stats.dam +
856 SP_level_dam_adjust(caster, spell_ob); 856 SP_level_dam_adjust(caster, spell_ob);
857 tmp->range = 0; 857 tmp->range = 0;
858 } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) { 858 } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
859 tmp->stats.hp = spell_ob->duration + 859 tmp->stats.hp = spell_ob->duration +
860 SP_level_duration_adjust(caster, spell_ob); 860 SP_level_duration_adjust(caster, spell_ob);
861 tmp->stats.maxhp = tmp->stats.hp; 861 tmp->stats.maxhp = tmp->stats.hp;
862 set_owner(tmp,op); 862 set_owner(tmp,op);
863 set_spell_skill(op, caster, spell_ob, tmp); 863 set_spell_skill(op, caster, spell_ob, tmp);
864 } 864 }
865 if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) { 865 if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
866 tmp->stats.food = spell_ob->duration + 866 tmp->stats.food = spell_ob->duration +
867 SP_level_duration_adjust(caster, spell_ob); 867 SP_level_duration_adjust(caster, spell_ob);
868 SET_FLAG(tmp, FLAG_IS_USED_UP); 868 SET_FLAG(tmp, FLAG_IS_USED_UP);
869 } 869 }
870 if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) { 870 if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
871 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob); 871 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob);
872 tmp->stats.maxhp = tmp->stats.hp; 872 tmp->stats.maxhp = tmp->stats.hp;
873 SET_FLAG(tmp, FLAG_TEAR_DOWN); 873 SET_FLAG(tmp, FLAG_TEAR_DOWN);
874 SET_FLAG(tmp, FLAG_ALIVE); 874 SET_FLAG(tmp, FLAG_ALIVE);
875 } 875 }
876 876
877 /* This can't really hurt - if the object doesn't kill anything, 877 /* This can't really hurt - if the object doesn't kill anything,
878 * these fields just won't be used. 878 * these fields just won't be used.
879 */ 879 */
883 tmp->y = y; 883 tmp->y = y;
884 tmp->level = caster_level(caster, spell_ob) / 2; 884 tmp->level = caster_level(caster, spell_ob) / 2;
885 885
886 name = tmp->name; 886 name = tmp->name;
887 if ((tmp = insert_ob_in_map (tmp, m, op,0)) == NULL) { 887 if ((tmp = insert_ob_in_map (tmp, m, op,0)) == NULL) {
888 new_draw_info_format(NDI_UNIQUE, 0,op,"Something destroys your %s", name); 888 new_draw_info_format(NDI_UNIQUE, 0,op,"Something destroys your %s", name);
889 return 0; 889 return 0;
890 } 890 }
891 /* If this is a spellcasting wall, need to insert the spell object */ 891 /* If this is a spellcasting wall, need to insert the spell object */
892 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL) 892 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
893 insert_ob_in_ob(arch_to_object(tmp->other_arch), tmp); 893 insert_ob_in_ob(arch_to_object(tmp->other_arch), tmp);
894 894
895 /* This code causes the wall to extend some distance in 895 /* This code causes the wall to extend some distance in
896 * each direction, or until an obstruction is encountered. 896 * each direction, or until an obstruction is encountered.
897 * posblocked and negblocked help determine how far the 897 * posblocked and negblocked help determine how far the
898 * created wall can extend, it won't go extend through 898 * created wall can extend, it won't go extend through
901 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob); 901 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob);
902 posblocked=0; 902 posblocked=0;
903 negblocked=0; 903 negblocked=0;
904 904
905 for(i=1; i<=maxrange; i++) { 905 for(i=1; i<=maxrange; i++) {
906 int dir2; 906 int dir2;
907 907
908 dir2 = (dir<4)?(dir+2):dir-2; 908 dir2 = (dir<4)?(dir+2):dir-2;
909 909
910 x = tmp->x+i*freearr_x[dir2]; 910 x = tmp->x+i*freearr_x[dir2];
911 y = tmp->y+i*freearr_y[dir2]; 911 y = tmp->y+i*freearr_y[dir2];
912 m = tmp->map; 912 m = tmp->map;
913 913
914 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) && 914 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) &&
915 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) && 915 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) &&
916 !posblocked) { 916 !posblocked) {
917 tmp2 = get_object(); 917 tmp2 = get_object();
918 copy_object(tmp,tmp2); 918 copy_object(tmp,tmp2);
919 tmp2->x = x; 919 tmp2->x = x;
920 tmp2->y = y; 920 tmp2->y = y;
921 insert_ob_in_map(tmp2,m,op,0); 921 insert_ob_in_map(tmp2,m,op,0);
922 /* If this is a spellcasting wall, need to insert the spell object */ 922 /* If this is a spellcasting wall, need to insert the spell object */
923 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 923 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
924 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2); 924 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2);
925 925
926 } else posblocked=1; 926 } else posblocked=1;
927 927
928 x = tmp->x-i*freearr_x[dir2]; 928 x = tmp->x-i*freearr_x[dir2];
929 y = tmp->y-i*freearr_y[dir2]; 929 y = tmp->y-i*freearr_y[dir2];
930 m = tmp->map; 930 m = tmp->map;
931 931
932 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) && 932 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) &&
933 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) && 933 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) &&
934 !negblocked) { 934 !negblocked) {
935 tmp2 = get_object(); 935 tmp2 = get_object();
936 copy_object(tmp,tmp2); 936 copy_object(tmp,tmp2);
937 tmp2->x = x; 937 tmp2->x = x;
938 tmp2->y = y; 938 tmp2->y = y;
939 insert_ob_in_map(tmp2,m,op,0); 939 insert_ob_in_map(tmp2,m,op,0);
940 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 940 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
941 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2); 941 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2);
942 } else negblocked=1; 942 } else negblocked=1;
943 } 943 }
944 944
945 if(QUERY_FLAG(tmp, FLAG_BLOCKSVIEW)) 945 if(QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
946 update_all_los(op->map, op->x, op->y); 946 update_all_los(op->map, op->x, op->y);
947 947
948 return 1; 948 return 1;
949} 949}
950 950
951int dimension_door(object *op,object *caster, object *spob, int dir) { 951int dimension_door(object *op,object *caster, object *spob, int dir) {
953 int mflags; 953 int mflags;
954 mapstruct *m; 954 mapstruct *m;
955 sint16 sx, sy; 955 sint16 sx, sy;
956 956
957 if(op->type!=PLAYER) 957 if(op->type!=PLAYER)
958 return 0; 958 return 0;
959 959
960 if(!dir) { 960 if(!dir) {
961 new_draw_info(NDI_UNIQUE, 0,op,"In what direction?"); 961 new_draw_info(NDI_UNIQUE, 0,op,"In what direction?");
962 return 0; 962 return 0;
963 } 963 }
964 964
965 /* Given the new outdoor maps, can't let players dimension door for 965 /* Given the new outdoor maps, can't let players dimension door for
966 * ever, so put limits in. 966 * ever, so put limits in.
967 */ 967 */
968 maxdist = spob->range + 968 maxdist = spob->range +
969 SP_level_range_adjust(caster, spob); 969 SP_level_range_adjust(caster, spob);
970 970
971 if(op->contr->count) { 971 if(op->contr->count) {
972 if (op->contr->count > maxdist) { 972 if (op->contr->count > maxdist) {
973 new_draw_info(NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 973 new_draw_info(NDI_UNIQUE, 0, op, "You can't dimension door that far!");
974 return 0; 974 return 0;
975 } 975 }
976 976
977 for(dist=0;dist<op->contr->count; dist++) { 977 for(dist=0;dist<op->contr->count; dist++) {
978 mflags = get_map_flags(op->map, &m, 978 mflags = get_map_flags(op->map, &m,
979 op->x+freearr_x[dir]*(dist+1), op->y+freearr_y[dir]*(dist+1), 979 op->x+freearr_x[dir]*(dist+1), op->y+freearr_y[dir]*(dist+1),
980 &sx, &sy); 980 &sx, &sy);
981 981
982 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break; 982 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break;
983 983
984 if ((mflags & P_BLOCKSVIEW) && 984 if ((mflags & P_BLOCKSVIEW) &&
985 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 985 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
986 } 986 }
987 987
988 if(dist<op->contr->count) { 988 if(dist<op->contr->count) {
989 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the spell.\n"); 989 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the spell.\n");
990 op->contr->count=0;
991 return 0;
992 }
990 op->contr->count=0; 993 op->contr->count=0;
991 return 0;
992 }
993 op->contr->count=0;
994 994
995 /* Remove code that puts player on random space on maps. IMO, 995 /* Remove code that puts player on random space on maps. IMO,
996 * a lot of maps probably have areas the player should not get to, 996 * a lot of maps probably have areas the player should not get to,
997 * but may not be marked as NO_MAGIC (as they may be bounded 997 * but may not be marked as NO_MAGIC (as they may be bounded
998 * by such squares). Also, there are probably treasure rooms and 998 * by such squares). Also, there are probably treasure rooms and
999 * lots of other maps that protect areas with no magic, but the 999 * lots of other maps that protect areas with no magic, but the
1000 * areas themselves don't contain no magic spaces. 1000 * areas themselves don't contain no magic spaces.
1001 */ 1001 */
1002 /* This call here is really just to normalize the coordinates */ 1002 /* This call here is really just to normalize the coordinates */
1003 mflags = get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist, 1003 mflags = get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1004 &sx, &sy); 1004 &sx, &sy);
1005 if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) { 1005 if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1006 new_draw_info(NDI_UNIQUE, 0,op,"You cast your spell, but nothing happens.\n"); 1006 new_draw_info(NDI_UNIQUE, 0,op,"You cast your spell, but nothing happens.\n");
1007 return 1; /* Maybe the penalty should be more severe... */ 1007 return 1; /* Maybe the penalty should be more severe... */
1008 } 1008 }
1009 } else { 1009 } else {
1010 /* Player didn't specify a distance, so lets see how far 1010 /* Player didn't specify a distance, so lets see how far
1011 * we can move the player. Don't know why this stopped on 1011 * we can move the player. Don't know why this stopped on
1012 * spaces that blocked the players view. 1012 * spaces that blocked the players view.
1013 */ 1013 */
1014 1014
1015 for(dist=0; dist < maxdist; dist++) { 1015 for(dist=0; dist < maxdist; dist++) {
1016 mflags = get_map_flags(op->map, &m, 1016 mflags = get_map_flags(op->map, &m,
1017 op->x+freearr_x[dir] * (dist+1), 1017 op->x+freearr_x[dir] * (dist+1),
1018 op->y+freearr_y[dir] * (dist+1), 1018 op->y+freearr_y[dir] * (dist+1),
1019 &sx, &sy); 1019 &sx, &sy);
1020 1020
1021 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break; 1021 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break;
1022 1022
1023 if ((mflags & P_BLOCKSVIEW) && 1023 if ((mflags & P_BLOCKSVIEW) &&
1024 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 1024 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
1025 1025
1026 } 1026 }
1027 1027
1028 /* If the destination is blocked, keep backing up until we 1028 /* If the destination is blocked, keep backing up until we
1029 * find a place for the player. 1029 * find a place for the player.
1030 */ 1030 */
1031 for(;dist>0; dist--) { 1031 for(;dist>0; dist--) {
1032 if (get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist, 1032 if (get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1033 &sx, &sy) & (P_OUT_OF_MAP|P_IS_ALIVE)) continue; 1033 &sx, &sy) & (P_OUT_OF_MAP|P_IS_ALIVE)) continue;
1034 1034
1035 1035
1036 if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 1036 if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
1037 1037
1038 } 1038 }
1039 if(!dist) { 1039 if(!dist) {
1040 new_draw_info(NDI_UNIQUE, 0,op,"Your spell failed!\n"); 1040 new_draw_info(NDI_UNIQUE, 0,op,"Your spell failed!\n");
1041 return 0; 1041 return 0;
1042 } 1042 }
1043 } 1043 }
1044 1044
1045 /* Actually move the player now */ 1045 /* Actually move the player now */
1046 remove_ob(op); 1046 remove_ob(op);
1047 op->x+=freearr_x[dir]*dist; 1047 op->x+=freearr_x[dir]*dist;
1072 /* Figure out how many hp this spell might cure. 1072 /* Figure out how many hp this spell might cure.
1073 * could be zero if this spell heals effects, not damage. 1073 * could be zero if this spell heals effects, not damage.
1074 */ 1074 */
1075 heal = spell->stats.dam; 1075 heal = spell->stats.dam;
1076 if (spell->stats.hp) 1076 if (spell->stats.hp)
1077 heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH) + 1077 heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH) +
1078 spell->stats.hp; 1078 spell->stats.hp;
1079 1079
1080 if (heal) { 1080 if (heal) {
1081 if (tmp->stats.hp >= tmp->stats.maxhp) {
1082 new_draw_info(NDI_UNIQUE, 0,tmp, "You are already fully healed.");
1083 }
1084 else {
1085 /* See how many points we actually heal. Instead of messages
1086 * based on type of spell, we instead do messages based
1087 * on amount of damage healed.
1088 */
1089 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1090 heal = tmp->stats.maxhp - tmp->stats.hp;
1091 tmp->stats.hp += heal;
1092
1093 if (tmp->stats.hp >= tmp->stats.maxhp) { 1081 if (tmp->stats.hp >= tmp->stats.maxhp) {
1082 new_draw_info(NDI_UNIQUE, 0,tmp, "You are already fully healed.");
1083 }
1084 else {
1085 /* See how many points we actually heal. Instead of messages
1086 * based on type of spell, we instead do messages based
1087 * on amount of damage healed.
1088 */
1089 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1090 heal = tmp->stats.maxhp - tmp->stats.hp;
1091 tmp->stats.hp += heal;
1092
1093 if (tmp->stats.hp >= tmp->stats.maxhp) {
1094 new_draw_info(NDI_UNIQUE, 0,tmp, "You feel just fine!"); 1094 new_draw_info(NDI_UNIQUE, 0,tmp, "You feel just fine!");
1095 } else if (heal > 50) { 1095 } else if (heal > 50) {
1096 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds close!"); 1096 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds close!");
1097 } else if (heal > 25) { 1097 } else if (heal > 25) {
1098 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds mostly close."); 1098 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds mostly close.");
1099 } else if (heal > 10) { 1099 } else if (heal > 10) {
1100 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to fade."); 1100 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to fade.");
1101 } else { 1101 } else {
1102 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to close."); 1102 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to close.");
1103 } 1103 }
1104 success=1; 1104 success=1;
1105 } 1105 }
1106 } 1106 }
1107 if (spell->attacktype & AT_DISEASE) 1107 if (spell->attacktype & AT_DISEASE)
1108 if (cure_disease (tmp, op)) 1108 if (cure_disease (tmp, op))
1109 success = 1; 1109 success = 1;
1110 1110
1111 if (spell->attacktype & AT_POISON) { 1111 if (spell->attacktype & AT_POISON) {
1112 at = find_archetype("poisoning"); 1112 at = find_archetype("poisoning");
1113 poison=present_arch_in_ob(at,tmp); 1113 poison=present_arch_in_ob(at,tmp);
1114 if (poison) { 1114 if (poison) {
1115 success = 1; 1115 success = 1;
1116 new_draw_info(NDI_UNIQUE, 0,tmp, "Your body feels cleansed"); 1116 new_draw_info(NDI_UNIQUE, 0,tmp, "Your body feels cleansed");
1117 poison->stats.food = 1; 1117 poison->stats.food = 1;
1118 } 1118 }
1119 } 1119 }
1120 if (spell->attacktype & AT_CONFUSION) { 1120 if (spell->attacktype & AT_CONFUSION) {
1121 poison=present_in_ob_by_name(FORCE,"confusion", tmp); 1121 poison=present_in_ob_by_name(FORCE,"confusion", tmp);
1122 if (poison) { 1122 if (poison) {
1123 success = 1; 1123 success = 1;
1124 new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer"); 1124 new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer");
1125 poison->duration = 1; 1125 poison->duration = 1;
1126 } 1126 }
1127 } 1127 }
1128 if (spell->attacktype & AT_BLIND) { 1128 if (spell->attacktype & AT_BLIND) {
1129 at=find_archetype("blindness"); 1129 at=find_archetype("blindness");
1130 poison=present_arch_in_ob(at,tmp); 1130 poison=present_arch_in_ob(at,tmp);
1131 if (poison) { 1131 if (poison) {
1132 success = 1; 1132 success = 1;
1133 new_draw_info(NDI_UNIQUE, 0,tmp,"Your vision begins to return."); 1133 new_draw_info(NDI_UNIQUE, 0,tmp,"Your vision begins to return.");
1134 poison->stats.food = 1; 1134 poison->stats.food = 1;
1135 } 1135 }
1136 } 1136 }
1137 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) { 1137 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) {
1138 tmp->stats.sp += spell->last_sp; 1138 tmp->stats.sp += spell->last_sp;
1139 if (tmp->stats.sp > tmp->stats.maxsp) tmp->stats.sp = tmp->stats.maxsp; 1139 if (tmp->stats.sp > tmp->stats.maxsp) tmp->stats.sp = tmp->stats.maxsp;
1140 success = 1; 1140 success = 1;
1141 new_draw_info(NDI_UNIQUE, 0,tmp,"Magical energy surges through your body!"); 1141 new_draw_info(NDI_UNIQUE, 0,tmp,"Magical energy surges through your body!");
1142 } 1142 }
1143 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) { 1143 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) {
1144 tmp->stats.grace += spell->last_grace; 1144 tmp->stats.grace += spell->last_grace;
1145 if (tmp->stats.grace > tmp->stats.maxgrace) tmp->stats.grace = tmp->stats.maxgrace; 1145 if (tmp->stats.grace > tmp->stats.maxgrace) tmp->stats.grace = tmp->stats.maxgrace;
1146 success = 1; 1146 success = 1;
1147 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel redeemed with your god!"); 1147 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel redeemed with your god!");
1148 } 1148 }
1149 if (spell->stats.food && tmp->stats.food < 999) { 1149 if (spell->stats.food && tmp->stats.food < 999) {
1150 tmp->stats.food += spell->stats.food; 1150 tmp->stats.food += spell->stats.food;
1151 if (tmp->stats.food > 999) tmp->stats.food=999; 1151 if (tmp->stats.food > 999) tmp->stats.food=999;
1152 success = 1; 1152 success = 1;
1153 /* We could do something a bit better like the messages for healing above */ 1153 /* We could do something a bit better like the messages for healing above */
1154 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel your belly fill with food"); 1154 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel your belly fill with food");
1155 } 1155 }
1156 return success; 1156 return success;
1157} 1157}
1158 1158
1159 1159
1176 object *force=NULL; 1176 object *force=NULL;
1177 int i; 1177 int i;
1178 1178
1179 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */ 1179 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1180 if(dir!=0) { 1180 if(dir!=0) {
1181 tmp=find_target_for_friendly_spell(op,dir); 1181 tmp=find_target_for_friendly_spell(op,dir);
1182 } else { 1182 } else {
1183 tmp = op; 1183 tmp = op;
1184 } 1184 }
1185 1185
1186 if(tmp==NULL) return 0; 1186 if(tmp==NULL) return 0;
1187 1187
1188 /* If we've already got a force of this type, don't add a new one. */ 1188 /* If we've already got a force of this type, don't add a new one. */
1189 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) { 1189 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) {
1190 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) { 1190 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1191 if (tmp2->name == spell_ob->name) { 1191 if (tmp2->name == spell_ob->name) {
1192 force=tmp2; /* the old effect will be "refreshed" */ 1192 force=tmp2; /* the old effect will be "refreshed" */
1193 break; 1193 break;
1194 } 1194 }
1195 else if (spell_ob->race && spell_ob->race == tmp2->name) { 1195 else if (spell_ob->race && spell_ob->race == tmp2->name) {
1196 if ( !silent ) 1196 if ( !silent )
1197 new_draw_info_format(NDI_UNIQUE, 0, op, 1197 new_draw_info_format(NDI_UNIQUE, 0, op,
1198 "You can not cast %s while %s is in effect", 1198 "You can not cast %s while %s is in effect",
1199 spell_ob->name, tmp2->name_pl); 1199 spell_ob->name, tmp2->name_pl);
1200 return 0; 1200 return 0;
1201 } 1201 }
1202 } 1202 }
1203 } 1203 }
1204 if(force==NULL) { 1204 if(force==NULL) {
1205 force=get_archetype(FORCE_NAME); 1205 force=get_archetype(FORCE_NAME);
1206 force->subtype = FORCE_CHANGE_ABILITY; 1206 force->subtype = FORCE_CHANGE_ABILITY;
1207 free_string(force->name); 1207 free_string(force->name);
1208 if (spell_ob->race) 1208 if (spell_ob->race)
1209 force->name = add_refcount(spell_ob->race); 1209 force->name = add_refcount(spell_ob->race);
1210 else 1210 else
1211 force->name = add_refcount(spell_ob->name);
1212 free_string(force->name_pl);
1211 force->name = add_refcount(spell_ob->name); 1213 force->name_pl = add_refcount(spell_ob->name);
1212 free_string(force->name_pl);
1213 force->name_pl = add_refcount(spell_ob->name);
1214 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 1214 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1215 1215
1216 } else { 1216 } else {
1217 int duration; 1217 int duration;
1218 1218
1219 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1219 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1220 if (duration > force->duration) { 1220 if (duration > force->duration) {
1221 force->duration = duration; 1221 force->duration = duration;
1222 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1222 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1223 } else { 1223 } else {
1224 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1224 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1225 } 1225 }
1226 return 1; 1226 return 1;
1227 } 1227 }
1228 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1228 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1229 force->speed = 1.0; 1229 force->speed = 1.0;
1230 force->speed_left = -1.0; 1230 force->speed_left = -1.0;
1231 SET_FLAG(force, FLAG_APPLIED); 1231 SET_FLAG(force, FLAG_APPLIED);
1232 1232
1233 /* Now start processing the effects. First, protections */ 1233 /* Now start processing the effects. First, protections */
1234 for (i=0; i < NROFATTACKS; i++) { 1234 for (i=0; i < NROFATTACKS; i++) {
1235 if (spell_ob->resist[i]) { 1235 if (spell_ob->resist[i]) {
1236 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust(caster, spell_ob); 1236 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust(caster, spell_ob);
1237 if (force->resist[i] > 100) force->resist[i] = 100; 1237 if (force->resist[i] > 100) force->resist[i] = 100;
1238 } 1238 }
1239 } 1239 }
1240 if (spell_ob->stats.hp) 1240 if (spell_ob->stats.hp)
1241 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust(caster,spell_ob); 1241 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust(caster,spell_ob);
1242 1242
1243 if (tmp->type == PLAYER) { 1243 if (tmp->type == PLAYER) {
1244 /* Stat adjustment spells */ 1244 /* Stat adjustment spells */
1245 for (i=0; i < NUM_STATS; i++) { 1245 for (i=0; i < NUM_STATS; i++) {
1246 sint8 stat = get_attr_value(&spell_ob->stats, i), k, sm; 1246 sint8 stat = get_attr_value(&spell_ob->stats, i), k, sm;
1247 if (stat) { 1247 if (stat) {
1248 sm=0; 1248 sm=0;
1249 for (k=0; k<stat; k++) 1249 for (k=0; k<stat; k++)
1250 sm += rndm(1, 3); 1250 sm += rndm(1, 3);
1251 1251
1252 if ((get_attr_value(&tmp->stats, i) + sm) > (15 + 5 * stat)) { 1252 if ((get_attr_value(&tmp->stats, i) + sm) > (15 + 5 * stat)) {
1253 sm = (15 + 5 * stat) - get_attr_value(&tmp->stats, i); 1253 sm = (15 + 5 * stat) - get_attr_value(&tmp->stats, i);
1254 if (sm<0) sm = 0; 1254 if (sm<0) sm = 0;
1255 } 1255 }
1256 set_attr_value(&force->stats, i, sm); 1256 set_attr_value(&force->stats, i, sm);
1257 if (!sm) 1257 if (!sm)
1258 new_draw_info(NDI_UNIQUE, 0,op,no_gain_msgs[i]); 1258 new_draw_info(NDI_UNIQUE, 0,op,no_gain_msgs[i]);
1259 } 1259 }
1260 } 1260 }
1261 } 1261 }
1262 1262
1263 force->move_type = spell_ob->move_type; 1263 force->move_type = spell_ob->move_type;
1264 1264
1265 if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK)) 1265 if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
1266 SET_FLAG(force, FLAG_SEE_IN_DARK); 1266 SET_FLAG(force, FLAG_SEE_IN_DARK);
1267 1267
1268 if (QUERY_FLAG(spell_ob, FLAG_XRAYS)) 1268 if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
1269 SET_FLAG(force, FLAG_XRAYS); 1269 SET_FLAG(force, FLAG_XRAYS);
1270 1270
1271 /* Haste/bonus speed */ 1271 /* Haste/bonus speed */
1272 if (spell_ob->stats.exp) { 1272 if (spell_ob->stats.exp) {
1273 if (op->speed > 0.5f) force->stats.exp = (sint64) ((float) spell_ob->stats.exp / (op->speed + 0.5f)); 1273 if (op->speed > 0.5f) force->stats.exp = (sint64) ((float) spell_ob->stats.exp / (op->speed + 0.5f));
1274 else 1274 else
1275 force->stats.exp = spell_ob->stats.exp; 1275 force->stats.exp = spell_ob->stats.exp;
1276 } 1276 }
1277 1277
1278 force->stats.wc = spell_ob->stats.wc; 1278 force->stats.wc = spell_ob->stats.wc;
1279 force->stats.ac = spell_ob->stats.ac; 1279 force->stats.ac = spell_ob->stats.ac;
1280 force->attacktype = spell_ob->attacktype; 1280 force->attacktype = spell_ob->attacktype;
1294 int i; 1294 int i;
1295 object *god = find_god(determine_god(op)), *tmp2, *force=NULL, *tmp; 1295 object *god = find_god(determine_god(op)), *tmp2, *force=NULL, *tmp;
1296 1296
1297 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */ 1297 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1298 if(dir!=0) { 1298 if(dir!=0) {
1299 tmp=find_target_for_friendly_spell(op,dir); 1299 tmp=find_target_for_friendly_spell(op,dir);
1300 } else { 1300 } else {
1301 tmp = op; 1301 tmp = op;
1302 } 1302 }
1303 1303
1304 /* If we've already got a force of this type, don't add a new one. */ 1304 /* If we've already got a force of this type, don't add a new one. */
1305 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) { 1305 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) {
1306 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) { 1306 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1307 if (tmp2->name == spell_ob->name) { 1307 if (tmp2->name == spell_ob->name) {
1308 force=tmp2; /* the old effect will be "refreshed" */ 1308 force=tmp2; /* the old effect will be "refreshed" */
1309 break; 1309 break;
1310 } 1310 }
1311 else if (spell_ob->race && spell_ob->race == tmp2->name) { 1311 else if (spell_ob->race && spell_ob->race == tmp2->name) {
1312 new_draw_info_format(NDI_UNIQUE, 0, op, 1312 new_draw_info_format(NDI_UNIQUE, 0, op,
1313 "You can not cast %s while %s is in effect", 1313 "You can not cast %s while %s is in effect",
1314 spell_ob->name, tmp2->name_pl); 1314 spell_ob->name, tmp2->name_pl);
1315 return 0; 1315 return 0;
1316 } 1316 }
1317 } 1317 }
1318 } 1318 }
1319 if(force==NULL) { 1319 if(force==NULL) {
1320 force=get_archetype(FORCE_NAME); 1320 force=get_archetype(FORCE_NAME);
1321 force->subtype = FORCE_CHANGE_ABILITY; 1321 force->subtype = FORCE_CHANGE_ABILITY;
1322 free_string(force->name); 1322 free_string(force->name);
1323 if (spell_ob->race) 1323 if (spell_ob->race)
1324 force->name = add_refcount(spell_ob->race); 1324 force->name = add_refcount(spell_ob->race);
1325 else 1325 else
1326 force->name = add_refcount(spell_ob->name);
1327 free_string(force->name_pl);
1326 force->name = add_refcount(spell_ob->name); 1328 force->name_pl = add_refcount(spell_ob->name);
1327 free_string(force->name_pl);
1328 force->name_pl = add_refcount(spell_ob->name);
1329 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 1329 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1330 } else { 1330 } else {
1331 int duration; 1331 int duration;
1332 1332
1333 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1333 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1334 if (duration > force->duration) { 1334 if (duration > force->duration) {
1335 force->duration = duration; 1335 force->duration = duration;
1336 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1336 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1337 } else { 1337 } else {
1338 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1338 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1339 } 1339 }
1340 return 0; 1340 return 0;
1341 } 1341 }
1342 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1342 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1343 force->speed = 1.0; 1343 force->speed = 1.0;
1344 force->speed_left = -1.0; 1344 force->speed_left = -1.0;
1345 SET_FLAG(force, FLAG_APPLIED); 1345 SET_FLAG(force, FLAG_APPLIED);
1346 1346
1347 if(!god) { 1347 if(!god) {
1348 new_draw_info(NDI_UNIQUE, 0,op,"Your blessing seems empty."); 1348 new_draw_info(NDI_UNIQUE, 0,op,"Your blessing seems empty.");
1349 } else { 1349 } else {
1350 /* Only give out good benefits, and put a max on it */ 1350 /* Only give out good benefits, and put a max on it */
1351 for (i=0; i<NROFATTACKS; i++) { 1351 for (i=0; i<NROFATTACKS; i++) {
1352 if (god->resist[i]>0) { 1352 if (god->resist[i]>0) {
1353 force->resist[i] = MIN(god->resist[i], spell_ob->resist[ATNR_GODPOWER]); 1353 force->resist[i] = MIN(god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1354 } 1354 }
1355 } 1355 }
1356 force->path_attuned|=god->path_attuned; 1356 force->path_attuned|=god->path_attuned;
1357 if (spell_ob->attacktype) { 1357 if (spell_ob->attacktype) {
1358 force->attacktype|=god->attacktype | AT_PHYSICAL; 1358 force->attacktype|=god->attacktype | AT_PHYSICAL;
1359 if(god->slaying) force->slaying = add_string(god->slaying); 1359 if(god->slaying) force->slaying = add_string(god->slaying);
1360 } 1360 }
1361 if (tmp != op) { 1361 if (tmp != op) {
1362 new_draw_info_format(NDI_UNIQUE, 0, op, "You bless %s.", tmp->name); 1362 new_draw_info_format(NDI_UNIQUE, 0, op, "You bless %s.", tmp->name);
1363 new_draw_info_format(NDI_UNIQUE, 0, tmp, "%s blessed you.", op->name); 1363 new_draw_info_format(NDI_UNIQUE, 0, tmp, "%s blessed you.", op->name);
1364 } else { 1364 } else {
1365 new_draw_info_format(NDI_UNIQUE, 0,tmp, 1365 new_draw_info_format(NDI_UNIQUE, 0,tmp,
1366 "You are blessed by %s!",god->name); 1366 "You are blessed by %s!",god->name);
1367 } 1367 }
1368 1368
1369 } 1369 }
1370 force->stats.wc = spell_ob->stats.wc; 1370 force->stats.wc = spell_ob->stats.wc;
1371 force->stats.ac = spell_ob->stats.ac; 1371 force->stats.ac = spell_ob->stats.ac;
1372 1372
1405 * is finished. 1405 * is finished.
1406 */ 1406 */
1407static object *small, *large; 1407static object *small, *large;
1408 1408
1409static void alchemy_object(object *obj, int *small_nuggets, 1409static void alchemy_object(object *obj, int *small_nuggets,
1410 int *large_nuggets, int *weight) 1410 int *large_nuggets, int *weight)
1411{ 1411{
1412 uint64 value=query_cost(obj, NULL, F_TRUE); 1412 uint64 value=query_cost(obj, NULL, F_TRUE);
1413 1413
1414 /* Give third price when we alchemy money (This should hopefully 1414 /* Give third price when we alchemy money (This should hopefully
1415 * make it so that it isn't worth it to alchemy money, sell 1415 * make it so that it isn't worth it to alchemy money, sell
1418 * so that it would still be more affordable to haul 1418 * so that it would still be more affordable to haul
1419 * the stuff back to town. 1419 * the stuff back to town.
1420 */ 1420 */
1421 1421
1422 if (QUERY_FLAG(obj, FLAG_UNPAID)) 1422 if (QUERY_FLAG(obj, FLAG_UNPAID))
1423 value=0; 1423 value=0;
1424 else if (obj->type==MONEY || obj->type==GEM) 1424 else if (obj->type==MONEY || obj->type==GEM)
1425 value /=3; 1425 value /=3;
1426 else 1426 else
1427 value = (value*9)/10; 1427 value = (value*9)/10;
1428 1428
1429 value /= 4; // fix by GHJ, don't understand, pcg 1429 value /= 4; // fix by GHJ, don't understand, pcg
1430 1430
1431 if ((obj->value>0) && rndm(0, 29)) { 1431 if ((obj->value>0) && rndm(0, 29)) {
1432 int count; 1432 int count;
1433 1433
1434 count = value / large->value; 1434 count = value / large->value;
1435 *large_nuggets += count; 1435 *large_nuggets += count;
1436 value -= (uint64)count * (uint64)large->value; 1436 value -= (uint64)count * (uint64)large->value;
1437 count = value / small->value; 1437 count = value / small->value;
1438 *small_nuggets += count; 1438 *small_nuggets += count;
1439 } 1439 }
1440 1440
1441 /* Turn 25 small nuggets into 1 large nugget. If the value 1441 /* Turn 25 small nuggets into 1 large nugget. If the value
1442 * of large nuggets is not evenly divisable by the small nugget 1442 * of large nuggets is not evenly divisable by the small nugget
1443 * value, take off an extra small_nugget (Assuming small_nuggets!=0) 1443 * value, take off an extra small_nugget (Assuming small_nuggets!=0)
1444 */ 1444 */
1445 if (*small_nuggets * small->value >= large->value) { 1445 if (*small_nuggets * small->value >= large->value) {
1446 (*large_nuggets)++; 1446 (*large_nuggets)++;
1447 *small_nuggets -= large->value / small->value; 1447 *small_nuggets -= large->value / small->value;
1448 if (*small_nuggets && large->value % small->value) 1448 if (*small_nuggets && large->value % small->value)
1449 (*small_nuggets)--; 1449 (*small_nuggets)--;
1450 } 1450 }
1451 weight += obj->weight; 1451 weight += obj->weight;
1452 remove_ob(obj); 1452 remove_ob(obj);
1453 free_object(obj); 1453 free_object(obj);
1454} 1454}
1455 1455
1456static void update_map(object *op, mapstruct *m, int small_nuggets, int large_nuggets, 1456static void update_map(object *op, mapstruct *m, int small_nuggets, int large_nuggets,
1457 int x, int y) 1457 int x, int y)
1458{ 1458{
1459 object *tmp; 1459 object *tmp;
1460 int flag=0; 1460 int flag=0;
1461 1461
1462 /* Put any nuggets below the player, but we can only pass this 1462 /* Put any nuggets below the player, but we can only pass this
1463 * flag if we are on the same space as the player 1463 * flag if we are on the same space as the player
1464 */ 1464 */
1465 if (x == op->x && y == op->y && op->map == m) flag = INS_BELOW_ORIGINATOR; 1465 if (x == op->x && y == op->y && op->map == m) flag = INS_BELOW_ORIGINATOR;
1466 1466
1467 if (small_nuggets) { 1467 if (small_nuggets) {
1468 tmp = get_object(); 1468 tmp = get_object();
1469 copy_object(small, tmp); 1469 copy_object(small, tmp);
1470 tmp-> nrof = small_nuggets; 1470 tmp-> nrof = small_nuggets;
1471 tmp->x = x; 1471 tmp->x = x;
1472 tmp->y = y; 1472 tmp->y = y;
1473 insert_ob_in_map(tmp, m, op, flag); 1473 insert_ob_in_map(tmp, m, op, flag);
1474 } 1474 }
1475 if (large_nuggets) { 1475 if (large_nuggets) {
1476 tmp = get_object(); 1476 tmp = get_object();
1477 copy_object(large, tmp); 1477 copy_object(large, tmp);
1478 tmp-> nrof = large_nuggets; 1478 tmp-> nrof = large_nuggets;
1479 tmp->x = x; 1479 tmp->x = x;
1480 tmp->y = y; 1480 tmp->y = y;
1481 insert_ob_in_map(tmp, m, op, flag); 1481 insert_ob_in_map(tmp, m, op, flag);
1482 } 1482 }
1483} 1483}
1484 1484
1485int alchemy(object *op, object *caster, object *spell_ob) 1485int alchemy(object *op, object *caster, object *spell_ob)
1486{ 1486{
1488 sint16 nx, ny; 1488 sint16 nx, ny;
1489 object *next,*tmp; 1489 object *next,*tmp;
1490 mapstruct *mp; 1490 mapstruct *mp;
1491 1491
1492 if(op->type!=PLAYER) 1492 if(op->type!=PLAYER)
1493 return 0; 1493 return 0;
1494 1494
1495 /* Put a maximum weight of items that can be alchemied. Limits the power 1495 /* Put a maximum weight of items that can be alchemied. Limits the power
1496 * some, and also prevents people from alcheming every table/chair/clock 1496 * some, and also prevents people from alcheming every table/chair/clock
1497 * in sight 1497 * in sight
1498 */ 1498 */
1500 weight_max *= 1000; 1500 weight_max *= 1000;
1501 small=get_archetype("smallnugget"), 1501 small=get_archetype("smallnugget"),
1502 large=get_archetype("largenugget"); 1502 large=get_archetype("largenugget");
1503 1503
1504 for(y= op->y-1;y<=op->y+1;y++) { 1504 for(y= op->y-1;y<=op->y+1;y++) {
1505 for(x= op->x-1;x<=op->x+1;x++) { 1505 for(x= op->x-1;x<=op->x+1;x++) {
1506 nx = x; 1506 nx = x;
1507 ny = y; 1507 ny = y;
1508 1508
1509 mp = op->map; 1509 mp = op->map;
1510 1510
1511 mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny); 1511 mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
1512 1512
1513 if(mflags & (P_OUT_OF_MAP | P_NO_MAGIC)) 1513 if(mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1514 continue; 1514 continue;
1515 1515
1516 /* Treat alchemy a little differently - most spell effects 1516 /* Treat alchemy a little differently - most spell effects
1517 * use fly as the movement type - for alchemy, consider it 1517 * use fly as the movement type - for alchemy, consider it
1518 * ground level effect. 1518 * ground level effect.
1519 */ 1519 */
1520 if (GET_MAP_MOVE_BLOCK(mp, nx, ny) & MOVE_WALK) 1520 if (GET_MAP_MOVE_BLOCK(mp, nx, ny) & MOVE_WALK)
1521 continue; 1521 continue;
1522 1522
1523 small_nuggets=0; 1523 small_nuggets=0;
1524 large_nuggets=0; 1524 large_nuggets=0;
1525 1525
1526 for(tmp=get_map_ob(mp,nx,ny);tmp!=NULL;tmp=next) { 1526 for(tmp=get_map_ob(mp,nx,ny);tmp!=NULL;tmp=next) {
1527 next=tmp->above; 1527 next=tmp->above;
1528 if (tmp->weight>0 && !QUERY_FLAG(tmp, FLAG_NO_PICK) &&
1529 !QUERY_FLAG(tmp, FLAG_ALIVE) &&
1530 !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
1531
1532 if (tmp->inv) {
1533 object *next1, *tmp1;
1534 for (tmp1 = tmp->inv; tmp1!=NULL; tmp1=next1) {
1535 next1 = tmp1->below;
1536 if (tmp1->weight>0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK) && 1528 if (tmp->weight>0 && !QUERY_FLAG(tmp, FLAG_NO_PICK) &&
1537 !QUERY_FLAG(tmp1, FLAG_ALIVE) && 1529 !QUERY_FLAG(tmp, FLAG_ALIVE) &&
1538 !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON)) 1530 !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
1539 alchemy_object(tmp1, &small_nuggets, &large_nuggets, 1531
1540 &weight); 1532 if (tmp->inv) {
1541 } 1533 object *next1, *tmp1;
1542 } 1534 for (tmp1 = tmp->inv; tmp1!=NULL; tmp1=next1) {
1535 next1 = tmp1->below;
1536 if (tmp1->weight>0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK) &&
1537 !QUERY_FLAG(tmp1, FLAG_ALIVE) &&
1538 !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
1539 alchemy_object(tmp1, &small_nuggets, &large_nuggets,
1540 &weight);
1541 }
1542 }
1543 alchemy_object(tmp, &small_nuggets, &large_nuggets, &weight); 1543 alchemy_object(tmp, &small_nuggets, &large_nuggets, &weight);
1544 1544
1545 if (weight>weight_max) { 1545 if (weight>weight_max) {
1546 update_map(op, mp, small_nuggets, large_nuggets, nx, ny); 1546 update_map(op, mp, small_nuggets, large_nuggets, nx, ny);
1547 free_object(large); 1547 free_object(large);
1548 free_object(small); 1548 free_object(small);
1549 return 1; 1549 return 1;
1550 } 1550 }
1551 } /* is alchemable object */ 1551 } /* is alchemable object */
1552 } /* process all objects on this space */ 1552 } /* process all objects on this space */
1553 1553
1554 /* Insert all the nuggets at one time. This probably saves time, but 1554 /* Insert all the nuggets at one time. This probably saves time, but
1555 * it also prevents us from alcheming nuggets that were just created 1555 * it also prevents us from alcheming nuggets that were just created
1556 * with this spell. 1556 * with this spell.
1557 */ 1557 */
1558 update_map(op, mp, small_nuggets, large_nuggets, nx, ny); 1558 update_map(op, mp, small_nuggets, large_nuggets, nx, ny);
1559 } 1559 }
1560 } 1560 }
1561 free_object(large); 1561 free_object(large);
1562 free_object(small); 1562 free_object(small);
1563 /* reset this so that if player standing on a big pile of stuff, 1563 /* reset this so that if player standing on a big pile of stuff,
1564 * it is redrawn properly. 1564 * it is redrawn properly.
1574int remove_curse(object *op, object *caster, object *spell) { 1574int remove_curse(object *op, object *caster, object *spell) {
1575 object *tmp; 1575 object *tmp;
1576 int success = 0, was_one = 0; 1576 int success = 0, was_one = 0;
1577 1577
1578 for (tmp = op->inv; tmp; tmp = tmp->below) 1578 for (tmp = op->inv; tmp; tmp = tmp->below)
1579 if (QUERY_FLAG(tmp, FLAG_APPLIED) && 1579 if (QUERY_FLAG(tmp, FLAG_APPLIED) &&
1580 ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED)) || 1580 ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED)) ||
1581 (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) { 1581 (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
1582 1582
1583 was_one++; 1583 was_one++;
1584 if (tmp->level <= caster_level(caster, spell)) { 1584 if (tmp->level <= caster_level(caster, spell)) {
1585 success++; 1585 success++;
1586 if (QUERY_FLAG(spell, FLAG_DAMNED)) 1586 if (QUERY_FLAG(spell, FLAG_DAMNED))
1587 CLEAR_FLAG(tmp, FLAG_DAMNED); 1587 CLEAR_FLAG(tmp, FLAG_DAMNED);
1588 1588
1589 CLEAR_FLAG(tmp, FLAG_CURSED); 1589 CLEAR_FLAG(tmp, FLAG_CURSED);
1590 CLEAR_FLAG(tmp, FLAG_KNOWN_CURSED); 1590 CLEAR_FLAG(tmp, FLAG_KNOWN_CURSED);
1591 tmp->value = 0; /* Still can't sell it */ 1591 tmp->value = 0; /* Still can't sell it */
1592 if (op->type == PLAYER) 1592 if (op->type == PLAYER)
1593 esrv_send_item(op, tmp); 1593 esrv_send_item(op, tmp);
1594 } 1594 }
1595 } 1595 }
1596 1596
1597 if (op->type==PLAYER) { 1597 if (op->type==PLAYER) {
1598 if (success) { 1598 if (success) {
1599 new_draw_info(NDI_UNIQUE, 0,op, "You feel like some of your items are looser now."); 1599 new_draw_info(NDI_UNIQUE, 0,op, "You feel like some of your items are looser now.");
1600 } else { 1600 } else {
1601 if (was_one) 1601 if (was_one)
1602 new_draw_info(NDI_UNIQUE, 0,op, "You failed to remove the curse."); 1602 new_draw_info(NDI_UNIQUE, 0,op, "You failed to remove the curse.");
1603 else 1603 else
1604 new_draw_info(NDI_UNIQUE, 0,op, "You are not using any cursed items."); 1604 new_draw_info(NDI_UNIQUE, 0,op, "You are not using any cursed items.");
1605 } 1605 }
1606 } 1606 }
1607 return success; 1607 return success;
1608} 1608}
1609 1609
1610/* Identifies objects in the players inventory/on the ground */ 1610/* Identifies objects in the players inventory/on the ground */
1617 1617
1618 if (num_ident < 1) num_ident=1; 1618 if (num_ident < 1) num_ident=1;
1619 1619
1620 1620
1621 for (tmp = op->inv; tmp ; tmp = tmp->below) { 1621 for (tmp = op->inv; tmp ; tmp = tmp->below) {
1622 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) { 1622 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) {
1623 identify(tmp); 1623 identify(tmp);
1624 if (op->type==PLAYER) { 1624 if (op->type==PLAYER) {
1625 new_draw_info_format(NDI_UNIQUE, 0, op, 1625 new_draw_info_format(NDI_UNIQUE, 0, op,
1626 "You have %s.", long_desc(tmp, op)); 1626 "You have %s.", long_desc(tmp, op));
1627 if (tmp->msg) { 1627 if (tmp->msg) {
1628 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:"); 1628 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:");
1629 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg); 1629 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg);
1630 } 1630 }
1631 } 1631 }
1632 num_ident--; 1632 num_ident--;
1633 success=1; 1633 success=1;
1634 if (!num_ident) break; 1634 if (!num_ident) break;
1635 } 1635 }
1636 } 1636 }
1637 /* If all the power of the spell has been used up, don't go and identify 1637 /* If all the power of the spell has been used up, don't go and identify
1638 * stuff on the floor. Only identify stuff on the floor if the spell 1638 * stuff on the floor. Only identify stuff on the floor if the spell
1639 * was not fully used. 1639 * was not fully used.
1640 */ 1640 */
1641 if (num_ident) { 1641 if (num_ident) {
1642 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) 1642 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above)
1643 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && 1643 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible &&
1644 need_identify(tmp)) { 1644 need_identify(tmp)) {
1645 1645
1646 identify(tmp); 1646 identify(tmp);
1647 if (op->type==PLAYER) { 1647 if (op->type==PLAYER) {
1648 new_draw_info_format(NDI_UNIQUE, 0,op, 1648 new_draw_info_format(NDI_UNIQUE, 0,op,
1649 "On the ground is %s.", long_desc(tmp, op)); 1649 "On the ground is %s.", long_desc(tmp, op));
1650 if (tmp->msg) { 1650 if (tmp->msg) {
1651 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:"); 1651 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:");
1652 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg); 1652 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg);
1653 } 1653 }
1654 esrv_send_item(op, tmp); 1654 esrv_send_item(op, tmp);
1655 } 1655 }
1656 num_ident--; 1656 num_ident--;
1657 success=1; 1657 success=1;
1658 if (!num_ident) break; 1658 if (!num_ident) break;
1659 } 1659 }
1660 } 1660 }
1661 if (!success) 1661 if (!success)
1662 new_draw_info(NDI_UNIQUE, 0,op, "You can't reach anything unidentified."); 1662 new_draw_info(NDI_UNIQUE, 0,op, "You can't reach anything unidentified.");
1663 else { 1663 else {
1664 spell_effect(spell, op->x, op->y, op->map, op); 1664 spell_effect(spell, op->x, op->y, op->map, op);
1665 } 1665 }
1666 return success; 1666 return success;
1667} 1667}
1668 1668
1669 1669
1681 range = spell->range + SP_level_range_adjust(caster, spell); 1681 range = spell->range + SP_level_range_adjust(caster, spell);
1682 1682
1683 if (!skill) skill=caster; 1683 if (!skill) skill=caster;
1684 1684
1685 for (x = op->x - range; x <= op->x + range; x++) 1685 for (x = op->x - range; x <= op->x + range; x++)
1686 for (y = op->y - range; y <= op->y + range; y++) { 1686 for (y = op->y - range; y <= op->y + range; y++) {
1687 1687
1688 m = op->map; 1688 m = op->map;
1689 mflags = get_map_flags(m, &m, x, y, &nx, &ny); 1689 mflags = get_map_flags(m, &m, x, y, &nx, &ny);
1690 if (mflags & P_OUT_OF_MAP) continue; 1690 if (mflags & P_OUT_OF_MAP) continue;
1691 1691
1692 /* For most of the detections, we only detect objects above the 1692 /* For most of the detections, we only detect objects above the
1693 * floor. But this is not true for show invisible. 1693 * floor. But this is not true for show invisible.
1694 * Basically, we just go and find the top object and work 1694 * Basically, we just go and find the top object and work
1695 * down - that is easier than working up. 1695 * down - that is easier than working up.
1696 */ 1696 */
1697 1697
1698 for (last=NULL, tmp=get_map_ob(m, nx, ny); tmp; tmp=tmp->above) last=tmp; 1698 for (last=NULL, tmp=get_map_ob(m, nx, ny); tmp; tmp=tmp->above) last=tmp;
1699 /* Shouldn't happen, but if there are no objects on a space, this 1699 /* Shouldn't happen, but if there are no objects on a space, this
1700 * would happen. 1700 * would happen.
1701 */ 1701 */
1702 if (!last) continue; 1702 if (!last) continue;
1703 1703
1704 done_one=0; 1704 done_one=0;
1705 floor=0; 1705 floor=0;
1706 detect = NULL; 1706 detect = NULL;
1707 for (tmp=last; tmp; tmp=tmp->below) { 1707 for (tmp=last; tmp; tmp=tmp->below) {
1708 1708
1709 /* show invisible */ 1709 /* show invisible */
1710 if (QUERY_FLAG(spell, FLAG_MAKE_INVIS) && 1710 if (QUERY_FLAG(spell, FLAG_MAKE_INVIS) &&
1711 /* Might there be other objects that we can make visibile? */ 1711 /* Might there be other objects that we can make visibile? */
1712 (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || 1712 (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
1713 (tmp->type==PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) || 1713 (tmp->type==PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
1714 tmp->type==CF_HANDLE || 1714 tmp->type==CF_HANDLE ||
1715 tmp->type==TRAPDOOR || tmp->type==EXIT || tmp->type==HOLE || 1715 tmp->type==TRAPDOOR || tmp->type==EXIT || tmp->type==HOLE ||
1716 tmp->type==BUTTON || tmp->type==TELEPORTER || 1716 tmp->type==BUTTON || tmp->type==TELEPORTER ||
1717 tmp->type==GATE || tmp->type==LOCKED_DOOR || 1717 tmp->type==GATE || tmp->type==LOCKED_DOOR ||
1718 tmp->type==WEAPON || tmp->type==ALTAR || tmp->type==SIGN || 1718 tmp->type==WEAPON || tmp->type==ALTAR || tmp->type==SIGN ||
1719 tmp->type==TRIGGER_PEDESTAL || tmp->type==SPECIAL_KEY || 1719 tmp->type==TRIGGER_PEDESTAL || tmp->type==SPECIAL_KEY ||
1720 tmp->type==TREASURE || tmp->type==BOOK || 1720 tmp->type==TREASURE || tmp->type==BOOK ||
1721 tmp->type==HOLY_ALTAR))) { 1721 tmp->type==HOLY_ALTAR))) {
1722 if(random_roll(0, skill->level-1, op, PREFER_HIGH) > level/4) { 1722 if(random_roll(0, skill->level-1, op, PREFER_HIGH) > level/4) {
1723 tmp->invisible=0; 1723 tmp->invisible=0;
1724 done_one = 1; 1724 done_one = 1;
1725 } 1725 }
1726 } 1726 }
1727 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) floor=1; 1727 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) floor=1;
1728 1728
1729 /* All detections below this point don't descend beneath the floor, 1729 /* All detections below this point don't descend beneath the floor,
1730 * so just continue on. We could be clever and look at the type of 1730 * so just continue on. We could be clever and look at the type of
1731 * detection to completely break out if we don't care about objects beneath 1731 * detection to completely break out if we don't care about objects beneath
1732 * the floor, but once we get to the floor, not likely a very big issue anyways. 1732 * the floor, but once we get to the floor, not likely a very big issue anyways.
1733 */ 1733 */
1734 if (floor) continue; 1734 if (floor) continue;
1735 1735
1736 /* I had thought about making detect magic and detect curse 1736 /* I had thought about making detect magic and detect curse
1737 * show the flash the magic item like it does for detect monster. 1737 * show the flash the magic item like it does for detect monster.
1738 * however, if the object is within sight, this would then make it 1738 * however, if the object is within sight, this would then make it
1739 * difficult to see what object is magical/cursed, so the 1739 * difficult to see what object is magical/cursed, so the
1740 * effect wouldn't be as apparant. 1740 * effect wouldn't be as apparant.
1741 */ 1741 */
1742 1742
1743 /* detect magic */ 1743 /* detect magic */
1744 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) && 1744 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) &&
1745 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) && 1745 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) &&
1746 !QUERY_FLAG(tmp, FLAG_IDENTIFIED) && 1746 !QUERY_FLAG(tmp, FLAG_IDENTIFIED) &&
1747 is_magical(tmp)) { 1747 is_magical(tmp)) {
1748 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 1748 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL);
1749 /* make runes more visibile */ 1749 /* make runes more visibile */
1750 if(tmp->type==RUNE && tmp->attacktype&AT_MAGIC) 1750 if(tmp->type==RUNE && tmp->attacktype&AT_MAGIC)
1751 tmp->stats.Cha/=4; 1751 tmp->stats.Cha/=4;
1752 done_one = 1; 1752 done_one = 1;
1753 } 1753 }
1754 /* detect monster */ 1754 /* detect monster */
1755 if (QUERY_FLAG(spell, FLAG_MONSTER) && 1755 if (QUERY_FLAG(spell, FLAG_MONSTER) &&
1756 (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) { 1756 (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) {
1757 done_one = 2; 1757 done_one = 2;
1758 if (!detect) detect=tmp; 1758 if (!detect) detect=tmp;
1759 } 1759 }
1760 /* Basically, if race is set in the spell, then the creatures race must 1760 /* Basically, if race is set in the spell, then the creatures race must
1761 * match that. if the spell race is set to GOD, then the gods opposing 1761 * match that. if the spell race is set to GOD, then the gods opposing
1762 * race must match. 1762 * race must match.
1763 */ 1763 */
1764 if (spell->race && QUERY_FLAG(tmp,FLAG_MONSTER) && tmp->race && 1764 if (spell->race && QUERY_FLAG(tmp,FLAG_MONSTER) && tmp->race &&
1765 ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying,tmp->race)) || 1765 ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying,tmp->race)) ||
1766 (strstr(spell->race, tmp->race)))) { 1766 (strstr(spell->race, tmp->race)))) {
1767 done_one = 2; 1767 done_one = 2;
1768 if (!detect) detect=tmp; 1768 if (!detect) detect=tmp;
1769 } 1769 }
1770 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && 1770 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) &&
1771 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) { 1771 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
1772 SET_FLAG(tmp, FLAG_KNOWN_CURSED); 1772 SET_FLAG(tmp, FLAG_KNOWN_CURSED);
1773 done_one = 1; 1773 done_one = 1;
1774 } 1774 }
1775 } /* for stack of objects on this space */ 1775 } /* for stack of objects on this space */
1776 1776
1777 /* Code here puts an effect of the spell on the space, so you can see 1777 /* Code here puts an effect of the spell on the space, so you can see
1778 * where the magic is. 1778 * where the magic is.
1779 */ 1779 */
1780 if (done_one) { 1780 if (done_one) {
1781 object *detect_ob = arch_to_object(spell->other_arch); 1781 object *detect_ob = arch_to_object(spell->other_arch);
1782 detect_ob->x = nx; 1782 detect_ob->x = nx;
1783 detect_ob->y = ny; 1783 detect_ob->y = ny;
1784 /* if this is set, we want to copy the face */ 1784 /* if this is set, we want to copy the face */
1785 if (done_one == 2 && detect) { 1785 if (done_one == 2 && detect) {
1786 detect_ob->face = detect->face; 1786 detect_ob->face = detect->face;
1787 detect_ob->animation_id = detect->animation_id; 1787 detect_ob->animation_id = detect->animation_id;
1788 detect_ob->anim_speed = detect->anim_speed; 1788 detect_ob->anim_speed = detect->anim_speed;
1789 detect_ob->last_anim=0; 1789 detect_ob->last_anim=0;
1790 /* by default, the detect_ob is already animated */ 1790 /* by default, the detect_ob is already animated */
1791 if (!QUERY_FLAG(detect, FLAG_ANIMATE)) CLEAR_FLAG(detect_ob, FLAG_ANIMATE); 1791 if (!QUERY_FLAG(detect, FLAG_ANIMATE)) CLEAR_FLAG(detect_ob, FLAG_ANIMATE);
1792 } 1792 }
1793 insert_ob_in_map(detect_ob, m, op,0); 1793 insert_ob_in_map(detect_ob, m, op,0);
1794 } 1794 }
1795 } /* for processing the surrounding spaces */ 1795 } /* for processing the surrounding spaces */
1796 1796
1797 1797
1798 /* Now process objects in the players inventory if detect curse or magic */ 1798 /* Now process objects in the players inventory if detect curse or magic */
1799 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) { 1799 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
1800 done_one = 0; 1800 done_one = 0;
1801 for (tmp = op->inv; tmp; tmp = tmp->below) { 1801 for (tmp = op->inv; tmp; tmp = tmp->below) {
1802 if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) { 1802 if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
1803 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) && 1803 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) &&
1804 is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) { 1804 is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) {
1805 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 1805 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL);
1806 if (op->type==PLAYER) 1806 if (op->type==PLAYER)
1807 esrv_send_item (op, tmp); 1807 esrv_send_item (op, tmp);
1808 } 1808 }
1809 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && 1809 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) &&
1810 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) { 1810 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
1811 SET_FLAG(tmp, FLAG_KNOWN_CURSED); 1811 SET_FLAG(tmp, FLAG_KNOWN_CURSED);
1812 if (op->type==PLAYER) 1812 if (op->type==PLAYER)
1813 esrv_send_item (op, tmp); 1813 esrv_send_item (op, tmp);
1814 } 1814 }
1815 } /* if item is not identified */ 1815 } /* if item is not identified */
1816 } /* for the players inventory */ 1816 } /* for the players inventory */
1817 } /* if detect magic/curse and object is a player */ 1817 } /* if detect magic/curse and object is a player */
1818 return 1; 1818 return 1;
1819} 1819}
1820 1820
1821 1821
1879 y = op->y+freearr_y[dir]; 1879 y = op->y+freearr_y[dir];
1880 1880
1881 mflags = get_map_flags(m, &m, x, y, &x, &y); 1881 mflags = get_map_flags(m, &m, x, y, &x, &y);
1882 1882
1883 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) { 1883 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) {
1884 for(plyr=get_map_ob(m, x, y); plyr!=NULL; plyr=plyr->above) 1884 for(plyr=get_map_ob(m, x, y); plyr!=NULL; plyr=plyr->above)
1885 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE)) 1885 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
1886 break; 1886 break;
1887 } 1887 }
1888 1888
1889 1889
1890 /* If we did not find a player in the specified direction, transfer 1890 /* If we did not find a player in the specified direction, transfer
1891 * to anyone on top of us. This is used for the rune of transference mostly. 1891 * to anyone on top of us. This is used for the rune of transference mostly.
1892 */ 1892 */
1893 if(plyr==NULL) 1893 if(plyr==NULL)
1894 for(plyr=get_map_ob(op->map,op->x,op->y); plyr!=NULL; plyr=plyr->above) 1894 for(plyr=get_map_ob(op->map,op->x,op->y); plyr!=NULL; plyr=plyr->above)
1895 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE)) 1895 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
1896 break; 1896 break;
1897 1897
1898 if (!plyr) { 1898 if (!plyr) {
1899 new_draw_info(NDI_BLACK, 0, op, "There is no one there."); 1899 new_draw_info(NDI_BLACK, 0, op, "There is no one there.");
1900 return 0; 1900 return 0;
1901 } 1901 }
1902 /* give sp */ 1902 /* give sp */
1903 if(spell->stats.dam > 0) { 1903 if(spell->stats.dam > 0) {
1904 plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust(caster, spell); 1904 plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust(caster, spell);
1905 charge_mana_effect(plyr, caster_level(caster, spell)); 1905 charge_mana_effect(plyr, caster_level(caster, spell));
1906 return 1; 1906 return 1;
1907 } 1907 }
1908 /* suck sp away. Can't suck sp from yourself */ 1908 /* suck sp away. Can't suck sp from yourself */
1909 else if (op != plyr) { 1909 else if (op != plyr) {
1910 /* old dragin magic used floats. easier to just use ints and divide by 100 */ 1910 /* old dragin magic used floats. easier to just use ints and divide by 100 */
1911 1911
1912 int rate = -spell->stats.dam + SP_level_dam_adjust(caster, spell), sucked; 1912 int rate = -spell->stats.dam + SP_level_dam_adjust(caster, spell), sucked;
1913 1913
1914 if (rate > 95) rate=95; 1914 if (rate > 95) rate=95;
1915 1915
1916 sucked = (plyr->stats.sp * rate) / 100; 1916 sucked = (plyr->stats.sp * rate) / 100;
1917 plyr->stats.sp -= sucked; 1917 plyr->stats.sp -= sucked;
1918 if (QUERY_FLAG(op, FLAG_ALIVE)) { 1918 if (QUERY_FLAG(op, FLAG_ALIVE)) {
1919 /* Player doesn't get full credit */ 1919 /* Player doesn't get full credit */
1920 sucked = (sucked * rate) / 100; 1920 sucked = (sucked * rate) / 100;
1921 op->stats.sp += sucked; 1921 op->stats.sp += sucked;
1922 if (sucked > 0) { 1922 if (sucked > 0) {
1923 charge_mana_effect(op, caster_level(caster, spell)); 1923 charge_mana_effect(op, caster_level(caster, spell));
1924 } 1924 }
1925 } 1925 }
1926 return 1; 1926 return 1;
1927 } 1927 }
1928 return 0; 1928 return 0;
1929} 1929}
1930 1930
1931 1931
1947 m = op->map; 1947 m = op->map;
1948 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy); 1948 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
1949 if (mflags & P_OUT_OF_MAP) return; 1949 if (mflags & P_OUT_OF_MAP) return;
1950 1950
1951 for(tmp=get_map_ob(m,sx,sy); tmp!=NULL; tmp=next) { 1951 for(tmp=get_map_ob(m,sx,sy); tmp!=NULL; tmp=next) {
1952 next = tmp->above; 1952 next = tmp->above;
1953 1953
1954 /* Need to look at the head object - otherwise, if tmp 1954 /* Need to look at the head object - otherwise, if tmp
1955 * points to a monster, we don't have all the necessary 1955 * points to a monster, we don't have all the necessary
1956 * info for it. 1956 * info for it.
1957 */ 1957 */
1958 if (tmp->head) head = tmp->head; 1958 if (tmp->head) head = tmp->head;
1959 else head = tmp; 1959 else head = tmp;
1960 1960
1961 /* don't attack our own spells */ 1961 /* don't attack our own spells */
1962 if(tmp->owner && tmp->owner == op->owner) continue; 1962 if(tmp->owner && tmp->owner == op->owner) continue;
1963 1963
1964 /* Basically, if the object is magical and not counterspell, 1964 /* Basically, if the object is magical and not counterspell,
1965 * we will more or less remove the object. Don't counterspell 1965 * we will more or less remove the object. Don't counterspell
1966 * monsters either. 1966 * monsters either.
1967 */ 1967 */
1968 1968
1969 if (head->attacktype & AT_MAGIC && 1969 if (head->attacktype & AT_MAGIC &&
1970 !(head->attacktype & AT_COUNTERSPELL) && 1970 !(head->attacktype & AT_COUNTERSPELL) &&
1971 !QUERY_FLAG(head,FLAG_MONSTER) && 1971 !QUERY_FLAG(head,FLAG_MONSTER) &&
1972 (op->level > head->level)) { 1972 (op->level > head->level)) {
1973 remove_ob(head); 1973 remove_ob(head);
1974 free_object(head); 1974 free_object(head);
1975 } else switch(head->type) { 1975 } else switch(head->type) {
1976 case SPELL_EFFECT: 1976 case SPELL_EFFECT:
1977 if(op->level > head->level) { 1977 if(op->level > head->level) {
1978 remove_ob(head); 1978 remove_ob(head);
1979 free_object(head); 1979 free_object(head);
1980 } 1980 }
1981 break; 1981 break;
1982 1982
1983 /* I really don't get this rune code that much - that 1983 /* I really don't get this rune code that much - that
1984 * random chance seems really low. 1984 * random chance seems really low.
1985 */ 1985 */
1986 case RUNE: 1986 case RUNE:
1987 if(rndm(0, 149) == 0) { 1987 if(rndm(0, 149) == 0) {
1988 head->stats.hp--; /* weaken the rune */ 1988 head->stats.hp--; /* weaken the rune */
1989 if(!head->stats.hp) { 1989 if(!head->stats.hp) {
1990 remove_ob(head); 1990 remove_ob(head);
1991 free_object(head); 1991 free_object(head);
1992 } 1992 }
1993 } 1993 }
1994 break; 1994 break;
1995 } 1995 }
1996 } 1996 }
1997} 1997}
1998 1998
1999 1999
2000 2000
2003 char buf[MAX_BUF]; 2003 char buf[MAX_BUF];
2004 2004
2005 object *tmp, *god=find_god(determine_god(op)); 2005 object *tmp, *god=find_god(determine_god(op));
2006 2006
2007 if(!god) { 2007 if(!god) {
2008 new_draw_info(NDI_UNIQUE, 0,op, 2008 new_draw_info(NDI_UNIQUE, 0,op,
2009 "You can't consecrate anything if you don't worship a god!"); 2009 "You can't consecrate anything if you don't worship a god!");
2010 return 0; 2010 return 0;
2011 } 2011 }
2012 2012
2013 for(tmp=op->below;tmp;tmp=tmp->below) { 2013 for(tmp=op->below;tmp;tmp=tmp->below) {
2014 if(QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break; 2014 if(QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break;
2015 if(tmp->type==HOLY_ALTAR) { 2015 if(tmp->type==HOLY_ALTAR) {
2016 2016
2017 if(tmp->level > caster_level(caster, spell)) { 2017 if(tmp->level > caster_level(caster, spell)) {
2018 new_draw_info_format(NDI_UNIQUE, 0,op, 2018 new_draw_info_format(NDI_UNIQUE, 0,op,
2019 "You are not powerful enough to reconsecrate the %s", tmp->name); 2019 "You are not powerful enough to reconsecrate the %s", tmp->name);
2020 return 0; 2020 return 0;
2021 } else { 2021 } else {
2022 /* If we got here, we are consecrating an altar */ 2022 /* If we got here, we are consecrating an altar */
2023 if(tmp->name) free_string(tmp->name); 2023 if(tmp->name) free_string(tmp->name);
2024 sprintf(buf,"Altar of %s",god->name); 2024 sprintf(buf,"Altar of %s",god->name);
2025 tmp->name = add_string(buf); 2025 tmp->name = add_string(buf);
2026 tmp->level = caster_level(caster, spell); 2026 tmp->level = caster_level(caster, spell);
2027 tmp->other_arch = god->arch; 2027 tmp->other_arch = god->arch;
2028 if(op->type==PLAYER) esrv_update_item(UPD_NAME, op, tmp); 2028 if(op->type==PLAYER) esrv_update_item(UPD_NAME, op, tmp);
2029 new_draw_info_format(NDI_UNIQUE,0, op, 2029 new_draw_info_format(NDI_UNIQUE,0, op,
2030 "You consecrated the altar to %s!",god->name); 2030 "You consecrated the altar to %s!",god->name);
2031 return 1; 2031 return 1;
2032 } 2032 }
2033 } 2033 }
2034 } 2034 }
2035 new_draw_info(NDI_UNIQUE, 0,op,"You are not standing over an altar!"); 2035 new_draw_info(NDI_UNIQUE, 0,op,"You are not standing over an altar!");
2036 return 0; 2036 return 0;
2037} 2037}
2038 2038
2054 sint16 x, y; 2054 sint16 x, y;
2055 mapstruct *m; 2055 mapstruct *m;
2056 materialtype_t *mt; 2056 materialtype_t *mt;
2057 2057
2058 if(!spell->other_arch){ 2058 if(!spell->other_arch){
2059 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 2059 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
2060 LOG(llevError,"animate_weapon failed: spell %s missing other_arch!\n", spell->name); 2060 LOG(llevError,"animate_weapon failed: spell %s missing other_arch!\n", spell->name);
2061 return 0; 2061 return 0;
2062 } 2062 }
2063 /* exit if it's not a player using this spell. */ 2063 /* exit if it's not a player using this spell. */
2064 if(op->type!=PLAYER) return 0; 2064 if(op->type!=PLAYER) return 0;
2065 2065
2066 /* if player already has a golem, abort */ 2066 /* if player already has a golem, abort */
2067 if(op->contr->ranges[range_golem]!=NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) { 2067 if(op->contr->ranges[range_golem]!=NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
2068 control_golem(op->contr->ranges[range_golem],dir); 2068 control_golem(op->contr->ranges[range_golem],dir);
2069 return 0; 2069 return 0;
2070 } 2070 }
2071 2071
2072 /* if no direction specified, pick one */ 2072 /* if no direction specified, pick one */
2073 if(!dir) 2073 if(!dir)
2074 dir=find_free_spot(NULL,op->map,op->x,op->y,1,9); 2074 dir=find_free_spot(NULL,op->map,op->x,op->y,1,9);
2075 2075
2076 m = op->map; 2076 m = op->map;
2077 x = op->x+freearr_x[dir]; 2077 x = op->x+freearr_x[dir];
2078 y = op->y+freearr_y[dir]; 2078 y = op->y+freearr_y[dir];
2079 2079
2080 /* if there's no place to put the golem, abort */ 2080 /* if there's no place to put the golem, abort */
2081 if((dir==-1) || (get_map_flags(m, &m, x, y, &x, &y) & P_OUT_OF_MAP) || 2081 if((dir==-1) || (get_map_flags(m, &m, x, y, &x, &y) & P_OUT_OF_MAP) ||
2082 ((spell->other_arch->clone.move_type & GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) { 2082 ((spell->other_arch->clone.move_type & GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
2083 new_draw_info(NDI_UNIQUE, 0,op,"There is something in the way."); 2083 new_draw_info(NDI_UNIQUE, 0,op,"There is something in the way.");
2084 return 0; 2084 return 0;
2085 } 2085 }
2086 2086
2087 /* Use the weapon marked by the player. */ 2087 /* Use the weapon marked by the player. */
2088 weapon = find_marked_object(op); 2088 weapon = find_marked_object(op);
2089 2089
2090 if (!weapon) { 2090 if (!weapon) {
2091 new_draw_info(NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2091 new_draw_info(NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!");
2092 return 0; 2092 return 0;
2093 } 2093 }
2094 if (spell->race && strcmp(weapon->arch->name, spell->race)) { 2094 if (spell->race && strcmp(weapon->arch->name, spell->race)) {
2095 new_draw_info(NDI_UNIQUE, 0,op,"The spell fails to transform your weapon."); 2095 new_draw_info(NDI_UNIQUE, 0,op,"The spell fails to transform your weapon.");
2096 return 0; 2096 return 0;
2097 } 2097 }
2098 if (weapon->type != WEAPON) { 2098 if (weapon->type != WEAPON) {
2099 new_draw_info(NDI_UNIQUE, 0,op,"You need to wield a weapon to animate it."); 2099 new_draw_info(NDI_UNIQUE, 0,op,"You need to wield a weapon to animate it.");
2100 return 0; 2100 return 0;
2101 } 2101 }
2102 if (QUERY_FLAG(weapon, FLAG_APPLIED)) { 2102 if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
2103 new_draw_info_format(NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", 2103 new_draw_info_format(NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell",
2104 query_name(weapon)); 2104 query_name(weapon));
2105 return 0; 2105 return 0;
2106 } 2106 }
2107 2107
2108 if (weapon->nrof > 1) { 2108 if (weapon->nrof > 1) {
2109 tmp = get_split_ob(weapon, 1); 2109 tmp = get_split_ob(weapon, 1);
2110 esrv_send_item(op, weapon); 2110 esrv_send_item(op, weapon);
2111 weapon = tmp; 2111 weapon = tmp;
2112 } 2112 }
2113 2113
2114 /* create the golem object */ 2114 /* create the golem object */
2115 tmp=arch_to_object(spell->other_arch); 2115 tmp=arch_to_object(spell->other_arch);
2116 2116
2129 /* Give the weapon to the golem now. A bit of a hack to check the 2129 /* Give the weapon to the golem now. A bit of a hack to check the
2130 * removed flag - it should only be set if get_split_object was 2130 * removed flag - it should only be set if get_split_object was
2131 * used above. 2131 * used above.
2132 */ 2132 */
2133 if (!QUERY_FLAG(weapon, FLAG_REMOVED)) 2133 if (!QUERY_FLAG(weapon, FLAG_REMOVED))
2134 remove_ob (weapon); 2134 remove_ob (weapon);
2135 insert_ob_in_ob (weapon, tmp); 2135 insert_ob_in_ob (weapon, tmp);
2136 esrv_send_item(op, weapon); 2136 esrv_send_item(op, weapon);
2137 /* To do everything necessary to let a golem use the weapon is a pain, 2137 /* To do everything necessary to let a golem use the weapon is a pain,
2138 * so instead, just set it as equipped (otherwise, we need to update 2138 * so instead, just set it as equipped (otherwise, we need to update
2139 * body_info, skills, etc) 2139 * body_info, skills, etc)
2147 * if you're using a crappy weapon, it shouldn't be as good. 2147 * if you're using a crappy weapon, it shouldn't be as good.
2148 */ 2148 */
2149 2149
2150 /* modify weapon's animated wc */ 2150 /* modify weapon's animated wc */
2151 tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust(caster,spell) 2151 tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust(caster,spell)
2152 - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic; 2152 - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic;
2153 if(tmp->stats.wc<-127) tmp->stats.wc = -127; 2153 if(tmp->stats.wc<-127) tmp->stats.wc = -127;
2154 2154
2155 /* Modify hit points for weapon */ 2155 /* Modify hit points for weapon */
2156 tmp->stats.maxhp = tmp->stats.maxhp + spell->duration + 2156 tmp->stats.maxhp = tmp->stats.maxhp + spell->duration +
2157 SP_level_duration_adjust(caster, spell) + 2157 SP_level_duration_adjust(caster, spell) +
2158 + 8 * weapon->magic + 12 * weapon->stats.Con; 2158 + 8 * weapon->magic + 12 * weapon->stats.Con;
2159 if(tmp->stats.maxhp<0) tmp->stats.maxhp=10; 2159 if(tmp->stats.maxhp<0) tmp->stats.maxhp=10;
2160 tmp->stats.hp = tmp->stats.maxhp; 2160 tmp->stats.hp = tmp->stats.maxhp;
2161 2161
2162 /* Modify weapon's damage */ 2162 /* Modify weapon's damage */
2163 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust(caster, spell) 2163 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust(caster, spell)
2164 + weapon->stats.dam 2164 + weapon->stats.dam
2165 + weapon->magic 2165 + weapon->magic
2166 + 5 * weapon->stats.Str; 2166 + 5 * weapon->stats.Str;
2167 if(tmp->stats.dam<0) tmp->stats.dam=127; 2167 if(tmp->stats.dam<0) tmp->stats.dam=127;
2168 2168
2169 2169
2170 /* attacktype */ 2170 /* attacktype */
2171 if ( ! tmp->attacktype) 2171 if ( ! tmp->attacktype)
2172 tmp->attacktype = AT_PHYSICAL; 2172 tmp->attacktype = AT_PHYSICAL;
2173 2173
2174 mt = NULL; 2174 mt = NULL;
2175 if (op->materialname != NULL) 2175 if (op->materialname != NULL)
2176 mt = name_to_material(op->materialname); 2176 mt = name_to_material(op->materialname);
2177 if (mt != NULL) { 2177 if (mt != NULL) {
2178 for (i=0; i < NROFATTACKS; i++) 2178 for (i=0; i < NROFATTACKS; i++)
2179 tmp->resist[i] = 50 - (mt->save[i] * 5); 2179 tmp->resist[i] = 50 - (mt->save[i] * 5);
2180 a = mt->save[0]; 2180 a = mt->save[0];
2181 } else { 2181 } else {
2182 for (i=0; i < NROFATTACKS; i++) 2182 for (i=0; i < NROFATTACKS; i++)
2183 tmp->resist[i] = 5; 2183 tmp->resist[i] = 5;
2184 a = 10; 2184 a = 10;
2185 } 2185 }
2186 /* Set weapon's immunity */ 2186 /* Set weapon's immunity */
2187 tmp->resist[ATNR_CONFUSION] = 100; 2187 tmp->resist[ATNR_CONFUSION] = 100;
2188 tmp->resist[ATNR_POISON] = 100; 2188 tmp->resist[ATNR_POISON] = 100;
2189 tmp->resist[ATNR_SLOW] = 100; 2189 tmp->resist[ATNR_SLOW] = 100;
2203 tmp->speed = 0.4 + 0.1 * SP_level_range_adjust(caster,spell); 2203 tmp->speed = 0.4 + 0.1 * SP_level_range_adjust(caster,spell);
2204 2204
2205 if(tmp->speed > 3.33) tmp->speed = 3.33; 2205 if(tmp->speed > 3.33) tmp->speed = 3.33;
2206 2206
2207 if (!spell->race) { 2207 if (!spell->race) {
2208 sprintf(buf, "animated %s", weapon->name); 2208 sprintf(buf, "animated %s", weapon->name);
2209 if(tmp->name) free_string(tmp->name); 2209 if(tmp->name) free_string(tmp->name);
2210 tmp->name = add_string(buf); 2210 tmp->name = add_string(buf);
2211 2211
2212 tmp->face = weapon->face; 2212 tmp->face = weapon->face;
2213 tmp->animation_id = weapon->animation_id; 2213 tmp->animation_id = weapon->animation_id;
2214 tmp->anim_speed = weapon->anim_speed; 2214 tmp->anim_speed = weapon->anim_speed;
2215 tmp->last_anim = weapon->last_anim; 2215 tmp->last_anim = weapon->last_anim;
2216 tmp->state = weapon->state; 2216 tmp->state = weapon->state;
2217 if(QUERY_FLAG(weapon, FLAG_ANIMATE)) { 2217 if(QUERY_FLAG(weapon, FLAG_ANIMATE)) {
2218 SET_FLAG(tmp,FLAG_ANIMATE); 2218 SET_FLAG(tmp,FLAG_ANIMATE);
2219 } else { 2219 } else {
2220 CLEAR_FLAG(tmp,FLAG_ANIMATE); 2220 CLEAR_FLAG(tmp,FLAG_ANIMATE);
2221 } 2221 }
2222 update_ob_speed(tmp); 2222 update_ob_speed(tmp);
2223 } 2223 }
2224 2224
2225 /* make experience increase in proportion to the strength of the summoned creature. */ 2225 /* make experience increase in proportion to the strength of the summoned creature. */
2226 tmp->stats.exp *= 1 + (MAX(spell->stats.maxgrace, spell->stats.sp) / caster_level(caster, spell)); 2226 tmp->stats.exp *= 1 + (MAX(spell->stats.maxgrace, spell->stats.sp) / caster_level(caster, spell));
2227 2227
2244 2244
2245 if(!op->map) return 0; /* shouldnt happen */ 2245 if(!op->map) return 0; /* shouldnt happen */
2246 2246
2247 success=change_map_light(op->map,spell->stats.dam); 2247 success=change_map_light(op->map,spell->stats.dam);
2248 if(!success) { 2248 if(!success) {
2249 if (spell->stats.dam < 0) 2249 if (spell->stats.dam < 0)
2250 new_draw_info(NDI_UNIQUE,0,op,"It can be no brighter here."); 2250 new_draw_info(NDI_UNIQUE,0,op,"It can be no brighter here.");
2251 else 2251 else
2252 new_draw_info(NDI_UNIQUE,0,op,"It can be no darker here."); 2252 new_draw_info(NDI_UNIQUE,0,op,"It can be no darker here.");
2253 } 2253 }
2254 return success; 2254 return success;
2255} 2255}
2256 2256
2257 2257
2281 set_spell_skill(op, caster, spell, new_aura); 2281 set_spell_skill(op, caster, spell, new_aura);
2282 new_aura->attacktype= spell->attacktype; 2282 new_aura->attacktype= spell->attacktype;
2283 2283
2284 new_aura->level = caster_level(caster, spell); 2284 new_aura->level = caster_level(caster, spell);
2285 if (refresh) 2285 if (refresh)
2286 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 2286 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
2287 else 2287 else
2288 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 2288 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
2289 insert_ob_in_ob(new_aura, op); 2289 insert_ob_in_ob(new_aura, op);
2290 return 1; 2290 return 1;
2291} 2291}
2292 2292
2293 2293
2294/* move aura function. An aura is a part of someone's inventory, 2294/* move aura function. An aura is a part of someone's inventory,
2313 */ 2313 */
2314 remove_ob(aura); 2314 remove_ob(aura);
2315 2315
2316 /* exit if we're out of gas */ 2316 /* exit if we're out of gas */
2317 if(aura->duration--< 0) { 2317 if(aura->duration--< 0) {
2318 free_object(aura); 2318 free_object(aura);
2319 return; 2319 return;
2320 } 2320 }
2321 2321
2322 /* auras only exist in inventories */ 2322 /* auras only exist in inventories */
2323 if(env == NULL || env->map==NULL) { 2323 if(env == NULL || env->map==NULL) {
2324 free_object(aura); 2324 free_object(aura);
2325 return; 2325 return;
2326 } 2326 }
2327 aura->x = env->x; 2327 aura->x = env->x;
2328 aura->y = env->y; 2328 aura->y = env->y;
2329 2329
2330 /* we need to jump out of the inventory for a bit 2330 /* we need to jump out of the inventory for a bit
2331 * in order to hit the map conveniently. 2331 * in order to hit the map conveniently.
2332 */ 2332 */
2333 insert_ob_in_map(aura,env->map,aura,0); 2333 insert_ob_in_map(aura,env->map,aura,0);
2334 2334
2335 for(i=1;i<9;i++) { 2335 for(i=1;i<9;i++) {
2336 sint16 nx, ny; 2336 sint16 nx, ny;
2337 nx = aura->x + freearr_x[i]; 2337 nx = aura->x + freearr_x[i];
2338 ny = aura->y + freearr_y[i]; 2338 ny = aura->y + freearr_y[i];
2339 mflags = get_map_flags(env->map, &m, nx, ny, &nx, &ny); 2339 mflags = get_map_flags(env->map, &m, nx, ny, &nx, &ny);
2340 2340
2341 /* Consider the movement tyep of the person with the aura as 2341 /* Consider the movement tyep of the person with the aura as
2342 * movement type of the aura. Eg, if the player is flying, the aura 2342 * movement type of the aura. Eg, if the player is flying, the aura
2343 * is flying also, if player is walking, it is on the ground, etc. 2343 * is flying also, if player is walking, it is on the ground, etc.
2344 */ 2344 */
2345 if (!(mflags & P_OUT_OF_MAP) && !(OB_TYPE_MOVE_BLOCK(env, GET_MAP_MOVE_BLOCK(m, nx, ny)))) { 2345 if (!(mflags & P_OUT_OF_MAP) && !(OB_TYPE_MOVE_BLOCK(env, GET_MAP_MOVE_BLOCK(m, nx, ny)))) {
2346 hit_map(aura,i,aura->attacktype,0); 2346 hit_map(aura,i,aura->attacktype,0);
2347 2347
2348 if(aura->other_arch) { 2348 if(aura->other_arch) {
2349 object *new_ob; 2349 object *new_ob;
2350 2350
2351 new_ob = arch_to_object(aura->other_arch); 2351 new_ob = arch_to_object(aura->other_arch);
2352 new_ob->x = nx; 2352 new_ob->x = nx;
2353 new_ob->y = ny; 2353 new_ob->y = ny;
2354 insert_ob_in_map(new_ob,m,aura,0); 2354 insert_ob_in_map(new_ob,m,aura,0);
2355 } 2355 }
2356 } 2356 }
2357 } 2357 }
2358 /* put the aura back in the player's inventory */ 2358 /* put the aura back in the player's inventory */
2359 remove_ob(aura); 2359 remove_ob(aura);
2360 insert_ob_in_ob(aura, env); 2360 insert_ob_in_ob(aura, env);
2361} 2361}
2366 2366
2367void move_peacemaker(object *op) { 2367void move_peacemaker(object *op) {
2368 object *tmp; 2368 object *tmp;
2369 2369
2370 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) { 2370 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) {
2371 int atk_lev, def_lev; 2371 int atk_lev, def_lev;
2372 object *victim=tmp; 2372 object *victim=tmp;
2373 2373
2374 if (tmp->head) victim=tmp->head; 2374 if (tmp->head) victim=tmp->head;
2375 if (!QUERY_FLAG(victim,FLAG_MONSTER)) continue; 2375 if (!QUERY_FLAG(victim,FLAG_MONSTER)) continue;
2376 if (QUERY_FLAG(victim,FLAG_UNAGGRESSIVE)) continue; 2376 if (QUERY_FLAG(victim,FLAG_UNAGGRESSIVE)) continue;
2377 if (victim->stats.exp == 0) continue; 2377 if (victim->stats.exp == 0) continue;
2378 2378
2379 def_lev = MAX(1,victim->level); 2379 def_lev = MAX(1,victim->level);
2380 atk_lev = MAX(1,op->level); 2380 atk_lev = MAX(1,op->level);
2381 2381
2382 if (rndm(0, atk_lev-1) > def_lev) { 2382 if (rndm(0, atk_lev-1) > def_lev) {
2383 /* make this sucker peaceful. */ 2383 /* make this sucker peaceful. */
2384 2384
2385 change_exp(get_owner(op),victim->stats.exp, op->skill, 0); 2385 change_exp(get_owner(op),victim->stats.exp, op->skill, 0);
2386 victim->stats.exp=0; 2386 victim->stats.exp=0;
2387#if 0 2387#if 0
2388 /* No idea why these were all set to zero - if something 2388 /* No idea why these were all set to zero - if something
2389 * makes this creature agressive, he should still do damage. 2389 * makes this creature agressive, he should still do damage.
2390 */ 2390 */
2391 victim->stats.dam = 0; 2391 victim->stats.dam = 0;
2392 victim->stats.sp = 0; 2392 victim->stats.sp = 0;
2393 victim->stats.grace = 0; 2393 victim->stats.grace = 0;
2394 victim->stats.Pow = 0; 2394 victim->stats.Pow = 0;
2395#endif 2395#endif
2396 victim->attack_movement = RANDO2; 2396 victim->attack_movement = RANDO2;
2397 SET_FLAG(victim,FLAG_UNAGGRESSIVE); 2397 SET_FLAG(victim,FLAG_UNAGGRESSIVE);
2398 SET_FLAG(victim,FLAG_RUN_AWAY); 2398 SET_FLAG(victim,FLAG_RUN_AWAY);
2399 SET_FLAG(victim,FLAG_RANDOM_MOVE); 2399 SET_FLAG(victim,FLAG_RANDOM_MOVE);
2400 CLEAR_FLAG(victim,FLAG_MONSTER); 2400 CLEAR_FLAG(victim,FLAG_MONSTER);
2401 if(victim->name) { 2401 if(victim->name) {
2402 new_draw_info_format(NDI_UNIQUE,0,op->owner,"%s no longer feels like fighting.",victim->name); 2402 new_draw_info_format(NDI_UNIQUE,0,op->owner,"%s no longer feels like fighting.",victim->name);
2403 } 2403 }
2404 } 2404 }
2405 } 2405 }
2406} 2406}
2407 2407
2408 2408
2409/* This writes a rune that contains the appropriate message. 2409/* This writes a rune that contains the appropriate message.
2413int write_mark(object *op, object *spell, const char *msg) { 2413int write_mark(object *op, object *spell, const char *msg) {
2414 char rune[HUGE_BUF]; 2414 char rune[HUGE_BUF];
2415 object *tmp; 2415 object *tmp;
2416 2416
2417 if (!msg || msg[0] == 0) { 2417 if (!msg || msg[0] == 0) {
2418 new_draw_info(NDI_UNIQUE, 0, op, "Write what?"); 2418 new_draw_info(NDI_UNIQUE, 0, op, "Write what?");
2419 return 0; 2419 return 0;
2420 } 2420 }
2421 2421
2422 if (strcasestr_local(msg, "endmsg")) { 2422 if (strcasestr_local(msg, "endmsg")) {
2423 new_draw_info(NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2423 new_draw_info(NDI_UNIQUE, 0, op, "Trying to cheat are we?");
2424 LOG(llevInfo,"write_rune: player %s tried to write bogus rune %s\n", op->name, msg); 2424 LOG(llevInfo,"write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
2425 return 0; 2425 return 0;
2426 } 2426 }
2427 if (!spell->other_arch) return 0; 2427 if (!spell->other_arch) return 0;
2428 tmp = arch_to_object(spell->other_arch); 2428 tmp = arch_to_object(spell->other_arch);
2429 strncpy(rune, msg, HUGE_BUF-2); 2429 strncpy(rune, msg, HUGE_BUF-2);
2430 rune[HUGE_BUF-2] = 0; 2430 rune[HUGE_BUF-2] = 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines