1 | /* |
1 | /* |
2 | * static char *rcsid_spell_util_c = |
2 | * static char *rcsid_spell_util_c = |
3 | * "$Id: spell_util.c,v 1.1 2006/02/03 07:14:41 root Exp $"; |
3 | * "$Id: spell_util.c,v 1.11 2006/08/12 11:51:38 elmex 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 |
… | |
… | |
195 | * min_caster_level, so the difference is effectively 4 |
195 | * min_caster_level, so the difference is effectively 4 |
196 | */ |
196 | */ |
197 | |
197 | |
198 | int caster_level(object *caster, object *spell) |
198 | int caster_level(object *caster, object *spell) |
199 | { |
199 | { |
200 | int level= caster->level; |
200 | int level = caster->level; |
201 | |
201 | |
202 | /* If this is a player, try to find the matching skill */ |
202 | /* If this is a player, try to find the matching skill */ |
203 | if (caster->type == PLAYER && spell->skill) { |
203 | if (caster->type == PLAYER && spell->skill) { |
204 | int i; |
204 | int i; |
205 | |
205 | |
… | |
… | |
208 | caster->contr->last_skill_ob[i]->skill == spell->skill) { |
208 | caster->contr->last_skill_ob[i]->skill == spell->skill) { |
209 | level = caster->contr->last_skill_ob[i]->level; |
209 | level = caster->contr->last_skill_ob[i]->level; |
210 | break; |
210 | break; |
211 | } |
211 | } |
212 | } |
212 | } |
|
|
213 | |
|
|
214 | /* if a rod is fired by a player, take the use_magic_item skill in consideration. */ |
|
|
215 | if (caster->type == ROD && caster->env && caster->env->type == PLAYER) |
|
|
216 | { |
|
|
217 | object *skill = find_skill_by_number (caster->env, SK_USE_MAGIC_ITEM); |
|
|
218 | int sk_level = skill ? skill->level : 1; |
|
|
219 | level = MIN (level, sk_level + level / 10 + 1); |
|
|
220 | } |
|
|
221 | |
213 | /* Got valid caster level. Now adjust for attunement */ |
222 | /* Got valid caster level. Now adjust for attunement */ |
214 | level += ((caster->path_repelled & spell->path_attuned) ? -2 : 0) |
223 | level += ((caster->path_repelled & spell->path_attuned) ? -2 : 0) |
215 | + ((caster->path_attuned & spell->path_attuned) ? 2 : 0); |
224 | + ((caster->path_attuned & spell->path_attuned) ? 2 : 0); |
216 | |
225 | |
217 | /* Always make this at least 1. If this is zero, we get divide by zero |
226 | /* Always make this at least 1. If this is zero, we get divide by zero |
218 | * errors in various places. |
227 | * errors in various places. |
219 | */ |
228 | */ |
220 | if (level < 1) level =1; |
229 | if (level < 1) level = 1; |
221 | return level; |
230 | return level; |
222 | } |
231 | } |
223 | |
232 | |
224 | /* The following function scales the spellpoint cost of |
233 | /* The following function scales the spellpoint cost of |
225 | * a spell by it's increased effectiveness. Some of the |
234 | * a spell by it's increased effectiveness. Some of the |
… | |
… | |
453 | |
462 | |
454 | if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(mp, x, y))) return 0; |
463 | if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(mp, x, y))) return 0; |
455 | |
464 | |
456 | for(tmp=get_map_ob(mp,x,y);tmp!=NULL;tmp=tmp->above) { |
465 | for(tmp=get_map_ob(mp,x,y);tmp!=NULL;tmp=tmp->above) { |
457 | /* If there is a counterspell on the space, and this |
466 | /* If there is a counterspell on the space, and this |
458 | * object is using magic, don't progess. I believe we could |
467 | * object is using magic, don't progress. I believe we could |
459 | * leave this out and let in progress, and other areas of the code |
468 | * leave this out and let in progress, and other areas of the code |
460 | * will then remove it, but that would seem to to use more |
469 | * will then remove it, but that would seem to to use more |
461 | * resources, and may not work as well if a player is standing |
470 | * resources, and may not work as well if a player is standing |
462 | * on top of a counterwall spell (may hit the player before being |
471 | * on top of a counterwall spell (may hit the player before being |
463 | * removed.) On the other hand, it may be more dramatic for the |
472 | * removed.) On the other hand, it may be more dramatic for the |
… | |
… | |
473 | * limits one spell effect per space per spell. This is definately |
482 | * limits one spell effect per space per spell. This is definately |
474 | * needed for performance reasons, and just for playability I believe. |
483 | * needed for performance reasons, and just for playability I believe. |
475 | * there are no such things as multispaced spells right now, so |
484 | * there are no such things as multispaced spells right now, so |
476 | * we don't need to worry about the head. |
485 | * we don't need to worry about the head. |
477 | */ |
486 | */ |
478 | if ((tmp->stats.maxhp == op->stats.maxhp) && (tmp->type == op->type) && |
487 | if ((tmp->stats.maxhp == op->stats.maxhp) && (tmp->type == op->type) && |
479 | (tmp->subtype == op->subtype)) |
488 | (tmp->subtype == op->subtype)) |
480 | return 0; |
489 | return 0; |
|
|
490 | |
|
|
491 | /* |
|
|
492 | * Combine similar spell effects into one spell effect. Needed for |
|
|
493 | * performance reasons with meteor swarm and the like, but also for |
|
|
494 | * playability reasons. |
|
|
495 | */ |
|
|
496 | if (tmp->arch == op->arch |
|
|
497 | && tmp->type == op->type |
|
|
498 | && tmp->subtype == op->subtype |
|
|
499 | && tmp->owner == op->owner |
|
|
500 | && ((tmp->subtype == SP_EXPLOSION) |
|
|
501 | || (tmp->subtype == SP_CONE && tmp->stats.sp == op->stats.sp)) |
|
|
502 | ) { |
|
|
503 | tmp->stats.dam = MAX (tmp->stats.dam, op->stats.dam); |
|
|
504 | tmp->range = MAX (tmp->range, op->range); |
|
|
505 | tmp->duration = MAX (tmp->duration, op->duration); |
|
|
506 | return 0; |
|
|
507 | } |
481 | |
508 | |
482 | /* Perhaps we should also put checks in for no magic and unholy |
509 | /* Perhaps we should also put checks in for no magic and unholy |
483 | * ground to prevent it from moving along? |
510 | * ground to prevent it from moving along? |
484 | */ |
511 | */ |
485 | } |
512 | } |
… | |
… | |
598 | |
625 | |
599 | /* I don't really get this block - if op isn't a player or rune, |
626 | /* I don't really get this block - if op isn't a player or rune, |
600 | * we then make the owner of this object the target. |
627 | * we then make the owner of this object the target. |
601 | * The owner could very well be no where near op. |
628 | * The owner could very well be no where near op. |
602 | */ |
629 | */ |
603 | if(op->type!=PLAYER && op->type!=RUNE) { |
630 | if(op->type!=PLAYER && op->type!=RUNE) |
|
|
631 | { |
604 | tmp=get_owner(op); |
632 | tmp=get_owner(op); |
605 | /* If the owner does not exist, or is not a monster, than apply the spell |
633 | /* If the owner does not exist, or is not a monster, than apply the spell |
606 | * to the caster. |
634 | * to the caster. |
607 | */ |
635 | */ |
608 | if(!tmp || !QUERY_FLAG(tmp,FLAG_MONSTER)) tmp=op; |
636 | if(!tmp || !QUERY_FLAG(tmp,FLAG_MONSTER)) tmp=op; |
609 | } |
637 | } |
610 | else { |
638 | else |
611 | m = op->map; |
639 | { |
|
|
640 | m = op->map; |
612 | x = op->x+freearr_x[dir]; |
641 | x = op->x+freearr_x[dir]; |
613 | y = op->y+freearr_y[dir]; |
642 | y = op->y+freearr_y[dir]; |
614 | |
643 | |
615 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
644 | mflags = get_map_flags(m, &m, x, y, &x, &y); |
616 | |
645 | |
617 | if (mflags & P_OUT_OF_MAP) |
646 | if (mflags & P_OUT_OF_MAP) |
618 | tmp=NULL; |
647 | tmp=NULL; |
619 | else { |
648 | else |
|
|
649 | { |
620 | for(tmp=get_map_ob(m, x, y); tmp!=NULL; tmp=tmp->above) |
650 | for(tmp=get_map_ob(m, x, y); tmp!=NULL; tmp=tmp->above) |
621 | if(tmp->type==PLAYER) |
651 | { |
622 | break; |
652 | if(tmp->type==PLAYER) |
623 | } |
653 | break; |
|
|
654 | } |
|
|
655 | } |
624 | } |
656 | } |
625 | /* didn't find a player there, look in current square for a player */ |
657 | /* didn't find a player there, look in current square for a player */ |
626 | if(tmp==NULL) |
658 | if(tmp==NULL) |
627 | for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) |
659 | for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) |
|
|
660 | { |
628 | if(tmp->type==PLAYER) |
661 | if(tmp->type==PLAYER) |
629 | break; |
662 | break; |
|
|
663 | /* Don't forget to browse inside transports ! - gros 2006/07/25 */ |
|
|
664 | if(tmp->type==TRANSPORT) |
|
|
665 | { |
|
|
666 | object* inv; |
|
|
667 | for (inv=tmp->inv; inv; inv=inv->below) |
|
|
668 | { |
|
|
669 | if ((inv->type == PLAYER) && (op == inv)) |
|
|
670 | { |
|
|
671 | return inv; |
|
|
672 | } |
|
|
673 | } |
|
|
674 | } |
|
|
675 | } |
630 | return tmp; |
676 | return tmp; |
631 | } |
677 | } |
632 | |
678 | |
633 | |
679 | |
634 | |
680 | |
… | |
… | |
966 | * functions - it just blindly returns what ever value those functions |
1012 | * functions - it just blindly returns what ever value those functions |
967 | * return. So if your writing a new function that is called from this, |
1013 | * return. So if your writing a new function that is called from this, |
968 | * it shoudl also return 1 on success, 0 on failure. |
1014 | * it shoudl also return 1 on success, 0 on failure. |
969 | * |
1015 | * |
970 | * if it is a player casting the spell (op->type == PLAYER, op == caster), |
1016 | * if it is a player casting the spell (op->type == PLAYER, op == caster), |
971 | * this function will decrease teh mana/grace appropriately. For other |
1017 | * this function will decrease the mana/grace appropriately. For other |
972 | * objects, the caller should do what it considers appropriate. |
1018 | * objects, the caller should do what it considers appropriate. |
973 | */ |
1019 | */ |
974 | |
1020 | |
975 | int cast_spell(object *op, object *caster,int dir,object *spell_ob, char *stringarg) { |
1021 | int cast_spell(object *op, object *caster,int dir,object *spell_ob, char *stringarg) { |
976 | |
1022 | |
977 | const char *godname; |
1023 | const char *godname; |
978 | int success=0,mflags, cast_level=0, old_shoottype; |
1024 | int success=0,mflags, cast_level=0, old_shoottype, ev = 0; |
979 | object *skill=NULL; |
1025 | object *skill=NULL; |
980 | |
1026 | |
981 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
1027 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
982 | |
1028 | |
983 | if (!spell_ob) { |
1029 | if (!spell_ob) { |
… | |
… | |
1173 | return 0; |
1219 | return 0; |
1174 | } |
1220 | } |
1175 | change_skill(op, skill, 0); /* needed for proper exp credit */ |
1221 | change_skill(op, skill, 0); /* needed for proper exp credit */ |
1176 | } |
1222 | } |
1177 | |
1223 | |
|
|
1224 | /* elmex: FIXME: |
|
|
1225 | * This is a little bit hacky, i needed a special field in spell objects |
|
|
1226 | * to identify that it triggers EVENT_CAST_SPELL events. So that only special |
|
|
1227 | * spells call out into the plugin (which might be very slow). |
|
|
1228 | * I choose custom_name because it's set by the loader and a player can't modify it |
|
|
1229 | * on the spell object. |
|
|
1230 | * I would more like a simple flag... but that can be done later. |
|
|
1231 | */ |
|
|
1232 | LOG(llevError,"cast_spell: custom_name: %s\n", spell_ob->arch->clone.custom_name); |
|
|
1233 | if (spell_ob->arch->clone.custom_name) |
|
|
1234 | { |
|
|
1235 | ev = execute_global_event(EVENT_CAST_SPELL, op, caster, spell_ob, dir, stringarg ? stringarg : ""); |
|
|
1236 | LOG(llevError,"cast_spell: EVENT!!!!\n"); |
|
|
1237 | } |
|
|
1238 | |
|
|
1239 | if (!ev) |
1178 | switch(spell_ob->subtype) { |
1240 | switch(spell_ob->subtype) |
|
|
1241 | { |
1179 | /* The order of case statements is same as the order they show up |
1242 | /* The order of case statements is same as the order they show up |
1180 | * in in spells.h. |
1243 | * in in spells.h. |
1181 | */ |
1244 | */ |
1182 | case SP_RAISE_DEAD: |
1245 | case SP_RAISE_DEAD: |
1183 | success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); |
1246 | success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); |
1184 | break; |
1247 | break; |
1185 | |
1248 | |
1186 | case SP_RUNE: |
1249 | case SP_RUNE: |
1187 | success = write_rune(op,caster, spell_ob, dir,stringarg); |
1250 | success = write_rune(op,caster, spell_ob, dir,stringarg); |
1188 | break; |
1251 | break; |
1189 | |
1252 | |
1190 | case SP_MAKE_MARK: |
1253 | case SP_MAKE_MARK: |
1191 | success = write_mark(op, spell_ob, stringarg); |
1254 | success = write_mark(op, spell_ob, stringarg); |
1192 | break; |
1255 | break; |
1193 | |
1256 | |
1194 | case SP_BOLT: |
1257 | case SP_BOLT: |
1195 | success = fire_bolt(op,caster,dir,spell_ob,skill); |
1258 | success = fire_bolt(op,caster,dir,spell_ob,skill); |
1196 | break; |
1259 | break; |
1197 | |
1260 | |
1198 | case SP_BULLET: |
1261 | case SP_BULLET: |
1199 | success = fire_bullet(op, caster, dir, spell_ob); |
1262 | success = fire_bullet(op, caster, dir, spell_ob); |
1200 | break; |
1263 | break; |
1201 | |
1264 | |
1202 | case SP_CONE: |
1265 | case SP_CONE: |
1203 | success = cast_cone(op, caster, dir, spell_ob); |
1266 | success = cast_cone(op, caster, dir, spell_ob); |
1204 | break; |
1267 | break; |
1205 | |
1268 | |
1206 | case SP_BOMB: |
1269 | case SP_BOMB: |
1207 | success = create_bomb(op,caster,dir, spell_ob); |
1270 | success = create_bomb(op,caster,dir, spell_ob); |
1208 | break; |
1271 | break; |
1209 | |
1272 | |
1210 | case SP_WONDER: |
1273 | case SP_WONDER: |
1211 | success = cast_wonder(op,caster, dir,spell_ob); |
1274 | success = cast_wonder(op,caster, dir,spell_ob); |
1212 | break; |
1275 | break; |
1213 | |
1276 | |
1214 | case SP_SMITE: |
1277 | case SP_SMITE: |
1215 | success = cast_smite_spell(op,caster, dir,spell_ob); |
1278 | success = cast_smite_spell(op,caster, dir,spell_ob); |
1216 | break; |
1279 | break; |
1217 | |
1280 | |
1218 | case SP_MAGIC_MISSILE: |
1281 | case SP_MAGIC_MISSILE: |
1219 | success = fire_arch_from_position(op, caster, op->x + freearr_x[dir], |
1282 | success = fire_arch_from_position(op, caster, op->x + freearr_x[dir], |
1220 | op->y + freearr_y[dir], dir, spell_ob); |
1283 | op->y + freearr_y[dir], dir, spell_ob); |
1221 | break; |
1284 | break; |
1222 | |
1285 | |
1223 | case SP_SUMMON_GOLEM: |
1286 | case SP_SUMMON_GOLEM: |
1224 | success = summon_golem(op, caster, dir, spell_ob); |
1287 | success = summon_golem(op, caster, dir, spell_ob); |
1225 | old_shoottype = range_golem; |
1288 | old_shoottype = range_golem; |
1226 | break; |
1289 | break; |
1227 | |
1290 | |
1228 | case SP_DIMENSION_DOOR: |
1291 | case SP_DIMENSION_DOOR: |
1229 | /* dimension door needs the actual caster, because that is what is |
1292 | /* dimension door needs the actual caster, because that is what is |
1230 | * moved. |
1293 | * moved. |
1231 | */ |
1294 | */ |
1232 | success = dimension_door(op,caster, spell_ob, dir); |
1295 | success = dimension_door(op,caster, spell_ob, dir); |
1233 | break; |
1296 | break; |
1234 | |
1297 | |
1235 | case SP_MAGIC_MAPPING: |
1298 | case SP_MAGIC_MAPPING: |
1236 | if(op->type==PLAYER) { |
1299 | if(op->type==PLAYER) { |
1237 | spell_effect(spell_ob, op->x, op->y, op->map, op); |
1300 | spell_effect(spell_ob, op->x, op->y, op->map, op); |
1238 | draw_magic_map(op); |
1301 | draw_magic_map(op); |
1239 | success=1; |
1302 | success=1; |
1240 | } |
1303 | } |
1241 | else success=0; |
1304 | else success=0; |
1242 | break; |
1305 | break; |
1243 | |
1306 | |
1244 | case SP_MAGIC_WALL: |
1307 | case SP_MAGIC_WALL: |
1245 | success = magic_wall(op,caster,dir,spell_ob); |
1308 | success = magic_wall(op,caster,dir,spell_ob); |
1246 | break; |
1309 | break; |
1247 | |
1310 | |
1248 | case SP_DESTRUCTION: |
1311 | case SP_DESTRUCTION: |
1249 | success = cast_destruction(op,caster,spell_ob); |
1312 | success = cast_destruction(op,caster,spell_ob); |
1250 | break; |
1313 | break; |
1251 | |
1314 | |
1252 | case SP_PERCEIVE_SELF: |
1315 | case SP_PERCEIVE_SELF: |
1253 | success = perceive_self(op); |
1316 | success = perceive_self(op); |
1254 | break; |
1317 | break; |
1255 | |
1318 | |
1256 | case SP_WORD_OF_RECALL: |
1319 | case SP_WORD_OF_RECALL: |
1257 | success = cast_word_of_recall(op,caster,spell_ob); |
1320 | success = cast_word_of_recall(op,caster,spell_ob); |
1258 | break; |
1321 | break; |
1259 | |
1322 | |
1260 | case SP_INVISIBLE: |
1323 | case SP_INVISIBLE: |
1261 | success = cast_invisible(op,caster,spell_ob); |
1324 | success = cast_invisible(op,caster,spell_ob); |
1262 | break; |
1325 | break; |
1263 | |
1326 | |
1264 | case SP_PROBE: |
1327 | case SP_PROBE: |
1265 | success = probe(op,caster, spell_ob, dir); |
1328 | success = probe(op,caster, spell_ob, dir); |
1266 | break; |
1329 | break; |
1267 | |
1330 | |
1268 | case SP_HEALING: |
1331 | case SP_HEALING: |
1269 | success = cast_heal(op,caster, spell_ob, dir); |
1332 | success = cast_heal(op,caster, spell_ob, dir); |
1270 | break; |
1333 | break; |
1271 | |
1334 | |
1272 | case SP_CREATE_FOOD: |
1335 | case SP_CREATE_FOOD: |
1273 | success = cast_create_food(op,caster,spell_ob, dir,stringarg); |
1336 | success = cast_create_food(op,caster,spell_ob, dir,stringarg); |
1274 | break; |
1337 | break; |
1275 | |
1338 | |
1276 | case SP_EARTH_TO_DUST: |
1339 | case SP_EARTH_TO_DUST: |
1277 | success = cast_earth_to_dust(op,caster,spell_ob); |
1340 | success = cast_earth_to_dust(op,caster,spell_ob); |
1278 | break; |
1341 | break; |
1279 | |
1342 | |
1280 | case SP_CHANGE_ABILITY: |
1343 | case SP_CHANGE_ABILITY: |
1281 | success = cast_change_ability(op,caster,spell_ob, dir, 0); |
1344 | success = cast_change_ability(op,caster,spell_ob, dir, 0); |
1282 | break; |
1345 | break; |
1283 | |
1346 | |
1284 | case SP_BLESS: |
1347 | case SP_BLESS: |
1285 | success = cast_bless(op,caster,spell_ob, dir); |
1348 | success = cast_bless(op,caster,spell_ob, dir); |
1286 | break; |
1349 | break; |
1287 | |
1350 | |
1288 | case SP_CURSE: |
1351 | case SP_CURSE: |
1289 | success = cast_curse(op,caster,spell_ob, dir); |
1352 | success = cast_curse(op,caster,spell_ob, dir); |
1290 | break; |
1353 | break; |
1291 | |
1354 | |
1292 | case SP_SUMMON_MONSTER: |
1355 | case SP_SUMMON_MONSTER: |
1293 | success = summon_object(op,caster,spell_ob, dir,stringarg); |
1356 | success = summon_object(op,caster,spell_ob, dir,stringarg); |
1294 | break; |
1357 | break; |
1295 | |
1358 | |
1296 | case SP_CHARGING: |
1359 | case SP_CHARGING: |
1297 | success = recharge(op, caster, spell_ob); |
1360 | success = recharge(op, caster, spell_ob); |
1298 | break; |
1361 | break; |
1299 | |
1362 | |
1300 | case SP_POLYMORPH: |
1363 | case SP_POLYMORPH: |
1301 | #ifdef NO_POLYMORPH |
1364 | #ifdef NO_POLYMORPH |
1302 | /* Not great, but at least provide feedback so if players do have |
1365 | /* Not great, but at least provide feedback so if players do have |
1303 | * polymorph (ie, find it as a preset item or left over from before |
1366 | * polymorph (ie, find it as a preset item or left over from before |
1304 | * it was disabled), they get some feedback. |
1367 | * it was disabled), they get some feedback. |
1305 | */ |
1368 | */ |
1306 | new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); |
1369 | new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); |
1307 | success = 0; |
1370 | success = 0; |
1308 | #else |
1371 | #else |
1309 | success = cast_polymorph(op,caster,spell_ob, dir); |
1372 | success = cast_polymorph(op,caster,spell_ob, dir); |
1310 | #endif |
1373 | #endif |
1311 | break; |
1374 | break; |
1312 | |
1375 | |
1313 | case SP_ALCHEMY: |
1376 | case SP_ALCHEMY: |
1314 | success = alchemy(op, caster, spell_ob); |
1377 | success = alchemy(op, caster, spell_ob); |
1315 | break; |
1378 | break; |
1316 | |
1379 | |
1317 | case SP_REMOVE_CURSE: |
1380 | case SP_REMOVE_CURSE: |
1318 | success = remove_curse(op, caster, spell_ob); |
1381 | success = remove_curse(op, caster, spell_ob); |
1319 | break; |
1382 | break; |
1320 | |
1383 | |
1321 | case SP_IDENTIFY: |
1384 | case SP_IDENTIFY: |
1322 | success = cast_identify(op, caster, spell_ob); |
1385 | success = cast_identify(op, caster, spell_ob); |
1323 | break; |
1386 | break; |
1324 | |
1387 | |
1325 | case SP_DETECTION: |
1388 | case SP_DETECTION: |
1326 | success = cast_detection(op, caster, spell_ob, skill); |
1389 | success = cast_detection(op, caster, spell_ob, skill); |
1327 | break; |
1390 | break; |
1328 | |
1391 | |
1329 | case SP_MOOD_CHANGE: |
1392 | case SP_MOOD_CHANGE: |
1330 | success = mood_change(op, caster, spell_ob); |
1393 | success = mood_change(op, caster, spell_ob); |
1331 | break; |
1394 | break; |
1332 | |
1395 | |
1333 | case SP_MOVING_BALL: |
1396 | case SP_MOVING_BALL: |
1334 | if (spell_ob->path_repelled && |
1397 | if (spell_ob->path_repelled && |
1335 | (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { |
1398 | (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { |
1336 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1399 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1337 | "You lack the proper attunement to cast %s", spell_ob->name); |
1400 | "You lack the proper attunement to cast %s", spell_ob->name); |
1338 | success = 0; |
1401 | success = 0; |
1339 | } else |
1402 | } else |
1340 | success = fire_arch_from_position(op,caster, |
1403 | success = fire_arch_from_position(op,caster, |
1341 | op->x + freearr_x[dir], op->y + freearr_y[dir], |
1404 | op->x + freearr_x[dir], op->y + freearr_y[dir], |
1342 | dir, spell_ob); |
1405 | dir, spell_ob); |
1343 | break; |
1406 | break; |
1344 | |
1407 | |
1345 | case SP_SWARM: |
1408 | case SP_SWARM: |
1346 | success = fire_swarm(op, caster, spell_ob, dir); |
1409 | success = fire_swarm(op, caster, spell_ob, dir); |
1347 | break; |
1410 | break; |
1348 | |
1411 | |
1349 | case SP_CHANGE_MANA: |
1412 | case SP_CHANGE_MANA: |
1350 | success = cast_transfer(op,caster, spell_ob, dir); |
1413 | success = cast_transfer(op,caster, spell_ob, dir); |
1351 | break; |
1414 | break; |
1352 | |
1415 | |
1353 | case SP_DISPEL_RUNE: |
1416 | case SP_DISPEL_RUNE: |
1354 | /* in rune.c */ |
1417 | /* in rune.c */ |
1355 | success = dispel_rune(op,caster, spell_ob, skill, dir); |
1418 | success = dispel_rune(op,caster, spell_ob, skill, dir); |
1356 | break; |
1419 | break; |
1357 | |
1420 | |
1358 | case SP_CREATE_MISSILE: |
1421 | case SP_CREATE_MISSILE: |
1359 | success = cast_create_missile(op,caster,spell_ob, dir,stringarg); |
1422 | success = cast_create_missile(op,caster,spell_ob, dir,stringarg); |
1360 | break; |
1423 | break; |
1361 | |
1424 | |
1362 | case SP_CONSECRATE: |
1425 | case SP_CONSECRATE: |
1363 | success = cast_consecrate(op, caster, spell_ob); |
1426 | success = cast_consecrate(op, caster, spell_ob); |
1364 | break; |
1427 | break; |
1365 | |
1428 | |
1366 | case SP_ANIMATE_WEAPON: |
1429 | case SP_ANIMATE_WEAPON: |
1367 | success = animate_weapon(op, caster, spell_ob, dir); |
1430 | success = animate_weapon(op, caster, spell_ob, dir); |
1368 | old_shoottype = range_golem; |
1431 | old_shoottype = range_golem; |
1369 | break; |
1432 | break; |
1370 | |
1433 | |
1371 | case SP_LIGHT: |
1434 | case SP_LIGHT: |
1372 | success = cast_light(op, caster, spell_ob, dir); |
1435 | success = cast_light(op, caster, spell_ob, dir); |
1373 | break; |
1436 | break; |
1374 | |
1437 | |
1375 | case SP_CHANGE_MAP_LIGHT: |
1438 | case SP_CHANGE_MAP_LIGHT: |
1376 | success = cast_change_map_lightlevel(op, caster, spell_ob); |
1439 | success = cast_change_map_lightlevel(op, caster, spell_ob); |
1377 | break; |
1440 | break; |
1378 | |
1441 | |
1379 | case SP_FAERY_FIRE: |
1442 | case SP_FAERY_FIRE: |
1380 | success = cast_destruction(op,caster,spell_ob); |
1443 | success = cast_destruction(op,caster,spell_ob); |
1381 | break; |
1444 | break; |
1382 | |
1445 | |
1383 | case SP_CAUSE_DISEASE: |
1446 | case SP_CAUSE_DISEASE: |
1384 | success = cast_cause_disease(op, caster, spell_ob, dir); |
1447 | success = cast_cause_disease(op, caster, spell_ob, dir); |
1385 | break; |
1448 | break; |
1386 | |
1449 | |
1387 | case SP_AURA: |
1450 | case SP_AURA: |
1388 | success = create_aura(op, caster, spell_ob); |
1451 | success = create_aura(op, caster, spell_ob); |
1389 | break; |
1452 | break; |
1390 | |
1453 | |
1391 | case SP_TOWN_PORTAL: |
1454 | case SP_TOWN_PORTAL: |
1392 | success= cast_create_town_portal (op,caster,spell_ob, dir); |
1455 | success= cast_create_town_portal (op,caster,spell_ob, dir); |
1393 | break; |
1456 | break; |
1394 | |
1457 | |
1395 | case SP_PARTY_SPELL: |
1458 | case SP_PARTY_SPELL: |
1396 | success = cast_party_spell( op, caster, dir, spell_ob, stringarg ); |
1459 | success = cast_party_spell (op, caster, dir, spell_ob, stringarg); |
|
|
1460 | break; |
1397 | |
1461 | |
1398 | default: |
1462 | default: |
1399 | LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", |
1463 | LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", |
1400 | spell_ob->subtype); |
1464 | spell_ob->subtype); |
1401 | |
1465 | |
1402 | |
1466 | |
1403 | } |
1467 | } |
1404 | |
1468 | |
1405 | /* FIXME - we need some better sound suppport */ |
1469 | /* FIXME - we need some better sound suppport */ |
|
|
1470 | // yes, for example, augment map info with the spell effect |
|
|
1471 | // so clients can calculate the sounds themselves |
1406 | /* play_sound_map(op->map, op->x, op->y, SOUND_CAST_SPELL_0 + type);*/ |
1472 | //play_sound_map(op->map, op->x, op->y, SOUND_CAST_SPELL_0 + spell_ob->subtype); |
|
|
1473 | |
1407 | /* free the spell arg */ |
1474 | /* free the spell arg */ |
1408 | if(settings.casting_time == TRUE && stringarg) { |
1475 | if(settings.casting_time == TRUE && stringarg) { |
1409 | free(stringarg); |
1476 | free(stringarg); |
1410 | stringarg=NULL; |
1477 | stringarg=NULL; |
1411 | } |
1478 | } |