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

Comparing deliantra/server/server/spell_util.c (file contents):
Revision 1.4 by root, Mon Mar 13 23:59:29 2006 UTC vs.
Revision 1.11 by elmex, Sat Aug 12 11:51:38 2006 UTC

1/* 1/*
2 * static char *rcsid_spell_util_c = 2 * static char *rcsid_spell_util_c =
3 * "$Id: spell_util.c,v 1.4 2006/03/13 23:59:29 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
198int caster_level(object *caster, object *spell) 198int 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
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 487 if ((tmp->stats.maxhp == op->stats.maxhp) && (tmp->type == op->type) &&
479 && tmp->type == op->type
480 && tmp->subtype == op->subtype) 488 (tmp->subtype == op->subtype))
481 return 0; 489 return 0;
482 490
483 /* 491 /*
484 * Combine similar spell effects into one spell effect. Needed for 492 * Combine similar spell effects into one spell effect. Needed for
485 * performance reasons with meteor swarm and the like, but also for 493 * performance reasons with meteor swarm and the like, but also for
617 625
618 /* 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,
619 * we then make the owner of this object the target. 627 * we then make the owner of this object the target.
620 * The owner could very well be no where near op. 628 * The owner could very well be no where near op.
621 */ 629 */
622 if(op->type!=PLAYER && op->type!=RUNE) { 630 if(op->type!=PLAYER && op->type!=RUNE)
631 {
623 tmp=get_owner(op); 632 tmp=get_owner(op);
624 /* 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
625 * to the caster. 634 * to the caster.
626 */ 635 */
627 if(!tmp || !QUERY_FLAG(tmp,FLAG_MONSTER)) tmp=op; 636 if(!tmp || !QUERY_FLAG(tmp,FLAG_MONSTER)) tmp=op;
628 } 637 }
629 else { 638 else
630 m = op->map; 639 {
640 m = op->map;
631 x = op->x+freearr_x[dir]; 641 x = op->x+freearr_x[dir];
632 y = op->y+freearr_y[dir]; 642 y = op->y+freearr_y[dir];
633 643
634 mflags = get_map_flags(m, &m, x, y, &x, &y); 644 mflags = get_map_flags(m, &m, x, y, &x, &y);
635 645
636 if (mflags & P_OUT_OF_MAP) 646 if (mflags & P_OUT_OF_MAP)
637 tmp=NULL; 647 tmp=NULL;
638 else { 648 else
649 {
639 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)
640 if(tmp->type==PLAYER) 651 {
641 break; 652 if(tmp->type==PLAYER)
642 } 653 break;
654 }
655 }
643 } 656 }
644 /* 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 */
645 if(tmp==NULL) 658 if(tmp==NULL)
646 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 {
647 if(tmp->type==PLAYER) 661 if(tmp->type==PLAYER)
648 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 }
649 return tmp; 676 return tmp;
650} 677}
651 678
652 679
653 680
992 */ 1019 */
993 1020
994int cast_spell(object *op, object *caster,int dir,object *spell_ob, char *stringarg) { 1021int cast_spell(object *op, object *caster,int dir,object *spell_ob, char *stringarg) {
995 1022
996 const char *godname; 1023 const char *godname;
997 int success=0,mflags, cast_level=0, old_shoottype; 1024 int success=0,mflags, cast_level=0, old_shoottype, ev = 0;
998 object *skill=NULL; 1025 object *skill=NULL;
999 1026
1000 old_shoottype = op->contr ? op->contr->shoottype : 0; 1027 old_shoottype = op->contr ? op->contr->shoottype : 0;
1001 1028
1002 if (!spell_ob) { 1029 if (!spell_ob) {
1192 return 0; 1219 return 0;
1193 } 1220 }
1194 change_skill(op, skill, 0); /* needed for proper exp credit */ 1221 change_skill(op, skill, 0); /* needed for proper exp credit */
1195 } 1222 }
1196 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)
1197 switch(spell_ob->subtype) { 1240 switch(spell_ob->subtype)
1241 {
1198 /* 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
1199 * in in spells.h. 1243 * in in spells.h.
1200 */ 1244 */
1201 case SP_RAISE_DEAD: 1245 case SP_RAISE_DEAD:
1202 success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); 1246 success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg);
1203 break; 1247 break;
1204 1248
1205 case SP_RUNE: 1249 case SP_RUNE:
1206 success = write_rune(op,caster, spell_ob, dir,stringarg); 1250 success = write_rune(op,caster, spell_ob, dir,stringarg);
1207 break; 1251 break;
1208 1252
1209 case SP_MAKE_MARK: 1253 case SP_MAKE_MARK:
1210 success = write_mark(op, spell_ob, stringarg); 1254 success = write_mark(op, spell_ob, stringarg);
1211 break; 1255 break;
1212 1256
1213 case SP_BOLT: 1257 case SP_BOLT:
1214 success = fire_bolt(op,caster,dir,spell_ob,skill); 1258 success = fire_bolt(op,caster,dir,spell_ob,skill);
1215 break; 1259 break;
1216 1260
1217 case SP_BULLET: 1261 case SP_BULLET:
1218 success = fire_bullet(op, caster, dir, spell_ob); 1262 success = fire_bullet(op, caster, dir, spell_ob);
1219 break; 1263 break;
1220 1264
1221 case SP_CONE: 1265 case SP_CONE:
1222 success = cast_cone(op, caster, dir, spell_ob); 1266 success = cast_cone(op, caster, dir, spell_ob);
1223 break; 1267 break;
1224 1268
1225 case SP_BOMB: 1269 case SP_BOMB:
1226 success = create_bomb(op,caster,dir, spell_ob); 1270 success = create_bomb(op,caster,dir, spell_ob);
1227 break; 1271 break;
1228 1272
1229 case SP_WONDER: 1273 case SP_WONDER:
1230 success = cast_wonder(op,caster, dir,spell_ob); 1274 success = cast_wonder(op,caster, dir,spell_ob);
1231 break; 1275 break;
1232 1276
1233 case SP_SMITE: 1277 case SP_SMITE:
1234 success = cast_smite_spell(op,caster, dir,spell_ob); 1278 success = cast_smite_spell(op,caster, dir,spell_ob);
1235 break; 1279 break;
1236 1280
1237 case SP_MAGIC_MISSILE: 1281 case SP_MAGIC_MISSILE:
1238 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],
1239 op->y + freearr_y[dir], dir, spell_ob); 1283 op->y + freearr_y[dir], dir, spell_ob);
1240 break; 1284 break;
1241 1285
1242 case SP_SUMMON_GOLEM: 1286 case SP_SUMMON_GOLEM:
1243 success = summon_golem(op, caster, dir, spell_ob); 1287 success = summon_golem(op, caster, dir, spell_ob);
1244 old_shoottype = range_golem; 1288 old_shoottype = range_golem;
1245 break; 1289 break;
1246 1290
1247 case SP_DIMENSION_DOOR: 1291 case SP_DIMENSION_DOOR:
1248 /* dimension door needs the actual caster, because that is what is 1292 /* dimension door needs the actual caster, because that is what is
1249 * moved. 1293 * moved.
1250 */ 1294 */
1251 success = dimension_door(op,caster, spell_ob, dir); 1295 success = dimension_door(op,caster, spell_ob, dir);
1252 break; 1296 break;
1253 1297
1254 case SP_MAGIC_MAPPING: 1298 case SP_MAGIC_MAPPING:
1255 if(op->type==PLAYER) { 1299 if(op->type==PLAYER) {
1256 spell_effect(spell_ob, op->x, op->y, op->map, op); 1300 spell_effect(spell_ob, op->x, op->y, op->map, op);
1257 draw_magic_map(op); 1301 draw_magic_map(op);
1258 success=1; 1302 success=1;
1259 } 1303 }
1260 else success=0; 1304 else success=0;
1261 break; 1305 break;
1262 1306
1263 case SP_MAGIC_WALL: 1307 case SP_MAGIC_WALL:
1264 success = magic_wall(op,caster,dir,spell_ob); 1308 success = magic_wall(op,caster,dir,spell_ob);
1265 break; 1309 break;
1266 1310
1267 case SP_DESTRUCTION: 1311 case SP_DESTRUCTION:
1268 success = cast_destruction(op,caster,spell_ob); 1312 success = cast_destruction(op,caster,spell_ob);
1269 break; 1313 break;
1270 1314
1271 case SP_PERCEIVE_SELF: 1315 case SP_PERCEIVE_SELF:
1272 success = perceive_self(op); 1316 success = perceive_self(op);
1273 break; 1317 break;
1274 1318
1275 case SP_WORD_OF_RECALL: 1319 case SP_WORD_OF_RECALL:
1276 success = cast_word_of_recall(op,caster,spell_ob); 1320 success = cast_word_of_recall(op,caster,spell_ob);
1277 break; 1321 break;
1278 1322
1279 case SP_INVISIBLE: 1323 case SP_INVISIBLE:
1280 success = cast_invisible(op,caster,spell_ob); 1324 success = cast_invisible(op,caster,spell_ob);
1281 break; 1325 break;
1282 1326
1283 case SP_PROBE: 1327 case SP_PROBE:
1284 success = probe(op,caster, spell_ob, dir); 1328 success = probe(op,caster, spell_ob, dir);
1285 break; 1329 break;
1286 1330
1287 case SP_HEALING: 1331 case SP_HEALING:
1288 success = cast_heal(op,caster, spell_ob, dir); 1332 success = cast_heal(op,caster, spell_ob, dir);
1289 break; 1333 break;
1290 1334
1291 case SP_CREATE_FOOD: 1335 case SP_CREATE_FOOD:
1292 success = cast_create_food(op,caster,spell_ob, dir,stringarg); 1336 success = cast_create_food(op,caster,spell_ob, dir,stringarg);
1293 break; 1337 break;
1294 1338
1295 case SP_EARTH_TO_DUST: 1339 case SP_EARTH_TO_DUST:
1296 success = cast_earth_to_dust(op,caster,spell_ob); 1340 success = cast_earth_to_dust(op,caster,spell_ob);
1297 break; 1341 break;
1298 1342
1299 case SP_CHANGE_ABILITY: 1343 case SP_CHANGE_ABILITY:
1300 success = cast_change_ability(op,caster,spell_ob, dir, 0); 1344 success = cast_change_ability(op,caster,spell_ob, dir, 0);
1301 break; 1345 break;
1302 1346
1303 case SP_BLESS: 1347 case SP_BLESS:
1304 success = cast_bless(op,caster,spell_ob, dir); 1348 success = cast_bless(op,caster,spell_ob, dir);
1305 break; 1349 break;
1306 1350
1307 case SP_CURSE: 1351 case SP_CURSE:
1308 success = cast_curse(op,caster,spell_ob, dir); 1352 success = cast_curse(op,caster,spell_ob, dir);
1309 break; 1353 break;
1310 1354
1311 case SP_SUMMON_MONSTER: 1355 case SP_SUMMON_MONSTER:
1312 success = summon_object(op,caster,spell_ob, dir,stringarg); 1356 success = summon_object(op,caster,spell_ob, dir,stringarg);
1313 break; 1357 break;
1314 1358
1315 case SP_CHARGING: 1359 case SP_CHARGING:
1316 success = recharge(op, caster, spell_ob); 1360 success = recharge(op, caster, spell_ob);
1317 break; 1361 break;
1318 1362
1319 case SP_POLYMORPH: 1363 case SP_POLYMORPH:
1320#ifdef NO_POLYMORPH 1364#ifdef NO_POLYMORPH
1321 /* 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
1322 * 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
1323 * it was disabled), they get some feedback. 1367 * it was disabled), they get some feedback.
1324 */ 1368 */
1325 new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); 1369 new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles");
1326 success = 0; 1370 success = 0;
1327#else 1371#else
1328 success = cast_polymorph(op,caster,spell_ob, dir); 1372 success = cast_polymorph(op,caster,spell_ob, dir);
1329#endif 1373#endif
1330 break; 1374 break;
1331 1375
1332 case SP_ALCHEMY: 1376 case SP_ALCHEMY:
1333 success = alchemy(op, caster, spell_ob); 1377 success = alchemy(op, caster, spell_ob);
1334 break; 1378 break;
1335 1379
1336 case SP_REMOVE_CURSE: 1380 case SP_REMOVE_CURSE:
1337 success = remove_curse(op, caster, spell_ob); 1381 success = remove_curse(op, caster, spell_ob);
1338 break; 1382 break;
1339 1383
1340 case SP_IDENTIFY: 1384 case SP_IDENTIFY:
1341 success = cast_identify(op, caster, spell_ob); 1385 success = cast_identify(op, caster, spell_ob);
1342 break; 1386 break;
1343 1387
1344 case SP_DETECTION: 1388 case SP_DETECTION:
1345 success = cast_detection(op, caster, spell_ob, skill); 1389 success = cast_detection(op, caster, spell_ob, skill);
1346 break; 1390 break;
1347 1391
1348 case SP_MOOD_CHANGE: 1392 case SP_MOOD_CHANGE:
1349 success = mood_change(op, caster, spell_ob); 1393 success = mood_change(op, caster, spell_ob);
1350 break; 1394 break;
1351 1395
1352 case SP_MOVING_BALL: 1396 case SP_MOVING_BALL:
1353 if (spell_ob->path_repelled && 1397 if (spell_ob->path_repelled &&
1354 (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { 1398 (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) {
1355 new_draw_info_format(NDI_UNIQUE, 0, op, 1399 new_draw_info_format(NDI_UNIQUE, 0, op,
1356 "You lack the proper attunement to cast %s", spell_ob->name); 1400 "You lack the proper attunement to cast %s", spell_ob->name);
1357 success = 0; 1401 success = 0;
1358 } else 1402 } else
1359 success = fire_arch_from_position(op,caster, 1403 success = fire_arch_from_position(op,caster,
1360 op->x + freearr_x[dir], op->y + freearr_y[dir], 1404 op->x + freearr_x[dir], op->y + freearr_y[dir],
1361 dir, spell_ob); 1405 dir, spell_ob);
1362 break; 1406 break;
1363 1407
1364 case SP_SWARM: 1408 case SP_SWARM:
1365 success = fire_swarm(op, caster, spell_ob, dir); 1409 success = fire_swarm(op, caster, spell_ob, dir);
1366 break; 1410 break;
1367 1411
1368 case SP_CHANGE_MANA: 1412 case SP_CHANGE_MANA:
1369 success = cast_transfer(op,caster, spell_ob, dir); 1413 success = cast_transfer(op,caster, spell_ob, dir);
1370 break; 1414 break;
1371 1415
1372 case SP_DISPEL_RUNE: 1416 case SP_DISPEL_RUNE:
1373 /* in rune.c */ 1417 /* in rune.c */
1374 success = dispel_rune(op,caster, spell_ob, skill, dir); 1418 success = dispel_rune(op,caster, spell_ob, skill, dir);
1375 break; 1419 break;
1376 1420
1377 case SP_CREATE_MISSILE: 1421 case SP_CREATE_MISSILE:
1378 success = cast_create_missile(op,caster,spell_ob, dir,stringarg); 1422 success = cast_create_missile(op,caster,spell_ob, dir,stringarg);
1379 break; 1423 break;
1380 1424
1381 case SP_CONSECRATE: 1425 case SP_CONSECRATE:
1382 success = cast_consecrate(op, caster, spell_ob); 1426 success = cast_consecrate(op, caster, spell_ob);
1383 break; 1427 break;
1384 1428
1385 case SP_ANIMATE_WEAPON: 1429 case SP_ANIMATE_WEAPON:
1386 success = animate_weapon(op, caster, spell_ob, dir); 1430 success = animate_weapon(op, caster, spell_ob, dir);
1387 old_shoottype = range_golem; 1431 old_shoottype = range_golem;
1388 break; 1432 break;
1389 1433
1390 case SP_LIGHT: 1434 case SP_LIGHT:
1391 success = cast_light(op, caster, spell_ob, dir); 1435 success = cast_light(op, caster, spell_ob, dir);
1392 break; 1436 break;
1393 1437
1394 case SP_CHANGE_MAP_LIGHT: 1438 case SP_CHANGE_MAP_LIGHT:
1395 success = cast_change_map_lightlevel(op, caster, spell_ob); 1439 success = cast_change_map_lightlevel(op, caster, spell_ob);
1396 break; 1440 break;
1397 1441
1398 case SP_FAERY_FIRE: 1442 case SP_FAERY_FIRE:
1399 success = cast_destruction(op,caster,spell_ob); 1443 success = cast_destruction(op,caster,spell_ob);
1400 break; 1444 break;
1401 1445
1402 case SP_CAUSE_DISEASE: 1446 case SP_CAUSE_DISEASE:
1403 success = cast_cause_disease(op, caster, spell_ob, dir); 1447 success = cast_cause_disease(op, caster, spell_ob, dir);
1404 break; 1448 break;
1405 1449
1406 case SP_AURA: 1450 case SP_AURA:
1407 success = create_aura(op, caster, spell_ob); 1451 success = create_aura(op, caster, spell_ob);
1408 break; 1452 break;
1409 1453
1410 case SP_TOWN_PORTAL: 1454 case SP_TOWN_PORTAL:
1411 success= cast_create_town_portal (op,caster,spell_ob, dir); 1455 success= cast_create_town_portal (op,caster,spell_ob, dir);
1412 break; 1456 break;
1413 1457
1414 case SP_PARTY_SPELL: 1458 case SP_PARTY_SPELL:
1415 success = cast_party_spell( op, caster, dir, spell_ob, stringarg ); 1459 success = cast_party_spell (op, caster, dir, spell_ob, stringarg);
1460 break;
1416 1461
1417 default: 1462 default:
1418 LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", 1463 LOG(llevError,"cast_spell: Unhandled spell subtype %d\n",
1419 spell_ob->subtype); 1464 spell_ob->subtype);
1420 1465
1421 1466
1422 } 1467 }
1423 1468
1424 /* 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
1425/* 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
1426 /* free the spell arg */ 1474 /* free the spell arg */
1427 if(settings.casting_time == TRUE && stringarg) { 1475 if(settings.casting_time == TRUE && stringarg) {
1428 free(stringarg); 1476 free(stringarg);
1429 stringarg=NULL; 1477 stringarg=NULL;
1430 } 1478 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines