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