1 | /* |
1 | /* |
2 | * static char *rcsid_apply_c = |
2 | * static char *rcsid_apply_c = |
3 | * "$Id: apply.C,v 1.3 2006/08/15 15:00:20 elmex Exp $"; |
3 | * "$Id: apply.C,v 1.4 2006/08/15 16:19:55 elmex Exp $"; |
4 | */ |
4 | */ |
5 | /* |
5 | /* |
6 | CrossFire, A Multiplayer game for X-windows |
6 | CrossFire, A Multiplayer game for X-windows |
7 | |
7 | |
8 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
8 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
… | |
… | |
338 | int got_one = 0, i; |
338 | int got_one = 0, i; |
339 | object *force = 0, *floor = 0; |
339 | object *force = 0, *floor = 0; |
340 | |
340 | |
341 | floor = get_map_ob (op->map, op->x, op->y); |
341 | floor = get_map_ob (op->map, op->x, op->y); |
342 | |
342 | |
343 | if (!(get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE_MAP)) |
343 | if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE_MAP) |
344 | { |
344 | { |
345 | if (op->type == PLAYER) |
345 | if (op->type == PLAYER) |
|
|
346 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
347 | "Gods prevent you from using this here, it's sacred ground!" |
|
|
348 | ); |
|
|
349 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
|
|
350 | return 0; |
|
|
351 | } |
|
|
352 | |
|
|
353 | if (op->type == PLAYER) |
|
|
354 | { |
|
|
355 | if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) |
|
|
356 | identify (tmp); |
|
|
357 | } |
|
|
358 | |
|
|
359 | handle_apply_yield (tmp); |
|
|
360 | |
|
|
361 | /* Potion of restoration - only for players */ |
|
|
362 | if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) |
|
|
363 | { |
|
|
364 | object *depl; |
|
|
365 | archetype *at; |
|
|
366 | |
|
|
367 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
346 | { |
368 | { |
347 | if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) |
|
|
348 | identify (tmp); |
|
|
349 | } |
|
|
350 | |
|
|
351 | handle_apply_yield (tmp); |
|
|
352 | |
|
|
353 | /* Potion of restoration - only for players */ |
|
|
354 | if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) |
|
|
355 | { |
|
|
356 | object *depl; |
|
|
357 | archetype *at; |
|
|
358 | |
|
|
359 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
360 | { |
|
|
361 | drain_stat (op); |
369 | drain_stat (op); |
362 | fix_player (op); |
370 | fix_player (op); |
363 | decrease_ob (tmp); |
|
|
364 | return 1; |
|
|
365 | } |
|
|
366 | if ((at = find_archetype (ARCH_DEPLETION)) == NULL) |
|
|
367 | { |
|
|
368 | LOG (llevError, "Could not find archetype depletion\n"); |
|
|
369 | return 0; |
|
|
370 | } |
|
|
371 | depl = present_arch_in_ob (at, op); |
|
|
372 | if (depl != NULL) |
|
|
373 | { |
|
|
374 | for (i = 0; i < NUM_STATS; i++) |
|
|
375 | if (get_attr_value (&depl->stats, i)) |
|
|
376 | { |
|
|
377 | new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); |
|
|
378 | } |
|
|
379 | remove_ob (depl); |
|
|
380 | free_object (depl); |
|
|
381 | fix_player (op); |
|
|
382 | } |
|
|
383 | else |
|
|
384 | new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect."); |
|
|
385 | |
|
|
386 | decrease_ob (tmp); |
371 | decrease_ob (tmp); |
387 | return 1; |
372 | return 1; |
388 | } |
373 | } |
389 | |
374 | if ((at = find_archetype (ARCH_DEPLETION)) == NULL) |
390 | /* improvement potion - only for players */ |
|
|
391 | if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER) |
|
|
392 | { |
375 | { |
393 | |
376 | LOG (llevError, "Could not find archetype depletion\n"); |
394 | for (i = 1; i < MIN (11, op->level); i++) |
|
|
395 | { |
|
|
396 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
397 | { |
|
|
398 | if (op->contr->levhp[i] != 1) |
|
|
399 | { |
|
|
400 | op->contr->levhp[i] = 1; |
|
|
401 | break; |
|
|
402 | } |
|
|
403 | if (op->contr->levsp[i] != 1) |
|
|
404 | { |
|
|
405 | op->contr->levsp[i] = 1; |
|
|
406 | break; |
|
|
407 | } |
|
|
408 | if (op->contr->levgrace[i] != 1) |
|
|
409 | { |
|
|
410 | op->contr->levgrace[i] = 1; |
|
|
411 | break; |
|
|
412 | } |
|
|
413 | } |
|
|
414 | else |
|
|
415 | { |
|
|
416 | if (op->contr->levhp[i] < 9) |
|
|
417 | { |
|
|
418 | op->contr->levhp[i] = 9; |
|
|
419 | break; |
|
|
420 | } |
|
|
421 | if (op->contr->levsp[i] < 6) |
|
|
422 | { |
|
|
423 | op->contr->levsp[i] = 6; |
|
|
424 | break; |
|
|
425 | } |
|
|
426 | if (op->contr->levgrace[i] < 3) |
|
|
427 | { |
|
|
428 | op->contr->levgrace[i] = 3; |
|
|
429 | break; |
|
|
430 | } |
|
|
431 | } |
|
|
432 | } |
|
|
433 | /* Just makes checking easier */ |
|
|
434 | if (i < MIN (11, op->level)) |
|
|
435 | got_one = 1; |
|
|
436 | if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
437 | { |
|
|
438 | if (got_one) |
|
|
439 | { |
|
|
440 | fix_player (op); |
|
|
441 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
442 | "The Gods smile upon you and remake you"); |
|
|
443 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
444 | "a little more in their image."); |
|
|
445 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
446 | "You feel a little more perfect."); |
|
|
447 | } |
|
|
448 | else |
|
|
449 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
450 | "The potion had no effect - you are already perfect"); |
|
|
451 | } |
|
|
452 | else |
|
|
453 | { /* cursed potion */ |
|
|
454 | if (got_one) |
|
|
455 | { |
|
|
456 | fix_player (op); |
|
|
457 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
458 | "The Gods are angry and punish you."); |
|
|
459 | } |
|
|
460 | else |
|
|
461 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
462 | "You are fortunate that you are so pathetic."); |
|
|
463 | } |
|
|
464 | decrease_ob (tmp); |
|
|
465 | return 1; |
377 | return 0; |
466 | } |
378 | } |
467 | |
379 | depl = present_arch_in_ob (at, op); |
468 | |
380 | if (depl != NULL) |
469 | /* A potion that casts a spell. Healing, restore spellpoint (power potion) |
|
|
470 | * and heroism all fit into this category. Given the spell object code, |
|
|
471 | * there is no limit to the number of spells that potions can be cast, |
|
|
472 | * but direction is problematic to try and imbue fireball potions for example. |
|
|
473 | */ |
381 | { |
474 | if (tmp->inv) |
382 | for (i = 0; i < NUM_STATS; i++) |
|
|
383 | if (get_attr_value (&depl->stats, i)) |
|
|
384 | { |
|
|
385 | new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); |
|
|
386 | } |
|
|
387 | remove_ob (depl); |
|
|
388 | free_object (depl); |
|
|
389 | fix_player (op); |
|
|
390 | } |
|
|
391 | else |
|
|
392 | new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect."); |
|
|
393 | |
|
|
394 | decrease_ob (tmp); |
|
|
395 | return 1; |
|
|
396 | } |
|
|
397 | |
|
|
398 | /* improvement potion - only for players */ |
|
|
399 | if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER) |
|
|
400 | { |
|
|
401 | |
|
|
402 | for (i = 1; i < MIN (11, op->level); i++) |
475 | { |
403 | { |
476 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
404 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
477 | { |
405 | { |
478 | object *fball; |
406 | if (op->contr->levhp[i] != 1) |
479 | |
407 | { |
480 | new_draw_info (NDI_UNIQUE, 0, op, "Yech! Your lungs are on fire!"); |
408 | op->contr->levhp[i] = 1; |
481 | /* Explodes a fireball centered at player */ |
409 | break; |
482 | fball = get_archetype (EXPLODING_FIREBALL); |
410 | } |
483 | fball->dam_modifier = |
411 | if (op->contr->levsp[i] != 1) |
484 | random_roll (1, op->level, op, PREFER_LOW) / 5 + 1; |
412 | { |
485 | fball->stats.maxhp = |
413 | op->contr->levsp[i] = 1; |
486 | random_roll (1, op->level, op, PREFER_LOW) / 10 + 2; |
414 | break; |
487 | fball->x = op->x; |
415 | } |
488 | fball->y = op->y; |
416 | if (op->contr->levgrace[i] != 1) |
489 | insert_ob_in_map (fball, op->map, NULL, 0); |
417 | { |
|
|
418 | op->contr->levgrace[i] = 1; |
|
|
419 | break; |
|
|
420 | } |
490 | } |
421 | } |
491 | else |
422 | else |
492 | cast_spell (op, tmp, op->facing, tmp->inv, NULL); |
|
|
493 | |
|
|
494 | decrease_ob (tmp); |
|
|
495 | /* if youre dead, no point in doing this... */ |
|
|
496 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
|
|
497 | fix_player (op); |
|
|
498 | return 1; |
|
|
499 | } |
|
|
500 | |
|
|
501 | /* Deal with protection potions */ |
|
|
502 | force = NULL; |
|
|
503 | for (i = 0; i < NROFATTACKS; i++) |
|
|
504 | { |
|
|
505 | if (tmp->resist[i]) |
|
|
506 | { |
423 | { |
507 | if (!force) |
424 | if (op->contr->levhp[i] < 9) |
508 | force = get_archetype (FORCE_NAME); |
425 | { |
509 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
426 | op->contr->levhp[i] = 9; |
510 | force->type = POTION_EFFECT; |
427 | break; |
511 | break; /* Only need to find one protection since we copy entire batch */ |
428 | } |
|
|
429 | if (op->contr->levsp[i] < 6) |
|
|
430 | { |
|
|
431 | op->contr->levsp[i] = 6; |
|
|
432 | break; |
|
|
433 | } |
|
|
434 | if (op->contr->levgrace[i] < 3) |
|
|
435 | { |
|
|
436 | op->contr->levgrace[i] = 3; |
|
|
437 | break; |
|
|
438 | } |
512 | } |
439 | } |
513 | } |
440 | } |
514 | /* This is a protection potion */ |
441 | /* Just makes checking easier */ |
515 | if (force) |
442 | if (i < MIN (11, op->level)) |
|
|
443 | got_one = 1; |
|
|
444 | if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) |
516 | { |
445 | { |
517 | /* cursed items last longer */ |
446 | if (got_one) |
518 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
519 | { |
447 | { |
520 | force->stats.food *= 10; |
448 | fix_player (op); |
521 | for (i = 0; i < NROFATTACKS; i++) |
449 | new_draw_info (NDI_UNIQUE, 0, op, |
522 | if (force->resist[i] > 0) |
450 | "The Gods smile upon you and remake you"); |
523 | force->resist[i] = -force->resist[i]; /* prot => vuln */ |
451 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
452 | "a little more in their image."); |
|
|
453 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
454 | "You feel a little more perfect."); |
524 | } |
455 | } |
525 | force->speed_left = -1; |
456 | else |
526 | force = insert_ob_in_ob (force, op); |
457 | new_draw_info (NDI_UNIQUE, 0, op, |
527 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
458 | "The potion had no effect - you are already perfect"); |
528 | SET_FLAG (force, FLAG_APPLIED); |
|
|
529 | change_abil (op, force); |
|
|
530 | decrease_ob (tmp); |
|
|
531 | return 1; |
|
|
532 | } |
459 | } |
533 | |
460 | else |
534 | /* Only thing left are the stat potions */ |
461 | { /* cursed potion */ |
535 | if (op->type == PLAYER) |
462 | if (got_one) |
536 | { /* only for players */ |
463 | { |
537 | if ((QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
464 | fix_player (op); |
538 | && tmp->value != 0) |
465 | new_draw_info (NDI_UNIQUE, 0, op, |
539 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
466 | "The Gods are angry and punish you."); |
|
|
467 | } |
540 | else |
468 | else |
541 | SET_FLAG (tmp, FLAG_APPLIED); |
|
|
542 | if (!change_abil (op, tmp)) |
|
|
543 | new_draw_info (NDI_UNIQUE, 0, op, "Nothing happened."); |
469 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
470 | "You are fortunate that you are so pathetic."); |
544 | } |
471 | } |
|
|
472 | decrease_ob (tmp); |
|
|
473 | return 1; |
545 | } |
474 | } |
546 | else |
475 | |
|
|
476 | |
|
|
477 | /* A potion that casts a spell. Healing, restore spellpoint (power potion) |
|
|
478 | * and heroism all fit into this category. Given the spell object code, |
|
|
479 | * there is no limit to the number of spells that potions can be cast, |
|
|
480 | * but direction is problematic to try and imbue fireball potions for example. |
|
|
481 | */ |
|
|
482 | if (tmp->inv) |
547 | { |
483 | { |
548 | if (op->type == PLAYER) |
484 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
549 | new_draw_info (NDI_UNIQUE, 0, op, |
|
|
550 | "Gods prevent you from using the potion on this sacred ground" |
|
|
551 | ); |
485 | { |
|
|
486 | object *fball; |
|
|
487 | |
|
|
488 | new_draw_info (NDI_UNIQUE, 0, op, "Yech! Your lungs are on fire!"); |
|
|
489 | /* Explodes a fireball centered at player */ |
|
|
490 | fball = get_archetype (EXPLODING_FIREBALL); |
|
|
491 | fball->dam_modifier = |
|
|
492 | random_roll (1, op->level, op, PREFER_LOW) / 5 + 1; |
|
|
493 | fball->stats.maxhp = |
|
|
494 | random_roll (1, op->level, op, PREFER_LOW) / 10 + 2; |
|
|
495 | fball->x = op->x; |
|
|
496 | fball->y = op->y; |
|
|
497 | insert_ob_in_map (fball, op->map, NULL, 0); |
|
|
498 | } |
|
|
499 | else |
|
|
500 | cast_spell (op, tmp, op->facing, tmp->inv, NULL); |
|
|
501 | |
|
|
502 | decrease_ob (tmp); |
|
|
503 | /* if youre dead, no point in doing this... */ |
|
|
504 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
|
|
505 | fix_player (op); |
552 | return 0; |
506 | return 1; |
|
|
507 | } |
|
|
508 | |
|
|
509 | /* Deal with protection potions */ |
|
|
510 | force = NULL; |
|
|
511 | for (i = 0; i < NROFATTACKS; i++) |
|
|
512 | { |
|
|
513 | if (tmp->resist[i]) |
|
|
514 | { |
|
|
515 | if (!force) |
|
|
516 | force = get_archetype (FORCE_NAME); |
|
|
517 | memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); |
|
|
518 | force->type = POTION_EFFECT; |
|
|
519 | break; /* Only need to find one protection since we copy entire batch */ |
|
|
520 | } |
|
|
521 | } |
|
|
522 | /* This is a protection potion */ |
|
|
523 | if (force) |
|
|
524 | { |
|
|
525 | /* cursed items last longer */ |
|
|
526 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
527 | { |
|
|
528 | force->stats.food *= 10; |
|
|
529 | for (i = 0; i < NROFATTACKS; i++) |
|
|
530 | if (force->resist[i] > 0) |
|
|
531 | force->resist[i] = -force->resist[i]; /* prot => vuln */ |
|
|
532 | } |
|
|
533 | force->speed_left = -1; |
|
|
534 | force = insert_ob_in_ob (force, op); |
|
|
535 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
|
|
536 | SET_FLAG (force, FLAG_APPLIED); |
|
|
537 | change_abil (op, force); |
|
|
538 | decrease_ob (tmp); |
|
|
539 | return 1; |
|
|
540 | } |
|
|
541 | |
|
|
542 | /* Only thing left are the stat potions */ |
|
|
543 | if (op->type == PLAYER) |
|
|
544 | { /* only for players */ |
|
|
545 | if ((QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
|
|
546 | && tmp->value != 0) |
|
|
547 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
|
|
548 | else |
|
|
549 | SET_FLAG (tmp, FLAG_APPLIED); |
|
|
550 | if (!change_abil (op, tmp)) |
|
|
551 | new_draw_info (NDI_UNIQUE, 0, op, "Nothing happened."); |
553 | } |
552 | } |
554 | |
553 | |
555 | /* CLEAR_FLAG is so that if the character has other potions |
554 | /* CLEAR_FLAG is so that if the character has other potions |
556 | * that were grouped with the one consumed, his |
555 | * that were grouped with the one consumed, his |
557 | * stat will not be raised by them. fix_player just clears |
556 | * stat will not be raised by them. fix_player just clears |