1 | /* |
1 | /* |
2 | * static char *rcsid_spell_util_c = |
2 | * static char *rcsid_spell_util_c = |
3 | * "$Id: spell_util.c,v 1.10 2006/08/02 17:26:29 elmex 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 |
… | |
… | |
1019 | */ |
1019 | */ |
1020 | |
1020 | |
1021 | 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) { |
1022 | |
1022 | |
1023 | const char *godname; |
1023 | const char *godname; |
1024 | int success=0,mflags, cast_level=0, old_shoottype; |
1024 | int success=0,mflags, cast_level=0, old_shoottype, ev = 0; |
1025 | object *skill=NULL; |
1025 | object *skill=NULL; |
1026 | |
1026 | |
1027 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
1027 | old_shoottype = op->contr ? op->contr->shoottype : 0; |
1028 | |
1028 | |
1029 | if (!spell_ob) { |
1029 | if (!spell_ob) { |
… | |
… | |
1219 | return 0; |
1219 | return 0; |
1220 | } |
1220 | } |
1221 | change_skill(op, skill, 0); /* needed for proper exp credit */ |
1221 | change_skill(op, skill, 0); /* needed for proper exp credit */ |
1222 | } |
1222 | } |
1223 | |
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) |
1224 | switch(spell_ob->subtype) { |
1240 | switch(spell_ob->subtype) |
|
|
1241 | { |
1225 | /* 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 |
1226 | * in in spells.h. |
1243 | * in in spells.h. |
1227 | */ |
1244 | */ |
1228 | case SP_RAISE_DEAD: |
1245 | case SP_RAISE_DEAD: |
1229 | success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); |
1246 | success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); |
1230 | break; |
1247 | break; |
1231 | |
1248 | |
1232 | case SP_RUNE: |
1249 | case SP_RUNE: |
1233 | success = write_rune(op,caster, spell_ob, dir,stringarg); |
1250 | success = write_rune(op,caster, spell_ob, dir,stringarg); |
1234 | break; |
1251 | break; |
1235 | |
1252 | |
1236 | case SP_MAKE_MARK: |
1253 | case SP_MAKE_MARK: |
1237 | success = write_mark(op, spell_ob, stringarg); |
1254 | success = write_mark(op, spell_ob, stringarg); |
1238 | break; |
1255 | break; |
1239 | |
1256 | |
1240 | case SP_BOLT: |
1257 | case SP_BOLT: |
1241 | success = fire_bolt(op,caster,dir,spell_ob,skill); |
1258 | success = fire_bolt(op,caster,dir,spell_ob,skill); |
1242 | break; |
1259 | break; |
1243 | |
1260 | |
1244 | case SP_BULLET: |
1261 | case SP_BULLET: |
1245 | success = fire_bullet(op, caster, dir, spell_ob); |
1262 | success = fire_bullet(op, caster, dir, spell_ob); |
1246 | break; |
1263 | break; |
1247 | |
1264 | |
1248 | case SP_CONE: |
1265 | case SP_CONE: |
1249 | success = cast_cone(op, caster, dir, spell_ob); |
1266 | success = cast_cone(op, caster, dir, spell_ob); |
1250 | break; |
1267 | break; |
1251 | |
1268 | |
1252 | case SP_BOMB: |
1269 | case SP_BOMB: |
1253 | success = create_bomb(op,caster,dir, spell_ob); |
1270 | success = create_bomb(op,caster,dir, spell_ob); |
1254 | break; |
1271 | break; |
1255 | |
1272 | |
1256 | case SP_WONDER: |
1273 | case SP_WONDER: |
1257 | success = cast_wonder(op,caster, dir,spell_ob); |
1274 | success = cast_wonder(op,caster, dir,spell_ob); |
1258 | break; |
1275 | break; |
1259 | |
1276 | |
1260 | case SP_SMITE: |
1277 | case SP_SMITE: |
1261 | success = cast_smite_spell(op,caster, dir,spell_ob); |
1278 | success = cast_smite_spell(op,caster, dir,spell_ob); |
1262 | break; |
1279 | break; |
1263 | |
1280 | |
1264 | case SP_MAGIC_MISSILE: |
1281 | case SP_MAGIC_MISSILE: |
1265 | 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], |
1266 | op->y + freearr_y[dir], dir, spell_ob); |
1283 | op->y + freearr_y[dir], dir, spell_ob); |
1267 | break; |
1284 | break; |
1268 | |
1285 | |
1269 | case SP_SUMMON_GOLEM: |
1286 | case SP_SUMMON_GOLEM: |
1270 | success = summon_golem(op, caster, dir, spell_ob); |
1287 | success = summon_golem(op, caster, dir, spell_ob); |
1271 | old_shoottype = range_golem; |
1288 | old_shoottype = range_golem; |
1272 | break; |
1289 | break; |
1273 | |
1290 | |
1274 | case SP_DIMENSION_DOOR: |
1291 | case SP_DIMENSION_DOOR: |
1275 | /* dimension door needs the actual caster, because that is what is |
1292 | /* dimension door needs the actual caster, because that is what is |
1276 | * moved. |
1293 | * moved. |
1277 | */ |
1294 | */ |
1278 | success = dimension_door(op,caster, spell_ob, dir); |
1295 | success = dimension_door(op,caster, spell_ob, dir); |
1279 | break; |
1296 | break; |
1280 | |
1297 | |
1281 | case SP_MAGIC_MAPPING: |
1298 | case SP_MAGIC_MAPPING: |
1282 | if(op->type==PLAYER) { |
1299 | if(op->type==PLAYER) { |
1283 | spell_effect(spell_ob, op->x, op->y, op->map, op); |
1300 | spell_effect(spell_ob, op->x, op->y, op->map, op); |
1284 | draw_magic_map(op); |
1301 | draw_magic_map(op); |
1285 | success=1; |
1302 | success=1; |
1286 | } |
1303 | } |
1287 | else success=0; |
1304 | else success=0; |
1288 | break; |
1305 | break; |
1289 | |
1306 | |
1290 | case SP_MAGIC_WALL: |
1307 | case SP_MAGIC_WALL: |
1291 | success = magic_wall(op,caster,dir,spell_ob); |
1308 | success = magic_wall(op,caster,dir,spell_ob); |
1292 | break; |
1309 | break; |
1293 | |
1310 | |
1294 | case SP_DESTRUCTION: |
1311 | case SP_DESTRUCTION: |
1295 | success = cast_destruction(op,caster,spell_ob); |
1312 | success = cast_destruction(op,caster,spell_ob); |
1296 | break; |
1313 | break; |
1297 | |
1314 | |
1298 | case SP_PERCEIVE_SELF: |
1315 | case SP_PERCEIVE_SELF: |
1299 | success = perceive_self(op); |
1316 | success = perceive_self(op); |
1300 | break; |
1317 | break; |
1301 | |
1318 | |
1302 | case SP_WORD_OF_RECALL: |
1319 | case SP_WORD_OF_RECALL: |
1303 | success = cast_word_of_recall(op,caster,spell_ob); |
1320 | success = cast_word_of_recall(op,caster,spell_ob); |
1304 | break; |
1321 | break; |
1305 | |
1322 | |
1306 | case SP_INVISIBLE: |
1323 | case SP_INVISIBLE: |
1307 | success = cast_invisible(op,caster,spell_ob); |
1324 | success = cast_invisible(op,caster,spell_ob); |
1308 | break; |
1325 | break; |
1309 | |
1326 | |
1310 | case SP_PROBE: |
1327 | case SP_PROBE: |
1311 | success = probe(op,caster, spell_ob, dir); |
1328 | success = probe(op,caster, spell_ob, dir); |
1312 | break; |
1329 | break; |
1313 | |
1330 | |
1314 | case SP_HEALING: |
1331 | case SP_HEALING: |
1315 | success = cast_heal(op,caster, spell_ob, dir); |
1332 | success = cast_heal(op,caster, spell_ob, dir); |
1316 | break; |
1333 | break; |
1317 | |
1334 | |
1318 | case SP_CREATE_FOOD: |
1335 | case SP_CREATE_FOOD: |
1319 | success = cast_create_food(op,caster,spell_ob, dir,stringarg); |
1336 | success = cast_create_food(op,caster,spell_ob, dir,stringarg); |
1320 | break; |
1337 | break; |
1321 | |
1338 | |
1322 | case SP_EARTH_TO_DUST: |
1339 | case SP_EARTH_TO_DUST: |
1323 | success = cast_earth_to_dust(op,caster,spell_ob); |
1340 | success = cast_earth_to_dust(op,caster,spell_ob); |
1324 | break; |
1341 | break; |
1325 | |
1342 | |
1326 | case SP_CHANGE_ABILITY: |
1343 | case SP_CHANGE_ABILITY: |
1327 | success = cast_change_ability(op,caster,spell_ob, dir, 0); |
1344 | success = cast_change_ability(op,caster,spell_ob, dir, 0); |
1328 | break; |
1345 | break; |
1329 | |
1346 | |
1330 | case SP_BLESS: |
1347 | case SP_BLESS: |
1331 | success = cast_bless(op,caster,spell_ob, dir); |
1348 | success = cast_bless(op,caster,spell_ob, dir); |
1332 | break; |
1349 | break; |
1333 | |
1350 | |
1334 | case SP_CURSE: |
1351 | case SP_CURSE: |
1335 | success = cast_curse(op,caster,spell_ob, dir); |
1352 | success = cast_curse(op,caster,spell_ob, dir); |
1336 | break; |
1353 | break; |
1337 | |
1354 | |
1338 | case SP_SUMMON_MONSTER: |
1355 | case SP_SUMMON_MONSTER: |
1339 | success = summon_object(op,caster,spell_ob, dir,stringarg); |
1356 | success = summon_object(op,caster,spell_ob, dir,stringarg); |
1340 | break; |
1357 | break; |
1341 | |
1358 | |
1342 | case SP_CHARGING: |
1359 | case SP_CHARGING: |
1343 | success = recharge(op, caster, spell_ob); |
1360 | success = recharge(op, caster, spell_ob); |
1344 | break; |
1361 | break; |
1345 | |
1362 | |
1346 | case SP_POLYMORPH: |
1363 | case SP_POLYMORPH: |
1347 | #ifdef NO_POLYMORPH |
1364 | #ifdef NO_POLYMORPH |
1348 | /* 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 |
1349 | * 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 |
1350 | * it was disabled), they get some feedback. |
1367 | * it was disabled), they get some feedback. |
1351 | */ |
1368 | */ |
1352 | new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); |
1369 | new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); |
1353 | success = 0; |
1370 | success = 0; |
1354 | #else |
1371 | #else |
1355 | success = cast_polymorph(op,caster,spell_ob, dir); |
1372 | success = cast_polymorph(op,caster,spell_ob, dir); |
1356 | #endif |
1373 | #endif |
1357 | break; |
1374 | break; |
1358 | |
1375 | |
1359 | case SP_ALCHEMY: |
1376 | case SP_ALCHEMY: |
1360 | success = alchemy(op, caster, spell_ob); |
1377 | success = alchemy(op, caster, spell_ob); |
1361 | break; |
1378 | break; |
1362 | |
1379 | |
1363 | case SP_REMOVE_CURSE: |
1380 | case SP_REMOVE_CURSE: |
1364 | success = remove_curse(op, caster, spell_ob); |
1381 | success = remove_curse(op, caster, spell_ob); |
1365 | break; |
1382 | break; |
1366 | |
1383 | |
1367 | case SP_IDENTIFY: |
1384 | case SP_IDENTIFY: |
1368 | success = cast_identify(op, caster, spell_ob); |
1385 | success = cast_identify(op, caster, spell_ob); |
1369 | break; |
1386 | break; |
1370 | |
1387 | |
1371 | case SP_DETECTION: |
1388 | case SP_DETECTION: |
1372 | success = cast_detection(op, caster, spell_ob, skill); |
1389 | success = cast_detection(op, caster, spell_ob, skill); |
1373 | break; |
1390 | break; |
1374 | |
1391 | |
1375 | case SP_MOOD_CHANGE: |
1392 | case SP_MOOD_CHANGE: |
1376 | success = mood_change(op, caster, spell_ob); |
1393 | success = mood_change(op, caster, spell_ob); |
1377 | break; |
1394 | break; |
1378 | |
1395 | |
1379 | case SP_MOVING_BALL: |
1396 | case SP_MOVING_BALL: |
1380 | if (spell_ob->path_repelled && |
1397 | if (spell_ob->path_repelled && |
1381 | (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { |
1398 | (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { |
1382 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1399 | new_draw_info_format(NDI_UNIQUE, 0, op, |
1383 | "You lack the proper attunement to cast %s", spell_ob->name); |
1400 | "You lack the proper attunement to cast %s", spell_ob->name); |
1384 | success = 0; |
1401 | success = 0; |
1385 | } else |
1402 | } else |
1386 | success = fire_arch_from_position(op,caster, |
1403 | success = fire_arch_from_position(op,caster, |
1387 | op->x + freearr_x[dir], op->y + freearr_y[dir], |
1404 | op->x + freearr_x[dir], op->y + freearr_y[dir], |
1388 | dir, spell_ob); |
1405 | dir, spell_ob); |
1389 | break; |
1406 | break; |
1390 | |
1407 | |
1391 | case SP_SWARM: |
1408 | case SP_SWARM: |
1392 | success = fire_swarm(op, caster, spell_ob, dir); |
1409 | success = fire_swarm(op, caster, spell_ob, dir); |
1393 | break; |
1410 | break; |
1394 | |
1411 | |
1395 | case SP_CHANGE_MANA: |
1412 | case SP_CHANGE_MANA: |
1396 | success = cast_transfer(op,caster, spell_ob, dir); |
1413 | success = cast_transfer(op,caster, spell_ob, dir); |
1397 | break; |
1414 | break; |
1398 | |
1415 | |
1399 | case SP_DISPEL_RUNE: |
1416 | case SP_DISPEL_RUNE: |
1400 | /* in rune.c */ |
1417 | /* in rune.c */ |
1401 | success = dispel_rune(op,caster, spell_ob, skill, dir); |
1418 | success = dispel_rune(op,caster, spell_ob, skill, dir); |
1402 | break; |
1419 | break; |
1403 | |
1420 | |
1404 | case SP_CREATE_MISSILE: |
1421 | case SP_CREATE_MISSILE: |
1405 | success = cast_create_missile(op,caster,spell_ob, dir,stringarg); |
1422 | success = cast_create_missile(op,caster,spell_ob, dir,stringarg); |
1406 | break; |
1423 | break; |
1407 | |
1424 | |
1408 | case SP_CONSECRATE: |
1425 | case SP_CONSECRATE: |
1409 | success = cast_consecrate(op, caster, spell_ob); |
1426 | success = cast_consecrate(op, caster, spell_ob); |
1410 | break; |
1427 | break; |
1411 | |
1428 | |
1412 | case SP_ANIMATE_WEAPON: |
1429 | case SP_ANIMATE_WEAPON: |
1413 | success = animate_weapon(op, caster, spell_ob, dir); |
1430 | success = animate_weapon(op, caster, spell_ob, dir); |
1414 | old_shoottype = range_golem; |
1431 | old_shoottype = range_golem; |
1415 | break; |
1432 | break; |
1416 | |
1433 | |
1417 | case SP_LIGHT: |
1434 | case SP_LIGHT: |
1418 | success = cast_light(op, caster, spell_ob, dir); |
1435 | success = cast_light(op, caster, spell_ob, dir); |
1419 | break; |
1436 | break; |
1420 | |
1437 | |
1421 | case SP_CHANGE_MAP_LIGHT: |
1438 | case SP_CHANGE_MAP_LIGHT: |
1422 | success = cast_change_map_lightlevel(op, caster, spell_ob); |
1439 | success = cast_change_map_lightlevel(op, caster, spell_ob); |
1423 | break; |
1440 | break; |
1424 | |
1441 | |
1425 | case SP_FAERY_FIRE: |
1442 | case SP_FAERY_FIRE: |
1426 | success = cast_destruction(op,caster,spell_ob); |
1443 | success = cast_destruction(op,caster,spell_ob); |
1427 | break; |
1444 | break; |
1428 | |
1445 | |
1429 | case SP_CAUSE_DISEASE: |
1446 | case SP_CAUSE_DISEASE: |
1430 | success = cast_cause_disease(op, caster, spell_ob, dir); |
1447 | success = cast_cause_disease(op, caster, spell_ob, dir); |
1431 | break; |
1448 | break; |
1432 | |
1449 | |
1433 | case SP_AURA: |
1450 | case SP_AURA: |
1434 | success = create_aura(op, caster, spell_ob); |
1451 | success = create_aura(op, caster, spell_ob); |
1435 | break; |
1452 | break; |
1436 | |
1453 | |
1437 | case SP_TOWN_PORTAL: |
1454 | case SP_TOWN_PORTAL: |
1438 | success= cast_create_town_portal (op,caster,spell_ob, dir); |
1455 | success= cast_create_town_portal (op,caster,spell_ob, dir); |
1439 | break; |
1456 | break; |
1440 | |
1457 | |
1441 | case SP_PARTY_SPELL: |
1458 | case SP_PARTY_SPELL: |
1442 | success = cast_party_spell (op, caster, dir, spell_ob, stringarg); |
1459 | success = cast_party_spell (op, caster, dir, spell_ob, stringarg); |
1443 | break; |
1460 | break; |
1444 | |
1461 | |
1445 | default: |
1462 | default: |
1446 | LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", |
1463 | LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", |
1447 | spell_ob->subtype); |
1464 | spell_ob->subtype); |
1448 | |
1465 | |
1449 | |
1466 | |
1450 | } |
1467 | } |
1451 | |
1468 | |
1452 | /* FIXME - we need some better sound suppport */ |
1469 | /* FIXME - we need some better sound suppport */ |
1453 | // yes, for example, augment map info with the spell effect |
1470 | // yes, for example, augment map info with the spell effect |
1454 | // so clients can calculate the sounds themselves |
1471 | // so clients can calculate the sounds themselves |
1455 | //play_sound_map(op->map, op->x, op->y, SOUND_CAST_SPELL_0 + spell_ob->subtype); |
1472 | //play_sound_map(op->map, op->x, op->y, SOUND_CAST_SPELL_0 + spell_ob->subtype); |