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

Comparing deliantra/server/server/disease.C (file contents):
Revision 1.10 by root, Wed Dec 13 00:42:04 2006 UTC vs.
Revision 1.23 by root, Mon May 14 21:32:27 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail to <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22*/ 23 */
23 24
24/* This file contains all the code implementing diseases, 25/* This file contains all the code implementing diseases,
25 except for odds and ends in attack.c and in 26 * except for odds and ends in attack.c and in
26 living.c*/ 27 * living.c
27 28 */
28
29 29
30/* 30/*
31 31
32For DISEASES: 32For DISEASES:
33Stat Property Definition 33Stat Property Definition
126 126
127 127
128#include <global.h> 128#include <global.h>
129#include <object.h> 129#include <object.h>
130#include <living.h> 130#include <living.h>
131#ifndef __CEXTRACT__
132# include <sproto.h> 131#include <sproto.h>
133#endif
134#include <spells.h> 132#include <spells.h>
135#include <sounds.h> 133#include <sounds.h>
136#include <skills.h> 134#include <skills.h>
137 135
138/* IMPLEMENTATION NOTES 136/* IMPLEMENTATION NOTES
226 224
227 symptom->destroy (); 225 symptom->destroy ();
228 } 226 }
229 227
230 if (victim) 228 if (victim)
231 fix_player (victim); 229 victim->update_stats ();
232 return 0; 230 return 0;
233} 231}
234 232
235/* argument is a disease */ 233/* argument is a disease */
236object * 234object *
238{ 236{
239 object *walk; 237 object *walk;
240 238
241 /* check the inventory for symptoms */ 239 /* check the inventory for symptoms */
242 for (walk = disease->env->inv; walk; walk = walk->below) 240 for (walk = disease->env->inv; walk; walk = walk->below)
243 if (!strcmp (walk->name, disease->name) && walk->type == SYMPTOM) 241 if (walk->name == disease->name && walk->type == SYMPTOM)
244 return walk; 242 return walk;
245 return NULL; 243 return NULL;
246} 244}
247 245
248/* searches around for more victims to infect */ 246/* searches around for more victims to infect */
276 { 274 {
277 sint16 i2, j2; 275 sint16 i2, j2;
278 mflags = get_map_flags (map, &map2, i, j, &i2, &j2); 276 mflags = get_map_flags (map, &map2, i, j, &i2, &j2);
279 277
280 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) 278 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE))
281 for (tmp = get_map_ob (map2, i2, j2); tmp; tmp = tmp->above) 279 for (tmp = GET_MAP_OB (map2, i2, j2); tmp; tmp = tmp->above)
282 infect_object (tmp, disease, 0); 280 infect_object (tmp, disease, 0);
283 } 281 }
284 282
285 return 1; 283 return 1;
286} 284}
324 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as 322 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
325 * they were cast in that same order. Instead, change it so that 323 * they were cast in that same order. Instead, change it so that
326 * if you diseased, you can't get diseased more. 324 * if you diseased, you can't get diseased more.
327 */ 325 */
328 326
329 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 327 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
330 { 328 {
331 if (tmp->type == SIGN && !strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 329 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level)
332 return 0; /*Immune! */ 330 return 0; /* Immune! */
333 else if (tmp->type == DISEASE && !strcmp (tmp->name, disease->name)) 331 else if (tmp->type == DISEASE && tmp->name == disease->name)
334 return 0; /* already diseased */ 332 return 0; /* already diseased */
335 } 333 }
336 334
337 /* If we've gotten this far, go ahead and infect the victim. */ 335 /* If we've gotten this far, go ahead and infect the victim. */
338 new_disease = disease->clone (); 336 new_disease = disease->clone ();
342 340
343 /* Unfortunately, set_owner does the wrong thing to the skills pointers 341 /* Unfortunately, set_owner does the wrong thing to the skills pointers
344 * resulting in exp going into the owners *current* chosen skill. 342 * resulting in exp going into the owners *current* chosen skill.
345 */ 343 */
346 344
347 if (get_owner (disease)) 345 if (disease->owner)
348 { 346 {
349 set_owner (new_disease, disease->owner); 347 new_disease->set_owner (disease->owner);
350 348
351 /* Only need to update skill if different */ 349 /* Only need to update skill if different */
352 if (new_disease->skill != disease->skill) 350 if (new_disease->skill != disease->skill)
353 new_disease->skill = disease->skill; 351 new_disease->skill = disease->skill;
354 } 352 }
356 { /* for diseases which are passed by hitting, set owner and praying skill */ 354 { /* for diseases which are passed by hitting, set owner and praying skill */
357 if (disease->env && disease->env->type == PLAYER) 355 if (disease->env && disease->env->type == PLAYER)
358 { 356 {
359 object *player = disease->env; 357 object *player = disease->env;
360 358
361 set_owner (new_disease, player); 359 new_disease->set_owner (player);
362 360
363 /* the skill pointer for these diseases should already be set up - 361 /* the skill pointer for these diseases should already be set up -
364 * hardcoding in 'praying' is not the right approach. 362 * hardcoding in 'praying' is not the right approach.
365 */ 363 */
366 } 364 }
433 if (victim->head) 431 if (victim->head)
434 tmp = victim->head->inv; 432 tmp = victim->head->inv;
435 else 433 else
436 tmp = victim->inv; 434 tmp = victim->inv;
437 435
438 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 436 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
439 { 437 {
440 if (tmp->type == SIGN) /* possibly an immunity, or diseased */ 438 if (tmp->type == SIGN) /* possibly an immunity, or diseased */
441 if (!strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 439 if (tmp->name == disease->name && tmp->level >= disease->level)
442 return 0; /*Immune! */ 440 return 0; /*Immune! */
443 } 441 }
444 442
445 new_symptom = get_archetype (ARCH_SYMPTOM); 443 new_symptom = get_archetype (ARCH_SYMPTOM);
446 444
452 { 450 {
453 int dam = disease->stats.dam; 451 int dam = disease->stats.dam;
454 452
455 /* reduce the damage, on average, 50%, and making things random. */ 453 /* reduce the damage, on average, 50%, and making things random. */
456 454
457 dam = random_roll (1, FABS (dam), victim, PREFER_LOW); 455 dam = random_roll (1, abs (dam), victim, PREFER_LOW);
458 if (disease->stats.dam < 0) 456 if (disease->stats.dam < 0)
459 dam = -dam; 457 dam = -dam;
460 new_symptom->stats.dam = dam; 458 new_symptom->stats.dam = dam;
461 } 459 }
462 460
467 new_symptom->name = new_symptom->name_pl = disease->name; 465 new_symptom->name = new_symptom->name_pl = disease->name;
468 466
469 new_symptom->level = disease->level; 467 new_symptom->level = disease->level;
470 new_symptom->speed = disease->speed; 468 new_symptom->speed = disease->speed;
471 new_symptom->value = 0; 469 new_symptom->value = 0;
470
471 for (int i = 0; i < NUM_STATS; ++i)
472 new_symptom->stats.Str = disease->stats.Str; 472 new_symptom->stats.stat (i) = disease->stats.stat (i);
473 new_symptom->stats.Dex = disease->stats.Dex; 473
474 new_symptom->stats.Con = disease->stats.Con;
475 new_symptom->stats.Wis = disease->stats.Wis;
476 new_symptom->stats.Int = disease->stats.Int;
477 new_symptom->stats.Pow = disease->stats.Pow;
478 new_symptom->stats.Cha = disease->stats.Cha;
479 new_symptom->stats.sp = disease->stats.sp; 474 new_symptom->stats.sp = disease->stats.sp;
480 new_symptom->stats.food = disease->last_eat; 475 new_symptom->stats.food = disease->last_eat;
481 new_symptom->stats.maxsp = disease->stats.maxsp; 476 new_symptom->stats.maxsp = disease->stats.maxsp;
482 new_symptom->last_sp = disease->last_sp; 477 new_symptom->last_sp = disease->last_sp;
483 new_symptom->stats.exp = 0; 478 new_symptom->stats.exp = 0;
484 new_symptom->stats.hp = disease->stats.hp; 479 new_symptom->stats.hp = disease->stats.hp;
485 new_symptom->msg = disease->msg; 480 new_symptom->msg = disease->msg;
486 new_symptom->attacktype = disease->attacktype; 481 new_symptom->attacktype = disease->attacktype;
487 new_symptom->other_arch = disease->other_arch; 482 new_symptom->other_arch = disease->other_arch;
488 483
489 set_owner (new_symptom, disease->owner); 484 new_symptom->set_owner (disease->owner);
490 485
491 if (new_symptom->skill != disease->skill) 486 if (new_symptom->skill != disease->skill)
492 new_symptom->skill = disease->skill; 487 new_symptom->skill = disease->skill;
493 488
494 new_symptom->move_block = 0; 489 new_symptom->move_block = 0;
495 insert_ob_in_ob (new_symptom, victim); 490 insert_ob_in_ob (new_symptom, victim);
496 return 1; 491 return 1;
497 } 492 }
498 493
499 /* now deal with progressing diseases: we increase the debility 494 /* now deal with progressing diseases: we increase the debility
500 * caused by the symptoms. 495 * caused by the symptoms.
501 */ 496 */
502
503 if (disease->stats.ac != 0) 497 if (disease->stats.ac != 0)
504 { 498 {
505 float scale;
506
507 symptom->value += disease->stats.ac; 499 symptom->value += disease->stats.ac;
500
508 scale = 1.0 + symptom->value / 100.0; 501 float scale = 1.f + symptom->value / 100.f;
502
509 /* now rescale all the debilities */ 503 /* now rescale all the debilities */
504 for (int i = 0; i < NUM_STATS; ++i)
510 symptom->stats.Str = (int) (scale * disease->stats.Str); 505 symptom->stats.stat (i) = scale * disease->stats.stat (i);
511 symptom->stats.Dex = (int) (scale * disease->stats.Dex); 506
512 symptom->stats.Con = (int) (scale * disease->stats.Con);
513 symptom->stats.Wis = (int) (scale * disease->stats.Wis);
514 symptom->stats.Int = (int) (scale * disease->stats.Int);
515 symptom->stats.Pow = (int) (scale * disease->stats.Pow);
516 symptom->stats.Cha = (int) (scale * disease->stats.Cha);
517 symptom->stats.dam = (int) (scale * disease->stats.dam); 507 symptom->stats.dam = scale * disease->stats.dam;
518 symptom->stats.sp = (int) (scale * disease->stats.sp); 508 symptom->stats.sp = scale * disease->stats.sp;
519 symptom->stats.food = (int) (scale * disease->last_eat); 509 symptom->stats.food = scale * disease->last_eat;
520 symptom->stats.maxsp = (int) (scale * disease->stats.maxsp); 510 symptom->stats.maxsp = scale * disease->stats.maxsp;
521 symptom->last_sp = (int) (scale * disease->last_sp); 511 symptom->last_sp = scale * disease->last_sp;
522 symptom->stats.exp = 0; 512 symptom->stats.exp = 0;
523 symptom->stats.hp = (int) (scale * disease->stats.hp); 513 symptom->stats.hp = scale * disease->stats.hp;
514
524 symptom->msg = disease->msg; 515 symptom->msg = disease->msg;
525 symptom->attacktype = disease->attacktype; 516 symptom->attacktype = disease->attacktype;
526 symptom->other_arch = disease->other_arch; 517 symptom->other_arch = disease->other_arch;
527 } 518 }
519
528 SET_FLAG (symptom, FLAG_APPLIED); 520 SET_FLAG (symptom, FLAG_APPLIED);
529 fix_player (victim); 521 victim->update_stats ();
522
530 return 1; 523 return 1;
531} 524}
532
533 525
534/* grants immunity to plagues we've seen before. */ 526/* grants immunity to plagues we've seen before. */
535int 527int
536grant_immunity (object *disease) 528grant_immunity (object *disease)
537{ 529{
542 if (disease->last_heal) 534 if (disease->last_heal)
543 return 0; 535 return 0;
544 /* first, search for an immunity of the same name */ 536 /* first, search for an immunity of the same name */
545 for (walk = disease->env->inv; walk; walk = walk->below) 537 for (walk = disease->env->inv; walk; walk = walk->below)
546 { 538 {
547 if (walk->type == 98 && !strcmp (disease->name, walk->name)) 539 if (walk->type == 98 && disease->name == walk->name)
548 { 540 {
549 walk->level = disease->level; 541 walk->level = disease->level;
550 return 1; /* just update the existing immunity. */ 542 return 1; /* just update the existing immunity. */
551 } 543 }
552 } 544 }
598 object *tmp; 590 object *tmp;
599 591
600 tmp = victim; 592 tmp = victim;
601 if (tmp->head != NULL) 593 if (tmp->head != NULL)
602 tmp = tmp->head; 594 tmp = tmp->head;
603 for ( /*tmp initialized above */ ; tmp != NULL; tmp = tmp->more) 595 for ( /*tmp initialised above */ ; tmp != NULL; tmp = tmp->more)
604 { 596 {
605 new_ob = arch_to_object (symptom->other_arch); 597 new_ob = arch_to_object (symptom->other_arch);
606 new_ob->x = tmp->x; 598 new_ob->x = tmp->x;
607 new_ob->y = tmp->y; 599 new_ob->y = tmp->y;
608 new_ob->map = victim->map; 600 new_ob->map = victim->map;
612 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); 604 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg);
613 605
614 return 1; 606 return 1;
615} 607}
616 608
617
618/* possibly infect due to direct physical contact 609/* possibly infect due to direct physical contact
619 i.e., AT_PHYSICAL-- called from "hit_player_attacktype" */ 610 * i.e., AT_PHYSICAL-- called from "hit_player_attacktype" */
620
621int 611int
622check_physically_infect (object *victim, object *hitter) 612check_physically_infect (object *victim, object *hitter)
623{ 613{
624 object *walk;
625
626 /* search for diseases, give every disease a chance to infect */ 614 /* search for diseases, give every disease a chance to infect */
627 for (walk = hitter->inv; walk != NULL; walk = walk->below) 615 for (object *disease = hitter->inv; disease; disease = disease->below)
628 if (walk->type == DISEASE) 616 if (disease->type == DISEASE)
629 infect_object (victim, walk, 0); 617 infect_object (victim, disease, 0);
618
630 return 1; 619 return 1;
631} 620}
632 621
633/* find a disease in someone*/ 622// find a disease in someone
634object * 623object *
635find_disease (object *victim) 624find_disease (object *victim)
636{ 625{
637 object *walk; 626 for (object *disease = victim->inv; disease; disease = disease->below)
638
639 for (walk = victim->inv; walk; walk = walk->below)
640 if (walk->type == DISEASE) 627 if (disease->type == DISEASE)
641 return walk; 628 return disease;
629
642 return NULL; 630 return 0;
643} 631}
644 632
645/* do the cure disease stuff, from the spell "cure disease" */ 633/* do the cure disease stuff, from the spell "cure disease" */
646
647int 634int
648cure_disease (object *sufferer, object *caster) 635cure_disease (object *sufferer, object *caster)
649{ 636{
650 object *disease, *next; 637 object *disease, *next;
651 int casting_level; 638 int casting_level;
660 { 647 {
661 next = disease->below; 648 next = disease->below;
662 649
663 if (disease->type == DISEASE) 650 if (disease->type == DISEASE)
664 { /* attempt to cure this disease */ 651 { /* attempt to cure this disease */
665 /* If caster lvel is higher than disease level, cure chance 652 /* If caster level is higher than disease level, cure chance
666 * is automatic. If lower, then the chance is basically 653 * is automatic. If lower, then the chance is basically
667 * 1 in level_diff - if there is a 5 level difference, chance 654 * 1 in level_diff - if there is a 5 level difference, chance
668 * is 1 in 5. 655 * is 1 in 5.
669 */ 656 */
670 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW)))) 657 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW))))
671 { 658 {
672
673 remove_symptoms (disease); 659 remove_symptoms (disease);
674 cure = 1; 660 cure = 1;
675 661
676 if (caster) 662 if (caster)
677 change_exp (caster, disease->stats.exp, caster->chosen_skill ? &caster->chosen_skill->skill : (const char *) 0, 0); 663 change_exp (caster, disease->stats.exp, caster->chosen_skill ? caster->chosen_skill->skill : (const char *) 0, 0);
678 664
679 disease->destroy (); 665 disease->destroy ();
680 } 666 }
681 } 667 }
682 } 668 }
669
683 if (cure) 670 if (cure)
684 { 671 {
685 /* Only draw these messages once */ 672 /* Only draw these messages once */
686 if (caster) 673 if (caster)
687 new_draw_info_format (NDI_UNIQUE, 0, caster, "You cure a disease!"); 674 new_draw_info_format (NDI_UNIQUE, 0, caster, "You cure a disease!");
675
688 new_draw_info (NDI_UNIQUE, 0, sufferer, "You no longer feel diseased."); 676 new_draw_info (NDI_UNIQUE, 0, sufferer, "You no longer feel diseased.");
689 } 677 }
678
690 return 1; 679 return 1;
691} 680}
692 681
693/* reduces disease progression: reduce_symptoms 682/* reduces disease progression: reduce_symptoms
694 * return true if we actually reduce a disease. 683 * return true if we actually reduce a disease.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines