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.31 by root, Tue Aug 7 22:57:57 2007 UTC vs.
Revision 1.38 by root, Fri Aug 24 01:23:29 2007 UTC

44dam^ Damage How much damage it does (%?). 44dam^ Damage How much damage it does (%?).
45maxgrace+ Duration How long before the disease is naturally cured. 45maxgrace+ Duration How long before the disease is naturally cured.
46food DurCount Counter for Duration 46food DurCount Counter for Duration
47 47
48speed Speed How often the disease moves. 48speed Speed How often the disease moves.
49last_sp^ Lethargy Percentage of max speed--10 = 10% speed. 49last_sp^ Lethargy Percentage of max speed. 10 = 10% speed.
50 50
51maxsp^ Mana deplete Saps mana. 51maxsp^ Mana deplete Saps mana.
52ac^ Progressiveness How the diseases increases in severity. 52ac^ Progressiveness How the diseases increases in severity.
53last_eat*^ Deplete food saps food if negative 53last_eat*^ Deplete food saps food if negative
54last_heal GrantImmunity If nonzero, disease does NOT grant immunity 54last_heal GrantImmunity If nonzero, disease does NOT grant immunity
208 * Modified by MSW 2003-03-28 do try to find all the symptom the 208 * Modified by MSW 2003-03-28 do try to find all the symptom the
209 * player may have - I think through some odd interactoins with 209 * player may have - I think through some odd interactoins with
210 * disease level and player level and whatnot, a player could get 210 * disease level and player level and whatnot, a player could get
211 * more than one symtpom to a disease. 211 * more than one symtpom to a disease.
212 */ 212 */
213
214int 213int
215remove_symptoms (object *disease) 214remove_symptoms (object *disease)
216{ 215{
217 object *symptom, *victim = NULL; 216 object *symptom, *victim = NULL;
218 217
232 231
233/* argument is a disease */ 232/* argument is a disease */
234object * 233object *
235find_symptom (object *disease) 234find_symptom (object *disease)
236{ 235{
237 object *walk;
238
239 /* check the inventory for symptoms */ 236 /* check the inventory for symptoms */
240 for (walk = disease->env->inv; walk; walk = walk->below) 237 for (object *walk = disease->env->inv; walk; walk = walk->below)
241 if (walk->name == disease->name && walk->type == SYMPTOM) 238 if (walk->name == disease->name && walk->type == SYMPTOM)
242 return walk; 239 return walk;
243 240
244 return NULL; 241 return NULL;
245} 242}
281 infect_object (tmp, disease, 0); 278 infect_object (tmp, disease, 0);
282 } 279 }
283 280
284 return 1; 281 return 1;
285} 282}
286
287 283
288/* check to see if an object is infectable: 284/* check to see if an object is infectable:
289 * objects with immunity aren't infectable. 285 * objects with immunity aren't infectable.
290 * objects already infected aren't infectable. 286 * objects already infected aren't infectable.
291 * dead objects aren't infectable. 287 * dead objects aren't infectable.
310 /* roll the dice on infection before doing the inventory check! */ 306 /* roll the dice on infection before doing the inventory check! */
311 if (!force && (random_roll (0, 126, victim, PREFER_HIGH) >= disease->stats.wc)) 307 if (!force && (random_roll (0, 126, victim, PREFER_HIGH) >= disease->stats.wc))
312 return 0; 308 return 0;
313 309
314 /* do an immunity check */ 310 /* do an immunity check */
315 if (victim->head)
316 tmp = victim->head->inv;
317 else
318 tmp = victim->inv;
319 311
320 /* There used to (IMO) be a flaw in the below - it used to be the case 312 /* There used to (IMO) be a flaw in the below - it used to be the case
321 * that if level check was done for both immunity and disease. This could 313 * that if level check was done for both immunity and disease. This could
322 * result in a person with multiple afflictions of the same disease 314 * result in a person with multiple afflictions of the same disease
323 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as 315 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
324 * they were cast in that same order. Instead, change it so that 316 * they were cast in that same order. Instead, change it so that
325 * if you diseased, you can't get diseased more. 317 * if you diseased, you can't get diseased more.
326 */ 318 */
327 319
328 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below) 320 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below)
329 {
330 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level) 321 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level)
331 return 0; /* Immune! */ 322 return 0; /* Immune! */
332 else if (tmp->type == DISEASE && tmp->name == disease->name) 323 else if (tmp->type == DISEASE && tmp->name == disease->name)
333 return 0; /* already diseased */ 324 return 0; /* already diseased */
334 }
335 325
336 /* If we've gotten this far, go ahead and infect the victim. */ 326 /* If we've gotten this far, go ahead and infect the victim. */
327
337 new_disease = disease->clone (); 328 new_disease = disease->clone ();
329
338 new_disease->stats.food = disease->stats.maxgrace; 330 new_disease->stats.food = disease->stats.maxgrace;
339 new_disease->value = disease->stats.maxhp; 331 new_disease->value = disease->stats.maxhp;
340 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */ 332 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
341 333
342 /* Unfortunately, set_owner does the wrong thing to the skills pointers
343 * resulting in exp going into the owners *current* chosen skill.
344 */
345
346 if (disease->owner)
347 {
348 new_disease->set_owner (disease->owner);
349
350 /* Only need to update skill if different */
351 if (new_disease->skill != disease->skill)
352 new_disease->skill = disease->skill;
353 }
354 else
355 { /* for diseases which are passed by hitting, set owner and praying skill */
356 if (disease->env && disease->env->type == PLAYER)
357 {
358 object *player = disease->env;
359
360 new_disease->set_owner (player);
361
362 /* the skill pointer for these diseases should already be set up -
363 * hardcoding in 'praying' is not the right approach.
364 */
365 }
366 }
367
368 insert_ob_in_ob (new_disease, victim->head_ ());
369 /* This appears to be a horrible case of overloading 'NO_PASS' 334 /* This appears to be a horrible case of overloading 'NO_PASS'
370 * for meaning in the diseases. 335 * for meaning in the diseases.
371 */ 336 */
372 new_disease->move_block = 0; 337 new_disease->move_block = 0;
338
339 // insert before setting the owner
340 victim->head_ ()->insert (new_disease);
341
342 if (disease->owner)
343 new_disease->set_owner (disease->owner);
344 else if (object *pl = disease->in_player ())
345 /* for diseases which are passed by hitting, set owner and skill */
346 new_disease->set_owner (pl);
347
373 if (new_disease->owner && new_disease->owner->type == PLAYER) 348 if (new_disease->owner && new_disease->owner->type == PLAYER)
374 { 349 {
375 char buf[128]; 350 const char *buf;
376 351
377 /* if the disease has a title, it has a special infection message 352 /* if the disease has a title, it has a special infection message
378 * This messages is printed in the form MESSAGE victim 353 * This messages is printed in the form MESSAGE victim
379 */ 354 */
380 if (new_disease->title) 355 if (new_disease->title)
381 sprintf (buf, "%s %s!!", &disease->title, &victim->name); 356 buf = format ("%s %s!!", &disease->title, &victim->name);
382 else 357 else
383 sprintf (buf, "You infect %s with your disease, %s!", &victim->name, &new_disease->name); 358 buf = format ("You infect %s with your disease, %s!", &victim->name, &new_disease->name);
384 359
385 if (victim->type == PLAYER) 360 if (victim->type == PLAYER)
386 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf); 361 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf);
387 else 362 else
388 new_draw_info (0, 4, new_disease->owner, buf); 363 new_draw_info (0, 4, new_disease->owner, buf);
390 365
391 if (victim->type == PLAYER) 366 if (victim->type == PLAYER)
392 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill."); 367 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill.");
393 368
394 return 1; 369 return 1;
395
396} 370}
397 371
398/* this function monitors the symptoms caused by the disease (if any), 372/* this function monitors the symptoms caused by the disease (if any),
399causes symptoms, and modifies existing symptoms in the case of 373causes symptoms, and modifies existing symptoms in the case of
400existing diseases. */ 374existing diseases. */
423 397
424 symptom = find_symptom (disease); 398 symptom = find_symptom (disease);
425 if (!symptom) 399 if (!symptom)
426 { 400 {
427 /* no symptom? need to generate one! */ 401 /* no symptom? need to generate one! */
428 object *new_symptom;
429 402
430 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */ 403 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
431 if (!is_susceptible_to_disease (victim, disease)) 404 if (!is_susceptible_to_disease (victim, disease))
432 return 0; 405 return 0;
433 406
434 /* check for an actual immunity */ 407 /* check for an actual immunity */
435 /* do an immunity check */ 408 /* do an immunity check */
436 if (victim->head) 409 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below)
437 tmp = victim->head->inv;
438 else
439 tmp = victim->inv;
440
441 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
442 if (tmp->type == SIGN) /* possibly an immunity, or diseased */ 410 if (tmp->type == SIGN) /* possibly an immunity, or diseased */
443 if (tmp->name == disease->name && tmp->level >= disease->level) 411 if (tmp->name == disease->name && tmp->level >= disease->level)
444 return 0; /*Immune! */ 412 return 0; /* Immune! */
445 413
446 new_symptom = get_archetype ("symptom"); 414 object *new_symptom = get_archetype ("symptom");
447 415
448 /* Something special done with dam. We want diseases to be more 416 /* Something special done with dam. We want diseases to be more
449 * random in what they'll kill, so we'll make the damage they 417 * random in what they'll kill, so we'll make the damage they
450 * do random, note, this has a weird effect with progressive diseases. 418 * do random, note, this has a weird effect with progressive diseases.
451 */ 419 */
452 if (disease->stats.dam != 0) 420 if (disease->stats.dam)
453 { 421 {
454 int dam = disease->stats.dam; 422 int dam = disease->stats.dam;
455 423
456 /* reduce the damage, on average, 50%, and making things random. */ 424 /* reduce the damage, on average, 50%, and making things random. */
457 425
481 new_symptom->stats.exp = 0; 449 new_symptom->stats.exp = 0;
482 new_symptom->stats.hp = disease->stats.hp; 450 new_symptom->stats.hp = disease->stats.hp;
483 new_symptom->msg = disease->msg; 451 new_symptom->msg = disease->msg;
484 new_symptom->attacktype = disease->attacktype; 452 new_symptom->attacktype = disease->attacktype;
485 new_symptom->other_arch = disease->other_arch; 453 new_symptom->other_arch = disease->other_arch;
454 new_symptom->skill = disease->skill;
486 455
456 new_symptom->move_block = 0;
457
458 victim->head_ ()->insert (new_symptom);
459
460 // set owner last, as insert clears owner
487 new_symptom->set_owner (disease->owner); 461 new_symptom->set_owner (disease->owner);
488 462
489 if (new_symptom->skill != disease->skill)
490 new_symptom->skill = disease->skill;
491
492 new_symptom->move_block = 0;
493 insert_ob_in_ob (new_symptom, victim);
494 return 1; 463 return 1;
495 } 464 }
496 465
497 /* now deal with progressing diseases: we increase the debility 466 /* now deal with progressing diseases: we increase the debility
498 * caused by the symptoms. 467 * caused by the symptoms.
508 symptom->stats.stat (i) = clamp (int (scale * disease->stats.stat (i)), -128, 127); 477 symptom->stats.stat (i) = clamp (int (scale * disease->stats.stat (i)), -128, 127);
509 478
510 symptom->stats.dam = clamp (scale * disease->stats.dam , -1024, 1024); 479 symptom->stats.dam = clamp (scale * disease->stats.dam , -1024, 1024);
511 symptom->stats.food = clamp (scale * disease->last_eat , -1024, 1024); 480 symptom->stats.food = clamp (scale * disease->last_eat , -1024, 1024);
512 symptom->stats.maxsp = clamp (scale * disease->stats.maxsp, -1024, 1024); 481 symptom->stats.maxsp = clamp (scale * disease->stats.maxsp, -1024, 1024);
513 symptom->last_sp = clamp (scale * disease->last_sp , -1024, 1024);
514 symptom->stats.sp = clamp (scale * disease->stats.sp , -1024, 1024); 482 symptom->stats.sp = clamp (scale * disease->stats.sp , -1024, 1024);
515 symptom->stats.hp = clamp (scale * disease->stats.hp , -1024, 1024); 483 symptom->stats.hp = clamp (scale * disease->stats.hp , -1024, 1024);
516 symptom->stats.exp = 0; 484 symptom->stats.exp = 0;
517 485 symptom->last_sp = disease->last_sp ? clamp (disease->last_sp / scale, 1, 1024) : 0;
518 symptom->msg = disease->msg; 486 symptom->msg = disease->msg;
519 symptom->attacktype = disease->attacktype; 487 symptom->attacktype = disease->attacktype;
520 symptom->other_arch = disease->other_arch; 488 symptom->other_arch = disease->other_arch;
521 } 489 }
522 490
534 object *walk; 502 object *walk;
535 503
536 /* Don't give immunity to this disease if last_heal is set. */ 504 /* Don't give immunity to this disease if last_heal is set. */
537 if (disease->last_heal) 505 if (disease->last_heal)
538 return 0; 506 return 0;
507
539 /* first, search for an immunity of the same name */ 508 /* first, search for an immunity of the same name */
540 for (walk = disease->env->inv; walk; walk = walk->below) 509 for (walk = disease->env->inv; walk; walk = walk->below)
541 {
542 if (walk->type == 98 && disease->name == walk->name) 510 if (walk->type == 98 && disease->name == walk->name)
543 { 511 {
544 walk->level = disease->level; 512 walk->level = disease->level;
545 return 1; /* just update the existing immunity. */ 513 return 1; /* just update the existing immunity. */
546 } 514 }
547 } 515
548 immunity = get_archetype ("immunity"); 516 immunity = get_archetype ("immunity");
517
549 immunity->name = disease->name; 518 immunity->name = disease->name;
550 immunity->level = disease->level; 519 immunity->level = disease->level;
551 immunity->move_block = 0; 520 immunity->move_block = 0;
521
552 insert_ob_in_ob (immunity, disease->env); 522 insert_ob_in_ob (immunity, disease->env);
523
553 return 1; 524 return 1;
554
555} 525}
556
557 526
558/* make the symptom do the nasty things it does */ 527/* make the symptom do the nasty things it does */
559
560int 528int
561move_symptom (object *symptom) 529move_symptom (object *symptom)
562{ 530{
563 object *victim = symptom->env; 531 object *victim = symptom->env;
564 object *new_ob; 532 object *new_ob;
565 int sp_reduce; 533 int sp_reduce;
566 534
567 if (victim == NULL || victim->map == NULL) 535 if (!victim || !victim->map)
568 { /* outside a monster/player, die immediately */ 536 { /* outside a monster/player, die immediately */
569 symptom->destroy (); 537 symptom->destroy ();
570 return 0; 538 return 0;
571 } 539 }
572 540
573 if (symptom->stats.dam > 0) 541 if (symptom->stats.dam > 0)
574 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); 542 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
575 else 543 else
576 hit_player (victim, (int) MAX (1, -victim->stats.maxhp * symptom->stats.dam / 100.0), symptom, symptom->attacktype, 1); 544 hit_player (victim, max (1, -victim->stats.maxhp * symptom->stats.dam / 100.0), symptom, symptom->attacktype, 1);
577 545
578 if (symptom->stats.maxsp > 0) 546 if (symptom->stats.maxsp > 0)
579 sp_reduce = symptom->stats.maxsp; 547 sp_reduce = symptom->stats.maxsp;
580 else 548 else
581 sp_reduce = (int) MAX (1, victim->stats.maxsp * symptom->stats.maxsp / 100.0); 549 sp_reduce = max (1, victim->stats.maxsp * symptom->stats.maxsp / 100.0);
550
582 victim->stats.sp = MAX (0, victim->stats.sp - sp_reduce); 551 victim->stats.sp = max (0, victim->stats.sp - sp_reduce);
583 552
584 /* create the symptom "other arch" object and drop it here 553 /* create the symptom "other arch" object and drop it here
585 * under every part of the monster 554 * under every part of the monster
586 * The victim may well have died. 555 * The victim may well have died.
587 */ 556 */
588
589 if (victim->map == NULL)
590 return 0;
591 if (symptom->other_arch) 557 if (symptom->other_arch && victim->map)
592 { 558 for (object *tmp = victim->head_ (); tmp; tmp = tmp->more)
593 object *tmp;
594
595 tmp = victim;
596 if (tmp->head != NULL)
597 tmp = tmp->head;
598 for ( /*tmp initialised above */ ; tmp != NULL; tmp = tmp->more)
599 { 559 {
600 new_ob = arch_to_object (symptom->other_arch); 560 new_ob = arch_to_object (symptom->other_arch);
601 new_ob->x = tmp->x; 561 new_ob->x = tmp->x;
602 new_ob->y = tmp->y; 562 new_ob->y = tmp->y;
603 new_ob->map = victim->map; 563 new_ob->map = victim->map;
604 insert_ob_in_map (new_ob, victim->map, victim, 0); 564 insert_ob_in_map (new_ob, victim->map, victim, 0);
605 } 565 }
606 } 566
607 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); 567 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg);
608 568
609 return 1; 569 return 1;
610} 570}
611 571

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines