1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_spell_util_c = |
|
|
4 | * "$Id: spell_util.C,v 1.11 2006/09/10 15:59:58 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | |
|
|
8 | /* |
1 | /* |
9 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
10 | |
3 | |
11 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
12 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
23 | |
16 | |
24 | You should have received a copy of the GNU General Public License |
17 | You should have received a copy of the GNU General Public License |
25 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
27 | |
20 | |
28 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
21 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
29 | */ |
22 | */ |
30 | |
23 | |
31 | |
24 | |
32 | #include <global.h> |
25 | #include <global.h> |
33 | #include <spells.h> |
26 | #include <spells.h> |
… | |
… | |
126 | } |
119 | } |
127 | |
120 | |
128 | i = 0; |
121 | i = 0; |
129 | while (spell_mapping[i]) |
122 | while (spell_mapping[i]) |
130 | { |
123 | { |
131 | if (!find_archetype (spell_mapping[i])) |
124 | if (!archetype::find (spell_mapping[i])) |
132 | { |
125 | { |
133 | LOG (llevError, "Unable to find spell mapping %s (%i)\n", spell_mapping[i], i); |
126 | LOG (llevError, "Unable to find spell mapping %s (%i)\n", spell_mapping[i], i); |
134 | } |
127 | } |
135 | i++; |
128 | i++; |
136 | } |
129 | } |
… | |
… | |
160 | /* pretty basic function - basically just takes |
153 | /* pretty basic function - basically just takes |
161 | * an object, sets the x,y, and calls insert_ob_in_map |
154 | * an object, sets the x,y, and calls insert_ob_in_map |
162 | */ |
155 | */ |
163 | |
156 | |
164 | void |
157 | void |
165 | spell_effect (object *spob, int x, int y, mapstruct *map, object *originator) |
158 | spell_effect (object *spob, int x, int y, maptile *map, object *originator) |
166 | { |
159 | { |
167 | |
160 | |
168 | if (spob->other_arch != NULL) |
161 | if (spob->other_arch != NULL) |
169 | { |
162 | { |
170 | object *effect = arch_to_object (spob->other_arch); |
163 | object *effect = arch_to_object (spob->other_arch); |
… | |
… | |
451 | * reflect_spell fails.) |
444 | * reflect_spell fails.) |
452 | * Caller should be sure it passes us valid map coordinates |
445 | * Caller should be sure it passes us valid map coordinates |
453 | * eg, updated for tiled maps. |
446 | * eg, updated for tiled maps. |
454 | */ |
447 | */ |
455 | int |
448 | int |
456 | reflwall (mapstruct *m, int x, int y, object *sp_op) |
449 | reflwall (maptile *m, int x, int y, object *sp_op) |
457 | { |
450 | { |
458 | object *op; |
451 | object *op; |
459 | |
452 | |
460 | if (OUT_OF_REAL_MAP (m, x, y)) |
453 | if (OUT_OF_REAL_MAP (m, x, y)) |
461 | return 0; |
454 | return 0; |
… | |
… | |
475 | * in. |
468 | * in. |
476 | */ |
469 | */ |
477 | int |
470 | int |
478 | cast_create_obj (object *op, object *caster, object *new_op, int dir) |
471 | cast_create_obj (object *op, object *caster, object *new_op, int dir) |
479 | { |
472 | { |
480 | mapstruct *m; |
473 | maptile *m; |
481 | sint16 sx, sy; |
474 | sint16 sx, sy; |
482 | |
475 | |
483 | if (dir && |
476 | if (dir && |
484 | ((get_map_flags (op->map, &m, op->x + freearr_x[dir], op->y + freearr_y[dir], &sx, &sy) & P_OUT_OF_MAP) || |
477 | ((get_map_flags (op->map, &m, op->x + freearr_x[dir], op->y + freearr_y[dir], &sx, &sy) & P_OUT_OF_MAP) || |
485 | OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))) |
478 | OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))) |
… | |
… | |
505 | * does not have AT_MAGIC, then counterwalls do not effect the spell. |
498 | * does not have AT_MAGIC, then counterwalls do not effect the spell. |
506 | * |
499 | * |
507 | */ |
500 | */ |
508 | |
501 | |
509 | int |
502 | int |
510 | ok_to_put_more (mapstruct *m, sint16 x, sint16 y, object *op, int immune_stop) |
503 | ok_to_put_more (maptile *m, sint16 x, sint16 y, object *op, int immune_stop) |
511 | { |
504 | { |
512 | object *tmp; |
505 | object *tmp; |
513 | int mflags; |
506 | int mflags; |
514 | mapstruct *mp; |
507 | maptile *mp; |
515 | |
508 | |
516 | mp = m; |
509 | mp = m; |
517 | mflags = get_map_flags (m, &mp, x, y, &x, &y); |
510 | mflags = get_map_flags (m, &mp, x, y, &x, &y); |
518 | |
511 | |
519 | if (mflags & P_OUT_OF_MAP) |
512 | if (mflags & P_OUT_OF_MAP) |
… | |
… | |
585 | int |
578 | int |
586 | fire_arch_from_position (object *op, object *caster, sint16 x, sint16 y, int dir, object *spell) |
579 | fire_arch_from_position (object *op, object *caster, sint16 x, sint16 y, int dir, object *spell) |
587 | { |
580 | { |
588 | object *tmp; |
581 | object *tmp; |
589 | int mflags; |
582 | int mflags; |
590 | mapstruct *m; |
583 | maptile *m; |
591 | |
584 | |
592 | if (spell->other_arch == NULL) |
585 | if (spell->other_arch == NULL) |
593 | return 0; |
586 | return 0; |
594 | |
587 | |
595 | m = op->map; |
588 | m = op->map; |
… | |
… | |
685 | |
678 | |
686 | object * |
679 | object * |
687 | find_target_for_friendly_spell (object *op, int dir) |
680 | find_target_for_friendly_spell (object *op, int dir) |
688 | { |
681 | { |
689 | object *tmp; |
682 | object *tmp; |
690 | mapstruct *m; |
683 | maptile *m; |
691 | sint16 x, y; |
684 | sint16 x, y; |
692 | int mflags; |
685 | int mflags; |
693 | |
686 | |
694 | /* I don't really get this block - if op isn't a player or rune, |
687 | /* I don't really get this block - if op isn't a player or rune, |
695 | * we then make the owner of this object the target. |
688 | * we then make the owner of this object the target. |
… | |
… | |
745 | * any, otherwise -1. |
738 | * any, otherwise -1. |
746 | * note that exclude can be NULL, in which case all bets are off. |
739 | * note that exclude can be NULL, in which case all bets are off. |
747 | */ |
740 | */ |
748 | |
741 | |
749 | int |
742 | int |
750 | spell_find_dir (mapstruct *m, int x, int y, object *exclude) |
743 | spell_find_dir (maptile *m, int x, int y, object *exclude) |
751 | { |
744 | { |
752 | int i, max = SIZEOFFREE; |
745 | int i, max = SIZEOFFREE; |
753 | sint16 nx, ny; |
746 | sint16 nx, ny; |
754 | int owner_type = 0, mflags; |
747 | int owner_type = 0, mflags; |
755 | object *tmp; |
748 | object *tmp; |
756 | mapstruct *mp; |
749 | maptile *mp; |
757 | |
750 | |
758 | if (exclude && exclude->head) |
751 | if (exclude && exclude->head) |
759 | exclude = exclude->head; |
752 | exclude = exclude->head; |
760 | if (exclude && exclude->type) |
753 | if (exclude && exclude->type) |
761 | owner_type = exclude->type; |
754 | owner_type = exclude->type; |
… | |
… | |
796 | archetype *at; |
789 | archetype *at; |
797 | int dir; |
790 | int dir; |
798 | |
791 | |
799 | /* Handle cases where we are passed a bogus mosntername */ |
792 | /* Handle cases where we are passed a bogus mosntername */ |
800 | |
793 | |
801 | if ((at = find_archetype (monstername)) == NULL) |
794 | if ((at = archetype::find (monstername)) == NULL) |
802 | return; |
795 | return; |
803 | |
796 | |
804 | /* find a free square nearby |
797 | /* find a free square nearby |
805 | * first we check the closest square for free squares |
798 | * first we check the closest square for free squares |
806 | */ |
799 | */ |
… | |
… | |
1125 | */ |
1118 | */ |
1126 | |
1119 | |
1127 | int |
1120 | int |
1128 | cast_spell (object *op, object *caster, int dir, object *spell_ob, char *stringarg) |
1121 | cast_spell (object *op, object *caster, int dir, object *spell_ob, char *stringarg) |
1129 | { |
1122 | { |
1130 | |
|
|
1131 | const char *godname; |
1123 | const char *godname; |
1132 | int success = 0, mflags, cast_level = 0, old_shoottype; |
1124 | int success = 0, mflags, cast_level = 0, old_shoottype; |
1133 | object *skill = NULL; |
1125 | object *skill = NULL; |
1134 | |
1126 | |
1135 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
1127 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
… | |
… | |
1137 | if (!spell_ob) |
1129 | if (!spell_ob) |
1138 | { |
1130 | { |
1139 | LOG (llevError, "cast_spell: null spell object passed\n"); |
1131 | LOG (llevError, "cast_spell: null spell object passed\n"); |
1140 | return 0; |
1132 | return 0; |
1141 | } |
1133 | } |
|
|
1134 | |
1142 | if (!strcmp ((godname = determine_god (op)), "none")) |
1135 | if (!strcmp ((godname = determine_god (op)), "none")) |
1143 | godname = "A random spirit"; |
1136 | godname = "A random spirit"; |
1144 | |
1137 | |
1145 | /* the caller should set caster to op if appropriate */ |
1138 | /* the caller should set caster to op if appropriate */ |
1146 | if (!caster) |
1139 | if (!caster) |
… | |
… | |
1268 | if ((mflags & P_NO_CLERIC) && spell_ob->stats.grace) |
1261 | if ((mflags & P_NO_CLERIC) && spell_ob->stats.grace) |
1269 | new_draw_info_format (NDI_UNIQUE, 0, op, "This ground is unholy! %s ignores you.", godname); |
1262 | new_draw_info_format (NDI_UNIQUE, 0, op, "This ground is unholy! %s ignores you.", godname); |
1270 | else |
1263 | else |
1271 | switch (op->contr->shoottype) |
1264 | switch (op->contr->shoottype) |
1272 | { |
1265 | { |
1273 | case range_magic: |
1266 | case range_magic: |
1274 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your spellcasting."); |
1267 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your spellcasting."); |
1275 | break; |
1268 | break; |
1276 | case range_misc: |
1269 | case range_misc: |
1277 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of your item."); |
1270 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of your item."); |
1278 | break; |
1271 | break; |
1279 | case range_golem: |
1272 | case range_golem: |
1280 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of your scroll."); |
1273 | new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of your scroll."); |
1281 | break; |
1274 | break; |
1282 | default: |
1275 | default: |
1283 | break; |
1276 | break; |
1284 | } |
1277 | } |
1285 | return 0; |
1278 | return 0; |
1286 | } |
1279 | } |
1287 | |
1280 | |
1288 | if (caster == op && settings.casting_time == TRUE && spell_ob->type == SPELL) |
1281 | if (caster == op && settings.casting_time == TRUE && spell_ob->type == SPELL) |
… | |
… | |
1362 | change_skill (op, skill, 0); /* needed for proper exp credit */ |
1355 | change_skill (op, skill, 0); /* needed for proper exp credit */ |
1363 | } |
1356 | } |
1364 | |
1357 | |
1365 | switch (spell_ob->subtype) |
1358 | switch (spell_ob->subtype) |
1366 | { |
1359 | { |
1367 | /* The order of case statements is same as the order they show up |
1360 | /* The order of case statements is same as the order they show up |
1368 | * in in spells.h. |
1361 | * in in spells.h. |
1369 | */ |
1362 | */ |
1370 | case SP_RAISE_DEAD: |
1363 | case SP_RAISE_DEAD: |
1371 | success = cast_raise_dead_spell (op, caster, spell_ob, dir, stringarg); |
1364 | success = cast_raise_dead_spell (op, caster, spell_ob, dir, stringarg); |
1372 | break; |
1365 | break; |
1373 | |
1366 | |
1374 | case SP_RUNE: |
1367 | case SP_RUNE: |
1375 | success = write_rune (op, caster, spell_ob, dir, stringarg); |
1368 | success = write_rune (op, caster, spell_ob, dir, stringarg); |
1376 | break; |
1369 | break; |
1377 | |
1370 | |
1378 | case SP_MAKE_MARK: |
1371 | case SP_MAKE_MARK: |
1379 | success = write_mark (op, spell_ob, stringarg); |
1372 | success = write_mark (op, spell_ob, stringarg); |
1380 | break; |
1373 | break; |
1381 | |
1374 | |
1382 | case SP_BOLT: |
1375 | case SP_BOLT: |
1383 | success = fire_bolt (op, caster, dir, spell_ob, skill); |
1376 | success = fire_bolt (op, caster, dir, spell_ob, skill); |
1384 | break; |
1377 | break; |
1385 | |
1378 | |
1386 | case SP_BULLET: |
1379 | case SP_BULLET: |
1387 | success = fire_bullet (op, caster, dir, spell_ob); |
1380 | success = fire_bullet (op, caster, dir, spell_ob); |
1388 | break; |
1381 | break; |
1389 | |
1382 | |
1390 | case SP_CONE: |
1383 | case SP_CONE: |
1391 | success = cast_cone (op, caster, dir, spell_ob); |
1384 | success = cast_cone (op, caster, dir, spell_ob); |
1392 | break; |
1385 | break; |
1393 | |
1386 | |
1394 | case SP_BOMB: |
1387 | case SP_BOMB: |
1395 | success = create_bomb (op, caster, dir, spell_ob); |
1388 | success = create_bomb (op, caster, dir, spell_ob); |
1396 | break; |
1389 | break; |
1397 | |
1390 | |
1398 | case SP_WONDER: |
1391 | case SP_WONDER: |
1399 | success = cast_wonder (op, caster, dir, spell_ob); |
1392 | success = cast_wonder (op, caster, dir, spell_ob); |
1400 | break; |
1393 | break; |
1401 | |
1394 | |
1402 | case SP_SMITE: |
1395 | case SP_SMITE: |
1403 | success = cast_smite_spell (op, caster, dir, spell_ob); |
1396 | success = cast_smite_spell (op, caster, dir, spell_ob); |
1404 | break; |
1397 | break; |
1405 | |
1398 | |
1406 | case SP_MAGIC_MISSILE: |
1399 | case SP_MAGIC_MISSILE: |
|
|
1400 | success = fire_arch_from_position (op, caster, op->x + freearr_x[dir], op->y + freearr_y[dir], dir, spell_ob); |
|
|
1401 | break; |
|
|
1402 | |
|
|
1403 | case SP_SUMMON_GOLEM: |
|
|
1404 | success = summon_golem (op, caster, dir, spell_ob); |
|
|
1405 | old_shoottype = range_golem; |
|
|
1406 | break; |
|
|
1407 | |
|
|
1408 | case SP_DIMENSION_DOOR: |
|
|
1409 | /* dimension door needs the actual caster, because that is what is |
|
|
1410 | * moved. |
|
|
1411 | */ |
|
|
1412 | success = dimension_door (op, caster, spell_ob, dir); |
|
|
1413 | break; |
|
|
1414 | |
|
|
1415 | case SP_MAGIC_MAPPING: |
|
|
1416 | if (op->type == PLAYER) |
|
|
1417 | { |
|
|
1418 | spell_effect (spell_ob, op->x, op->y, op->map, op); |
|
|
1419 | draw_magic_map (op); |
|
|
1420 | success = 1; |
|
|
1421 | } |
|
|
1422 | else |
|
|
1423 | success = 0; |
|
|
1424 | break; |
|
|
1425 | |
|
|
1426 | case SP_MAGIC_WALL: |
|
|
1427 | success = magic_wall (op, caster, dir, spell_ob); |
|
|
1428 | break; |
|
|
1429 | |
|
|
1430 | case SP_DESTRUCTION: |
|
|
1431 | success = cast_destruction (op, caster, spell_ob); |
|
|
1432 | break; |
|
|
1433 | |
|
|
1434 | case SP_PERCEIVE_SELF: |
|
|
1435 | success = perceive_self (op); |
|
|
1436 | break; |
|
|
1437 | |
|
|
1438 | case SP_WORD_OF_RECALL: |
|
|
1439 | success = cast_word_of_recall (op, caster, spell_ob); |
|
|
1440 | break; |
|
|
1441 | |
|
|
1442 | case SP_INVISIBLE: |
|
|
1443 | success = cast_invisible (op, caster, spell_ob); |
|
|
1444 | break; |
|
|
1445 | |
|
|
1446 | case SP_PROBE: |
|
|
1447 | success = probe (op, caster, spell_ob, dir); |
|
|
1448 | break; |
|
|
1449 | |
|
|
1450 | case SP_HEALING: |
|
|
1451 | success = cast_heal (op, caster, spell_ob, dir); |
|
|
1452 | break; |
|
|
1453 | |
|
|
1454 | case SP_CREATE_FOOD: |
|
|
1455 | success = cast_create_food (op, caster, spell_ob, dir, stringarg); |
|
|
1456 | break; |
|
|
1457 | |
|
|
1458 | case SP_EARTH_TO_DUST: |
|
|
1459 | success = cast_earth_to_dust (op, caster, spell_ob); |
|
|
1460 | break; |
|
|
1461 | |
|
|
1462 | case SP_CHANGE_ABILITY: |
|
|
1463 | success = cast_change_ability (op, caster, spell_ob, dir, 0); |
|
|
1464 | break; |
|
|
1465 | |
|
|
1466 | case SP_BLESS: |
|
|
1467 | success = cast_bless (op, caster, spell_ob, dir); |
|
|
1468 | break; |
|
|
1469 | |
|
|
1470 | case SP_CURSE: |
|
|
1471 | success = cast_curse (op, caster, spell_ob, dir); |
|
|
1472 | break; |
|
|
1473 | |
|
|
1474 | case SP_SUMMON_MONSTER: |
|
|
1475 | success = summon_object (op, caster, spell_ob, dir, stringarg); |
|
|
1476 | break; |
|
|
1477 | |
|
|
1478 | case SP_CHARGING: |
|
|
1479 | success = recharge (op, caster, spell_ob); |
|
|
1480 | break; |
|
|
1481 | |
|
|
1482 | case SP_POLYMORPH: |
|
|
1483 | #ifdef NO_POLYMORPH |
|
|
1484 | /* Not great, but at least provide feedback so if players do have |
|
|
1485 | * polymorph (ie, find it as a preset item or left over from before |
|
|
1486 | * it was disabled), they get some feedback. |
|
|
1487 | */ |
|
|
1488 | new_draw_info (NDI_UNIQUE, 0, op, "The spell fizzles"); |
|
|
1489 | success = 0; |
|
|
1490 | #else |
|
|
1491 | success = cast_polymorph (op, caster, spell_ob, dir); |
|
|
1492 | #endif |
|
|
1493 | break; |
|
|
1494 | |
|
|
1495 | case SP_ALCHEMY: |
|
|
1496 | success = alchemy (op, caster, spell_ob); |
|
|
1497 | break; |
|
|
1498 | |
|
|
1499 | case SP_REMOVE_CURSE: |
|
|
1500 | success = remove_curse (op, caster, spell_ob); |
|
|
1501 | break; |
|
|
1502 | |
|
|
1503 | case SP_IDENTIFY: |
|
|
1504 | success = cast_identify (op, caster, spell_ob); |
|
|
1505 | break; |
|
|
1506 | |
|
|
1507 | case SP_DETECTION: |
|
|
1508 | success = cast_detection (op, caster, spell_ob, skill); |
|
|
1509 | break; |
|
|
1510 | |
|
|
1511 | case SP_MOOD_CHANGE: |
|
|
1512 | success = mood_change (op, caster, spell_ob); |
|
|
1513 | break; |
|
|
1514 | |
|
|
1515 | case SP_MOVING_BALL: |
|
|
1516 | if (spell_ob->path_repelled && (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) |
|
|
1517 | { |
|
|
1518 | new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the proper attunement to cast %s", &spell_ob->name); |
|
|
1519 | success = 0; |
|
|
1520 | } |
|
|
1521 | else |
1407 | success = fire_arch_from_position (op, caster, op->x + freearr_x[dir], op->y + freearr_y[dir], dir, spell_ob); |
1522 | success = fire_arch_from_position (op, caster, op->x + freearr_x[dir], op->y + freearr_y[dir], dir, spell_ob); |
1408 | break; |
1523 | break; |
1409 | |
1524 | |
1410 | case SP_SUMMON_GOLEM: |
|
|
1411 | success = summon_golem (op, caster, dir, spell_ob); |
|
|
1412 | old_shoottype = range_golem; |
|
|
1413 | break; |
|
|
1414 | |
|
|
1415 | case SP_DIMENSION_DOOR: |
|
|
1416 | /* dimension door needs the actual caster, because that is what is |
|
|
1417 | * moved. |
|
|
1418 | */ |
|
|
1419 | success = dimension_door (op, caster, spell_ob, dir); |
|
|
1420 | break; |
|
|
1421 | |
|
|
1422 | case SP_MAGIC_MAPPING: |
|
|
1423 | if (op->type == PLAYER) |
|
|
1424 | { |
|
|
1425 | spell_effect (spell_ob, op->x, op->y, op->map, op); |
|
|
1426 | draw_magic_map (op); |
|
|
1427 | success = 1; |
|
|
1428 | } |
|
|
1429 | else |
|
|
1430 | success = 0; |
|
|
1431 | break; |
|
|
1432 | |
|
|
1433 | case SP_MAGIC_WALL: |
|
|
1434 | success = magic_wall (op, caster, dir, spell_ob); |
|
|
1435 | break; |
|
|
1436 | |
|
|
1437 | case SP_DESTRUCTION: |
|
|
1438 | success = cast_destruction (op, caster, spell_ob); |
|
|
1439 | break; |
|
|
1440 | |
|
|
1441 | case SP_PERCEIVE_SELF: |
|
|
1442 | success = perceive_self (op); |
|
|
1443 | break; |
|
|
1444 | |
|
|
1445 | case SP_WORD_OF_RECALL: |
|
|
1446 | success = cast_word_of_recall (op, caster, spell_ob); |
|
|
1447 | break; |
|
|
1448 | |
|
|
1449 | case SP_INVISIBLE: |
|
|
1450 | success = cast_invisible (op, caster, spell_ob); |
|
|
1451 | break; |
|
|
1452 | |
|
|
1453 | case SP_PROBE: |
|
|
1454 | success = probe (op, caster, spell_ob, dir); |
|
|
1455 | break; |
|
|
1456 | |
|
|
1457 | case SP_HEALING: |
|
|
1458 | success = cast_heal (op, caster, spell_ob, dir); |
|
|
1459 | break; |
|
|
1460 | |
|
|
1461 | case SP_CREATE_FOOD: |
|
|
1462 | success = cast_create_food (op, caster, spell_ob, dir, stringarg); |
|
|
1463 | break; |
|
|
1464 | |
|
|
1465 | case SP_EARTH_TO_DUST: |
|
|
1466 | success = cast_earth_to_dust (op, caster, spell_ob); |
|
|
1467 | break; |
|
|
1468 | |
|
|
1469 | case SP_CHANGE_ABILITY: |
|
|
1470 | success = cast_change_ability (op, caster, spell_ob, dir, 0); |
|
|
1471 | break; |
|
|
1472 | |
|
|
1473 | case SP_BLESS: |
|
|
1474 | success = cast_bless (op, caster, spell_ob, dir); |
|
|
1475 | break; |
|
|
1476 | |
|
|
1477 | case SP_CURSE: |
|
|
1478 | success = cast_curse (op, caster, spell_ob, dir); |
|
|
1479 | break; |
|
|
1480 | |
|
|
1481 | case SP_SUMMON_MONSTER: |
|
|
1482 | success = summon_object (op, caster, spell_ob, dir, stringarg); |
|
|
1483 | break; |
|
|
1484 | |
|
|
1485 | case SP_CHARGING: |
|
|
1486 | success = recharge (op, caster, spell_ob); |
|
|
1487 | break; |
|
|
1488 | |
|
|
1489 | case SP_POLYMORPH: |
|
|
1490 | #ifdef NO_POLYMORPH |
|
|
1491 | /* Not great, but at least provide feedback so if players do have |
|
|
1492 | * polymorph (ie, find it as a preset item or left over from before |
|
|
1493 | * it was disabled), they get some feedback. |
|
|
1494 | */ |
|
|
1495 | new_draw_info (NDI_UNIQUE, 0, op, "The spell fizzles"); |
|
|
1496 | success = 0; |
|
|
1497 | #else |
|
|
1498 | success = cast_polymorph (op, caster, spell_ob, dir); |
|
|
1499 | #endif |
|
|
1500 | break; |
|
|
1501 | |
|
|
1502 | case SP_ALCHEMY: |
|
|
1503 | success = alchemy (op, caster, spell_ob); |
|
|
1504 | break; |
|
|
1505 | |
|
|
1506 | case SP_REMOVE_CURSE: |
|
|
1507 | success = remove_curse (op, caster, spell_ob); |
|
|
1508 | break; |
|
|
1509 | |
|
|
1510 | case SP_IDENTIFY: |
|
|
1511 | success = cast_identify (op, caster, spell_ob); |
|
|
1512 | break; |
|
|
1513 | |
|
|
1514 | case SP_DETECTION: |
|
|
1515 | success = cast_detection (op, caster, spell_ob, skill); |
|
|
1516 | break; |
|
|
1517 | |
|
|
1518 | case SP_MOOD_CHANGE: |
|
|
1519 | success = mood_change (op, caster, spell_ob); |
|
|
1520 | break; |
|
|
1521 | |
|
|
1522 | case SP_MOVING_BALL: |
|
|
1523 | if (spell_ob->path_repelled && (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) |
|
|
1524 | { |
|
|
1525 | new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the proper attunement to cast %s", &spell_ob->name); |
|
|
1526 | success = 0; |
|
|
1527 | } |
|
|
1528 | else |
|
|
1529 | success = fire_arch_from_position (op, caster, op->x + freearr_x[dir], op->y + freearr_y[dir], dir, spell_ob); |
|
|
1530 | break; |
|
|
1531 | |
|
|
1532 | case SP_SWARM: |
1525 | case SP_SWARM: |
1533 | success = fire_swarm (op, caster, spell_ob, dir); |
1526 | success = fire_swarm (op, caster, spell_ob, dir); |
1534 | break; |
1527 | break; |
1535 | |
1528 | |
1536 | case SP_CHANGE_MANA: |
1529 | case SP_CHANGE_MANA: |
1537 | success = cast_transfer (op, caster, spell_ob, dir); |
1530 | success = cast_transfer (op, caster, spell_ob, dir); |
1538 | break; |
1531 | break; |
1539 | |
1532 | |
1540 | case SP_DISPEL_RUNE: |
1533 | case SP_DISPEL_RUNE: |
1541 | /* in rune.c */ |
1534 | /* in rune.c */ |
1542 | success = dispel_rune (op, caster, spell_ob, skill, dir); |
1535 | success = dispel_rune (op, caster, spell_ob, skill, dir); |
1543 | break; |
1536 | break; |
1544 | |
1537 | |
1545 | case SP_CREATE_MISSILE: |
1538 | case SP_CREATE_MISSILE: |
1546 | success = cast_create_missile (op, caster, spell_ob, dir, stringarg); |
1539 | success = cast_create_missile (op, caster, spell_ob, dir, stringarg); |
1547 | break; |
1540 | break; |
1548 | |
1541 | |
1549 | case SP_CONSECRATE: |
1542 | case SP_CONSECRATE: |
1550 | success = cast_consecrate (op, caster, spell_ob); |
1543 | success = cast_consecrate (op, caster, spell_ob); |
1551 | break; |
1544 | break; |
1552 | |
1545 | |
1553 | case SP_ANIMATE_WEAPON: |
1546 | case SP_ANIMATE_WEAPON: |
1554 | success = animate_weapon (op, caster, spell_ob, dir); |
1547 | success = animate_weapon (op, caster, spell_ob, dir); |
1555 | old_shoottype = range_golem; |
1548 | old_shoottype = range_golem; |
1556 | break; |
1549 | break; |
1557 | |
1550 | |
1558 | case SP_LIGHT: |
1551 | case SP_LIGHT: |
1559 | success = cast_light (op, caster, spell_ob, dir); |
1552 | success = cast_light (op, caster, spell_ob, dir); |
1560 | break; |
1553 | break; |
1561 | |
1554 | |
1562 | case SP_CHANGE_MAP_LIGHT: |
1555 | case SP_CHANGE_MAP_LIGHT: |
1563 | success = cast_change_map_lightlevel (op, caster, spell_ob); |
1556 | success = cast_change_map_lightlevel (op, caster, spell_ob); |
1564 | break; |
1557 | break; |
1565 | |
1558 | |
1566 | case SP_FAERY_FIRE: |
1559 | case SP_FAERY_FIRE: |
1567 | success = cast_destruction (op, caster, spell_ob); |
1560 | success = cast_destruction (op, caster, spell_ob); |
1568 | break; |
1561 | break; |
1569 | |
1562 | |
1570 | case SP_CAUSE_DISEASE: |
1563 | case SP_CAUSE_DISEASE: |
1571 | success = cast_cause_disease (op, caster, spell_ob, dir); |
1564 | success = cast_cause_disease (op, caster, spell_ob, dir); |
1572 | break; |
1565 | break; |
1573 | |
1566 | |
1574 | case SP_AURA: |
1567 | case SP_AURA: |
1575 | success = create_aura (op, caster, spell_ob); |
1568 | success = create_aura (op, caster, spell_ob); |
1576 | break; |
1569 | break; |
1577 | |
1570 | |
1578 | case SP_TOWN_PORTAL: |
1571 | case SP_TOWN_PORTAL: |
1579 | success = cast_create_town_portal (op, caster, spell_ob, dir); |
1572 | success = cast_create_town_portal (op, caster, spell_ob, dir); |
1580 | break; |
1573 | break; |
1581 | |
1574 | |
1582 | case SP_PARTY_SPELL: |
1575 | case SP_PARTY_SPELL: |
1583 | success = cast_party_spell (op, caster, dir, spell_ob, stringarg); |
1576 | success = cast_party_spell (op, caster, dir, spell_ob, stringarg); |
1584 | break; |
1577 | break; |
1585 | |
1578 | |
1586 | default: |
1579 | default: |
1587 | if (!INVOKE_OBJECT (CAST_SPELL, spell_ob, ARG_OBJECT (op), ARG_OBJECT (caster), ARG_INT (dir), ARG_STRING (stringarg))) |
1580 | if (!INVOKE_OBJECT (CAST_SPELL, spell_ob, ARG_OBJECT (op), ARG_OBJECT (caster), ARG_INT (dir), ARG_STRING (stringarg))) |
1588 | LOG (llevError, "cast_spell: Unhandled spell subtype %d\n", spell_ob->subtype); |
1581 | LOG (llevError, "cast_spell: Unhandled spell subtype %d\n", spell_ob->subtype); |
1589 | |
|
|
1590 | |
|
|
1591 | } |
1582 | } |
1592 | |
1583 | |
1593 | /* FIXME - we need some better sound suppport */ |
1584 | /* FIXME - we need some better sound suppport */ |
1594 | // yes, for example, augment map info with the spell effect |
1585 | // yes, for example, augment map info with the spell effect |
1595 | // so clients can calculate the sounds themselves |
1586 | // so clients can calculate the sounds themselves |
… | |
… | |
1617 | * then dispatches them to the appropriate specific routines. |
1608 | * then dispatches them to the appropriate specific routines. |
1618 | */ |
1609 | */ |
1619 | void |
1610 | void |
1620 | move_spell_effect (object *op) |
1611 | move_spell_effect (object *op) |
1621 | { |
1612 | { |
1622 | |
|
|
1623 | switch (op->subtype) |
1613 | switch (op->subtype) |
1624 | { |
1614 | { |
1625 | case SP_BOLT: |
1615 | case SP_BOLT: |
1626 | move_bolt (op); |
1616 | move_bolt (op); |
1627 | break; |
1617 | break; |
1628 | |
1618 | |
1629 | case SP_BULLET: |
1619 | case SP_BULLET: |
1630 | move_bullet (op); |
1620 | move_bullet (op); |
1631 | break; |
1621 | break; |
1632 | |
1622 | |
1633 | case SP_EXPLOSION: |
1623 | case SP_EXPLOSION: |
1634 | explosion (op); |
1624 | explosion (op); |
1635 | break; |
1625 | break; |
1636 | |
1626 | |
1637 | case SP_CONE: |
1627 | case SP_CONE: |
1638 | move_cone (op); |
1628 | move_cone (op); |
1639 | break; |
1629 | break; |
1640 | |
1630 | |
1641 | case SP_BOMB: |
1631 | case SP_BOMB: |
1642 | animate_bomb (op); |
1632 | animate_bomb (op); |
1643 | break; |
1633 | break; |
1644 | |
1634 | |
1645 | case SP_MAGIC_MISSILE: |
1635 | case SP_MAGIC_MISSILE: |
1646 | move_missile (op); |
1636 | move_missile (op); |
1647 | break; |
1637 | break; |
1648 | |
1638 | |
1649 | case SP_WORD_OF_RECALL: |
1639 | case SP_WORD_OF_RECALL: |
1650 | execute_word_of_recall (op); |
1640 | execute_word_of_recall (op); |
1651 | break; |
1641 | break; |
1652 | |
1642 | |
1653 | case SP_MOVING_BALL: |
1643 | case SP_MOVING_BALL: |
1654 | move_ball_spell (op); |
1644 | move_ball_spell (op); |
1655 | break; |
1645 | break; |
1656 | |
1646 | |
1657 | case SP_SWARM: |
1647 | case SP_SWARM: |
1658 | move_swarm_spell (op); |
1648 | move_swarm_spell (op); |
1659 | break; |
1649 | break; |
1660 | |
1650 | |
1661 | case SP_AURA: |
1651 | case SP_AURA: |
1662 | move_aura (op); |
1652 | move_aura (op); |
1663 | break; |
1653 | break; |
1664 | |
|
|
1665 | } |
1654 | } |
1666 | } |
1655 | } |
1667 | |
1656 | |
1668 | /* this checks to see if something special should happen if |
1657 | /* this checks to see if something special should happen if |
1669 | * something runs into the object. |
1658 | * something runs into the object. |
1670 | */ |
1659 | */ |
1671 | void |
1660 | void |
1672 | check_spell_effect (object *op) |
1661 | check_spell_effect (object *op) |
1673 | { |
1662 | { |
1674 | |
|
|
1675 | switch (op->subtype) |
1663 | switch (op->subtype) |
1676 | { |
1664 | { |
1677 | case SP_BOLT: |
1665 | case SP_BOLT: |
1678 | move_bolt (op); |
1666 | move_bolt (op); |
1679 | return; |
1667 | return; |
1680 | |
1668 | |
1681 | case SP_BULLET: |
1669 | case SP_BULLET: |
1682 | check_bullet (op); |
1670 | check_bullet (op); |
1683 | return; |
1671 | return; |
1684 | } |
1672 | } |
1685 | |
|
|
1686 | } |
1673 | } |
1687 | |
1674 | |
1688 | /* This is called by move_apply. Basically, if someone |
1675 | /* This is called by move_apply. Basically, if someone |
1689 | * moves onto a spell effect and the walk_on or fly_on flags |
1676 | * moves onto a spell effect and the walk_on or fly_on flags |
1690 | * are set, this is called. This should only be called for |
1677 | * are set, this is called. This should only be called for |
… | |
… | |
1693 | void |
1680 | void |
1694 | apply_spell_effect (object *spell, object *victim) |
1681 | apply_spell_effect (object *spell, object *victim) |
1695 | { |
1682 | { |
1696 | switch (spell->subtype) |
1683 | switch (spell->subtype) |
1697 | { |
1684 | { |
1698 | case SP_CONE: |
1685 | case SP_CONE: |
1699 | if (QUERY_FLAG (victim, FLAG_ALIVE) && spell->speed && spell->attacktype) |
1686 | if (QUERY_FLAG (victim, FLAG_ALIVE) && spell->speed && spell->attacktype) |
1700 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 0); |
1687 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 0); |
1701 | break; |
1688 | break; |
1702 | |
1689 | |
1703 | case SP_MAGIC_MISSILE: |
1690 | case SP_MAGIC_MISSILE: |
1704 | if (QUERY_FLAG (victim, FLAG_ALIVE)) |
1691 | if (QUERY_FLAG (victim, FLAG_ALIVE)) |
1705 | { |
1692 | { |
1706 | tag_t spell_tag = spell->count; |
|
|
1707 | |
|
|
1708 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1); |
|
|
1709 | if (!was_destroyed (spell, spell_tag)) |
|
|
1710 | { |
|
|
1711 | remove_ob (spell); |
|
|
1712 | free_object (spell); |
|
|
1713 | } |
|
|
1714 | } |
|
|
1715 | break; |
|
|
1716 | |
|
|
1717 | case SP_MOVING_BALL: |
|
|
1718 | if (QUERY_FLAG (victim, FLAG_ALIVE)) |
|
|
1719 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1); |
1693 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1); |
|
|
1694 | |
|
|
1695 | if (!spell->destroyed ()) |
|
|
1696 | { |
|
|
1697 | remove_ob (spell); |
|
|
1698 | free_object (spell); |
|
|
1699 | } |
|
|
1700 | } |
|
|
1701 | break; |
|
|
1702 | |
|
|
1703 | case SP_MOVING_BALL: |
|
|
1704 | if (QUERY_FLAG (victim, FLAG_ALIVE)) |
|
|
1705 | hit_player (victim, spell->stats.dam, spell, spell->attacktype, 1); |
1720 | else if (victim->material || victim->materialname) |
1706 | else if (victim->material || victim->materialname) |
1721 | save_throw_object (victim, spell->attacktype, spell); |
1707 | save_throw_object (victim, spell->attacktype, spell); |
1722 | break; |
1708 | break; |
1723 | } |
1709 | } |
1724 | } |
1710 | } |