ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_attack.C
(Generate patch)

Comparing deliantra/server/server/spell_attack.C (file contents):
Revision 1.66 by root, Mon Sep 29 10:31:32 2008 UTC vs.
Revision 1.74 by root, Sun Dec 28 07:48:44 2008 UTC

351 maptile *m = op->map; 351 maptile *m = op->map;
352 int i; 352 int i;
353 353
354 if (--op->duration < 0) 354 if (--op->duration < 0)
355 { 355 {
356 op->destroy (true); 356 op->destroy ();
357 return; 357 return;
358 } 358 }
359 359
360 hit_map (op, 0, op->attacktype, 0); 360 hit_map (op, 0, op->attacktype, 0);
361 361
396 object *tmp, *owner; 396 object *tmp, *owner;
397 397
398 if (!op->other_arch) 398 if (!op->other_arch)
399 { 399 {
400 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 400 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
401 op->destroy (true); 401 op->destroy ();
402 return; 402 return;
403 } 403 }
404 404
405 if (op->env) 405 if (op->env)
406 { 406 {
407 object *env = op->outer_env (); 407 object *env = op->outer_env ();
408 408
409 if (!env->map || out_of_map (env->map, env->x, env->y)) 409 if (!env->map || out_of_map (env->map, env->x, env->y))
410 { 410 {
411 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 411 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
412 op->destroy (true); 412 op->destroy ();
413 return; 413 return;
414 } 414 }
415 415
416 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON); 416 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON);
417 } 417 }
418 else if (out_of_map (op->map, op->x, op->y)) 418 else if (out_of_map (op->map, op->x, op->y))
419 { 419 {
420 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 420 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
421 op->destroy (true); 421 op->destroy ();
422 return; 422 return;
423 } 423 }
424 424
425 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps 425 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps
426 // NOTE: If this breaks something important: remove this. I can't think of anything 426 // NOTE: If this breaks something important: remove this. I can't think of anything
427 // bad at the moment that might happen from this. 427 // bad at the moment that might happen from this.
428 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 428 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
429 { 429 {
430 op->destroy (true); 430 op->destroy ();
431 return; 431 return;
432 } 432 }
433 433
434 if (op->attacktype) 434 if (op->attacktype)
435 { 435 {
450 if ((tmp->attacktype & AT_HOLYWORD 450 if ((tmp->attacktype & AT_HOLYWORD
451 || tmp->attacktype & AT_GODPOWER) 451 || tmp->attacktype & AT_GODPOWER)
452 && owner 452 && owner
453 && !tailor_god_spell (tmp, owner)) 453 && !tailor_god_spell (tmp, owner))
454 { 454 {
455 op->destroy (true); 455 op->destroy ();
456 return; 456 return;
457 } 457 }
458 458
459 /* special for bombs - it actually has sane values for these */ 459 /* special for bombs - it actually has sane values for these */
460 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 460 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
488 488
489 tmp->insert_at (op, op); 489 tmp->insert_at (op, op);
490 tmp->play_sound (tmp->sound); 490 tmp->play_sound (tmp->sound);
491 491
492 /* remove the firebullet */ 492 /* remove the firebullet */
493 op->destroy (true); 493 op->destroy ();
494} 494}
495 495
496/* checks to see what op should do, given the space it is on 496/* checks to see what op should do, given the space it is on
497 * (eg, explode, damage player, etc) 497 * (eg, explode, damage player, etc)
498 */ 498 */
529 // TODO: can't understand the following if's 529 // TODO: can't understand the following if's
530 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 530 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
531 { 531 {
532 if (!QUERY_FLAG (op, FLAG_REMOVED)) 532 if (!QUERY_FLAG (op, FLAG_REMOVED))
533 { 533 {
534 op->destroy (true); 534 op->destroy ();
535 return; 535 return;
536 } 536 }
537 } 537 }
538 } 538 }
539 } 539 }
568 if (--op->range <= 0) 568 if (--op->range <= 0)
569 { 569 {
570 if (op->other_arch) 570 if (op->other_arch)
571 explode_bullet (op); 571 explode_bullet (op);
572 else 572 else
573 op->destroy (true); 573 op->destroy ();
574 574
575 return; 575 return;
576 } 576 }
577 577
578 new_x = op->x + DIRX (op); 578 new_x = op->x + DIRX (op);
580 m = op->map; 580 m = op->map;
581 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y); 581 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y);
582 582
583 if (mflags & P_OUT_OF_MAP) 583 if (mflags & P_OUT_OF_MAP)
584 { 584 {
585 op->destroy (true); 585 op->destroy ();
586 return; 586 return;
587 } 587 }
588 588
589 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 589 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))
590 { 590 {
591 if (op->other_arch) 591 if (op->other_arch)
592 explode_bullet (op); 592 explode_bullet (op);
593 else 593 else
594 op->destroy (true); 594 op->destroy ();
595 595
596 return; 596 return;
597 } 597 }
598 598
599 if (!(op = m->insert (op, new_x, new_y, op))) 599 if (!(op = m->insert (op, new_x, new_y, op)))
655 655
656 maptile *newmap; 656 maptile *newmap;
657 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y); 657 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
658 if (mflags & P_OUT_OF_MAP) 658 if (mflags & P_OUT_OF_MAP)
659 { 659 {
660 tmp->destroy (true); 660 tmp->destroy ();
661 return 0; 661 return 0;
662 } 662 }
663 663
664 tmp->map = newmap; 664 tmp->map = newmap;
665 665
666 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 666 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
667 { 667 {
668 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 668 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
669 { 669 {
670 tmp->destroy (true); 670 tmp->destroy ();
671 return 0; 671 return 0;
672 } 672 }
673 673
674 tmp->x = op->x; 674 tmp->x = op->x;
675 tmp->y = op->y; 675 tmp->y = op->y;
730 * when their cone dies when they die. 730 * when their cone dies when they die.
731 */ 731 */
732 /* If no owner left, the spell dies out. */ 732 /* If no owner left, the spell dies out. */
733 if (op->owner == NULL) 733 if (op->owner == NULL)
734 { 734 {
735 op->destroy (true); 735 op->destroy ();
736 return; 736 return;
737 } 737 }
738#endif 738#endif
739 739
740 hit_map (op, 0, op->attacktype, 0); 740 hit_map (op, 0, op->attacktype, 0);
741
742 if (!op->is_on_map ())
743 return;
741 744
742 /* Check to see if we should push anything. 745 /* Check to see if we should push anything.
743 * Spell objects with weight push whatever they encounter to some 746 * Spell objects with weight push whatever they encounter to some
744 * degree. 747 * degree.
745 */ 748 */
746 if (op->weight) 749 if (op->weight)
750 {
747 check_spell_knockback (op); 751 check_spell_knockback (op);
748 752
749 if (op->destroyed ()) 753 if (!op->is_on_map ())
750 return; 754 return;
755 }
751 756
752 if (op->duration-- < 0) 757 if (op->duration-- < 0)
753 { 758 {
754 op->destroy (true); 759 op->destroy ();
755 return; 760 return;
756 } 761 }
757 /* Object has hit maximum range, so don't have it move 762 /* Object has hit maximum range, so don't have it move
758 * any further. When the duration above expires, 763 * any further. When the duration above expires,
759 * then the object will get removed. 764 * then the object will get removed.
958 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding 963 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding
959 // on a safe map. I don't like this special casing, but it seems to be neccessary 964 // on a safe map. I don't like this special casing, but it seems to be neccessary
960 // as bombs can be carried. 965 // as bombs can be carried.
961 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 966 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
962 { 967 {
963 op->destroy (true); 968 op->destroy ();
964 return; 969 return;
965 } 970 }
966 971
967 /* This copies a lot of the code from the fire bullet, 972 /* This copies a lot of the code from the fire bullet,
968 * but using the cast_bullet isn't really feasible, 973 * but using the cast_bullet isn't really feasible,
1003 int mflags; 1008 int mflags;
1004 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir]; 1009 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir];
1005 maptile *m; 1010 maptile *m;
1006 1011
1007 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy); 1012 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy);
1013
1014 // when creating a bomb below ourself it should always work, even
1015 // when movement is blocked (somehow we got here, somehow we are here,
1016 // so we should also be able to make a bomb here). (originally added
1017 // to fix create bomb traps in doors, which cast with dir=0).
1018 if (dir)
1019 {
1008 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) 1020 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK))
1009 { 1021 {
1010 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1022 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
1011 return 0; 1023 return 0;
1024 }
1012 } 1025 }
1013 1026
1014 tmp = arch_to_object (spell->other_arch); 1027 tmp = arch_to_object (spell->other_arch);
1015 1028
1016 /* level dependencies for bomb */ 1029 /* level dependencies for bomb */
1150 } 1163 }
1151 else 1164 else
1152 { 1165 {
1153 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target)); 1166 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target));
1154 target->stats.hp = target->stats.maxhp * 2; 1167 target->stats.hp = target->stats.maxhp * 2;
1155 effect->destroy (true); 1168 effect->destroy ();
1156 return 0; 1169 return 0;
1157 } 1170 }
1158 } 1171 }
1159 } 1172 }
1160 else 1173 else
1192 mapxy pos (op); 1205 mapxy pos (op);
1193 pos.move (op->direction); 1206 pos.move (op->direction);
1194 1207
1195 if (!pos.normalise ()) 1208 if (!pos.normalise ())
1196 { 1209 {
1197 op->destroy (true); 1210 op->destroy ();
1198 return; 1211 return;
1199 } 1212 }
1200 1213
1201 mapspace &ms = pos.ms (); 1214 mapspace &ms = pos.ms ();
1202 1215
1204 { 1217 {
1205 hit_map (op, op->direction, AT_MAGIC, 1); 1218 hit_map (op, op->direction, AT_MAGIC, 1);
1206 /* Basically, missile only hits one thing then goes away. 1219 /* Basically, missile only hits one thing then goes away.
1207 * we need to remove it if someone hasn't already done so. 1220 * we need to remove it if someone hasn't already done so.
1208 */ 1221 */
1209 op->destroy (true); 1222 op->destroy ();
1210 return; 1223 return;
1211 } 1224 }
1212 1225
1213 if (!op->direction) 1226 if (!op->direction)
1214 { 1227 {
1215 op->destroy (true); 1228 op->destroy ();
1216 return; 1229 return;
1217 } 1230 }
1218 1231
1219 int i = spell_find_dir (pos.m, pos.x, pos.y, op->owner); 1232 int i = spell_find_dir (pos.m, pos.x, pos.y, op->owner);
1220 if (i > 0 && i != op->direction) 1233 if (i > 0 && i != op->direction)
1245 1258
1246 object *tmp = get_archetype (FORCE_NAME); 1259 object *tmp = get_archetype (FORCE_NAME);
1247 tmp->speed = 0.01; 1260 tmp->speed = 0.01;
1248 tmp->stats.food = time; 1261 tmp->stats.food = time;
1249 SET_FLAG (tmp, FLAG_IS_USED_UP); 1262 SET_FLAG (tmp, FLAG_IS_USED_UP);
1250 tmp->glow_radius = radius;
1251 if (tmp->glow_radius > MAX_LIGHT_RADII)
1252 tmp->glow_radius = MAX_LIGHT_RADII; 1263 tmp->glow_radius = min (MAX_LIGHT_RADIUS, radius);
1253
1254 tmp = insert_ob_in_ob (tmp, op); 1264 tmp = insert_ob_in_ob (tmp, op);
1255 1265
1256 if (tmp->glow_radius > op->glow_radius) 1266 if (tmp->glow_radius > op->glow_radius)
1257 op->glow_radius = tmp->glow_radius; 1267 op->glow_radius = tmp->glow_radius;
1258 1268
1260} 1270}
1261 1271
1262int 1272int
1263cast_destruction (object *op, object *caster, object *spell_ob) 1273cast_destruction (object *op, object *caster, object *spell_ob)
1264{ 1274{
1265 int i, j, range, mflags, friendly = 0, dam, dur;
1266 sint16 sx, sy;
1267 maptile *m;
1268 object *tmp;
1269 const char *skill;
1270
1271 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 1275 int range = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
1272 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 1276 int dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
1273 dur = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 1277 int dur = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1274 if (QUERY_FLAG (op, FLAG_FRIENDLY) || op->type == PLAYER) 1278
1275 friendly = 1; 1279 bool friendly = op->flag [FLAG_FRIENDLY] || op->is_player ();
1276 1280
1277 /* destruction doesn't use another spell object, so we need 1281 /* destruction doesn't use another spell object, so we need
1278 * update op's skill pointer so that exp is properly awarded. 1282 * update op's skill pointer so that exp is properly awarded.
1279 * We do some shortcuts here - since this is just temporary
1280 * and we'll reset the values back, we don't need to go through
1281 * the full share string/free_string route.
1282 */ 1283 */
1283 skill = op->skill; 1284 const shstr skill = op->skill;
1285
1284 if (caster == op) 1286 if (caster == op)
1285 op->skill = spell_ob->skill; 1287 op->skill = spell_ob->skill;
1286 else if (caster->skill) 1288 else if (caster->skill)
1287 op->skill = caster->skill; 1289 op->skill = caster->skill;
1288 else 1290 else
1289 op->skill = NULL; 1291 op->skill = 0;
1290 1292
1291 op->change_skill (find_skill_by_name (op, op->skill)); 1293 op->change_skill (find_skill_by_name (op, op->skill));
1292 1294
1293 for (i = -range; i <= range; i++) 1295 unordered_mapwalk (op, -range, -range, range, range)
1294 { 1296 {
1295 for (j = -range; j <= range; j++) 1297 mapspace &ms = m->at (nx, ny);
1296 {
1297 m = op->map;
1298 sx = op->x + i;
1299 sy = op->y + j;
1300 1298
1301 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1302 if (mflags & P_OUT_OF_MAP)
1303 continue;
1304
1305 if (mflags & P_IS_ALIVE) 1299 if (ms.flags () & P_IS_ALIVE)
1300 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1301 if (tmp->flag [FLAG_ALIVE] || tmp->is_player ())
1306 { 1302 {
1307 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above) 1303 tmp = tmp->head_ ();
1308 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1309 break;
1310 1304
1311 if (tmp) 1305 if ((friendly && !tmp->flag [FLAG_FRIENDLY] && !tmp->is_player ())
1306 || (!friendly && (tmp->flag [FLAG_FRIENDLY] || tmp->is_player ())))
1312 { 1307 {
1313 if (tmp->head) 1308 if (spell_ob->subtype == SP_DESTRUCTION)
1314 tmp = tmp->head;
1315
1316 if ((friendly && !QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->type != PLAYER) ||
1317 (!friendly && (QUERY_FLAG (tmp, FLAG_FRIENDLY) || tmp->type == PLAYER)))
1318 { 1309 {
1319 if (spell_ob->subtype == SP_DESTRUCTION)
1320 {
1321 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1310 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1322 1311
1323 if (spell_ob->other_arch) 1312 if (spell_ob->other_arch)
1324 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op); 1313 m->insert (arch_to_object (spell_ob->other_arch), nx, ny, op);
1325 } 1314 }
1326 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100) 1315 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist [ATNR_MAGIC] != 100)
1327 { 1316 {
1328 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch) 1317 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch)
1329 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op); 1318 m->insert (arch_to_object (spell_ob->other_arch), nx, ny, op);
1330 }
1331 } 1319 }
1332 } 1320 }
1333 } 1321 }
1334 }
1335 } 1322 }
1336 1323
1337 op->skill = skill; 1324 op->skill = skill;
1338 return 1; 1325 return 1;
1339} 1326}
1487 /* If there is nothing living on this space, no need to go further */ 1474 /* If there is nothing living on this space, no need to go further */
1488 if (!(mflags & P_IS_ALIVE)) 1475 if (!(mflags & P_IS_ALIVE))
1489 continue; 1476 continue;
1490 1477
1491 // players can only affect spaces that they can actually see 1478 // players can only affect spaces that they can actually see
1479 if (caster
1492 if (caster && caster->contr 1480 && caster->contr
1493 && caster->contr->visibility_at (m, nx, ny) < 70) 1481 && caster->contr->darkness_at (m, nx, ny) == LOS_BLOCKED)
1494 continue; 1482 continue;
1495 1483
1496 for (tmp = GET_MAP_TOP (m, nx, ny); tmp; tmp = tmp->below) 1484 for (tmp = GET_MAP_TOP (m, nx, ny); tmp; tmp = tmp->below)
1497 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1485 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1498 break; 1486 break;
1608 } /* for y */ 1596 } /* for y */
1609 1597
1610 return 1; 1598 return 1;
1611} 1599}
1612 1600
1613
1614/* Move_ball_spell: This handles ball type spells that just sort of wander 1601/* Move_ball_spell: This handles ball type spells that just sort of wander
1615 * about. was called move_ball_lightning, but since more than the ball 1602 * about. was called move_ball_lightning, but since more than the ball
1616 * lightning spell used it, that seemed misnamed. 1603 * lightning spell used it, that seemed misnamed.
1617 * op is the spell effect. 1604 * op is the spell effect.
1618 * note that duration is handled by process_object() in time.c 1605 * note that duration is handled by process_object() in time.c
1643 for (i = 1; i < 9; i++) 1630 for (i = 1; i < 9; i++)
1644 { 1631 {
1645 /* i bit 0: alters sign of offset 1632 /* i bit 0: alters sign of offset
1646 * other bits (i / 2): absolute value of offset 1633 * other bits (i / 2): absolute value of offset
1647 */ 1634 */
1648
1649 int offset = ((i ^ j) & 1) ? (i / 2) : -(i / 2); 1635 int offset = ((i ^ j) & 1) ? (i / 2) : -(i / 2);
1650 int tmpdir = absdir (op->direction + offset); 1636 int tmpdir = absdir (op->direction + offset);
1651 1637
1652 nx = op->x + freearr_x[tmpdir]; 1638 nx = op->x + freearr_x[tmpdir];
1653 ny = op->y + freearr_y[tmpdir]; 1639 ny = op->y + freearr_y[tmpdir];
1655 { 1641 {
1656 dir = tmpdir; 1642 dir = tmpdir;
1657 break; 1643 break;
1658 } 1644 }
1659 } 1645 }
1646
1660 if (dir == 0) 1647 if (dir == 0)
1661 { 1648 {
1662 nx = op->x; 1649 nx = op->x;
1663 ny = op->y; 1650 ny = op->y;
1664 m = op->map; 1651 m = op->map;
1737 object *owner = op->env; 1724 object *owner = op->env;
1738 1725
1739 if (!owner) // MUST not happen, remove when true TODO 1726 if (!owner) // MUST not happen, remove when true TODO
1740 { 1727 {
1741 LOG (llevError, "swarm spell found outside inventory: %s\n", op->debug_desc ()); 1728 LOG (llevError, "swarm spell found outside inventory: %s\n", op->debug_desc ());
1742 op->destroy (true); 1729 op->destroy ();
1743 return; 1730 return;
1744 } 1731 }
1745 1732
1746 if (!op->duration || !owner->is_on_map ()) 1733 if (!op->duration || !owner->is_on_map ())
1747 { 1734 {
1885 int dam, mflags; 1872 int dam, mflags;
1886 maptile *m; 1873 maptile *m;
1887 1874
1888 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1875 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1889 1876
1890 if (!dir) 1877 if (dir)
1891 {
1892 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?");
1893 return 0;
1894 } 1878 {
1895
1896 x = op->x + freearr_x[dir]; 1879 x = op->x + freearr_x[dir];
1897 y = op->y + freearr_y[dir]; 1880 y = op->y + freearr_y[dir];
1898 m = op->map; 1881 m = op->map;
1899 1882
1900 mflags = get_map_flags (m, &m, x, y, &x, &y); 1883 mflags = get_map_flags (m, &m, x, y, &x, &y);
1901 1884
1902 if (mflags & P_OUT_OF_MAP) 1885 if (mflags & P_OUT_OF_MAP)
1903 { 1886 {
1904 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there."); 1887 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there.");
1905 return 0; 1888 return 0;
1906 } 1889 }
1907 1890
1908 if (mflags & P_IS_ALIVE && spell->attacktype) 1891 if (mflags & P_IS_ALIVE && spell->attacktype)
1909 { 1892 {
1910 for (target = GET_MAP_OB (m, x, y); target; target = target->above) 1893 for (target = GET_MAP_OB (m, x, y); target; target = target->above)
1911 if (QUERY_FLAG (target, FLAG_MONSTER)) 1894 if (QUERY_FLAG (target, FLAG_MONSTER))
1912 { 1895 {
1913 /* oky doky. got a target monster. Lets make a blinding attack */ 1896 /* oky doky. got a target monster. Lets make a blinding attack */
1914 if (target->head) 1897 if (target->head)
1915 target = target->head; 1898 target = target->head;
1916 1899
1917 hit_player (target, dam, op, spell->attacktype, 1); 1900 hit_player (target, dam, op, spell->attacktype, 1);
1918 return 1; /* one success only! */ 1901 return 1; /* one success only! */
1902 }
1919 } 1903 }
1920 }
1921 1904
1922 /* no live target, perhaps a wall is in the way? */ 1905 /* no live target, perhaps a wall is in the way? */
1923 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) 1906 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)))
1924 { 1907 {
1925 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 1908 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1926 return 0; 1909 return 0;
1910 }
1927 } 1911 }
1928 1912
1929 /* ok, looks groovy to just insert a new light on the map */ 1913 /* ok, looks groovy to just insert a new light on the map */
1930 tmp = arch_to_object (spell->other_arch); 1914 tmp = arch_to_object (spell->other_arch);
1931 if (!tmp) 1915 if (!tmp)
1932 { 1916 {
1933 LOG (llevError, "Error: spell arch for cast_light() missing.\n"); 1917 LOG (llevError, "Error: spell arch for cast_light() missing.\n");
1934 return 0; 1918 return 0;
1935 } 1919 }
1920
1936 tmp->stats.food = spell->duration + SP_level_duration_adjust (caster, spell); 1921 tmp->stats.food = spell->duration + SP_level_duration_adjust (caster, spell);
1922
1937 if (tmp->glow_radius) 1923 if (tmp->glow_radius)
1938 {
1939 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); 1924 tmp->glow_radius = min (MAX_LIGHT_RADIUS, spell->range + SP_level_range_adjust (caster, spell));
1940 if (tmp->glow_radius > MAX_LIGHT_RADII)
1941 tmp->glow_radius = MAX_LIGHT_RADII;
1942 }
1943 1925
1926 if (dir)
1944 m->insert (tmp, x, y, op); 1927 m->insert (tmp, x, y, op);
1928 else
1929 caster->outer_env ()->insert (tmp);
1930
1945 return 1; 1931 return 1;
1946} 1932}
1947 1933
1948/* cast_cause_disease: this spell looks along <dir> from the 1934/* cast_cause_disease: this spell looks along <dir> from the
1949 * player and infects someone. 1935 * player and infects someone.
2056 2042
2057 if (infect_object (walk, disease, 1)) 2043 if (infect_object (walk, disease, 1))
2058 { 2044 {
2059 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); 2045 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name);
2060 2046
2061 disease->destroy (true); /* don't need this one anymore */ 2047 disease->destroy (); /* don't need this one anymore */
2062 walk->map->insert (get_archetype ("detect_magic"), x, y, op); 2048 walk->map->insert (get_archetype ("detect_magic"), x, y, op);
2063 return 1; 2049 return 1;
2064 } 2050 }
2065 2051
2066 disease->destroy (true); 2052 disease->destroy ();
2067 } 2053 }
2068 } /* if living creature */ 2054 } /* if living creature */
2069 } /* for range of spaces */ 2055 } /* for range of spaces */
2070 2056
2071 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2057 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines