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.37 by root, Thu Aug 23 18:55:02 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
232 232
233/* argument is a disease */ 233/* argument is a disease */
234object * 234object *
235find_symptom (object *disease) 235find_symptom (object *disease)
236{ 236{
237 object *walk;
238
239 /* check the inventory for symptoms */ 237 /* check the inventory for symptoms */
240 for (walk = disease->env->inv; walk; walk = walk->below) 238 for (object *walk = disease->env->inv; walk; walk = walk->below)
241 if (walk->name == disease->name && walk->type == SYMPTOM) 239 if (walk->name == disease->name && walk->type == SYMPTOM)
242 return walk; 240 return walk;
243 241
244 return NULL; 242 return NULL;
245} 243}
281 infect_object (tmp, disease, 0); 279 infect_object (tmp, disease, 0);
282 } 280 }
283 281
284 return 1; 282 return 1;
285} 283}
286
287 284
288/* check to see if an object is infectable: 285/* check to see if an object is infectable:
289 * objects with immunity aren't infectable. 286 * objects with immunity aren't infectable.
290 * objects already infected aren't infectable. 287 * objects already infected aren't infectable.
291 * dead objects aren't infectable. 288 * dead objects aren't infectable.
310 /* roll the dice on infection before doing the inventory check! */ 307 /* roll the dice on infection before doing the inventory check! */
311 if (!force && (random_roll (0, 126, victim, PREFER_HIGH) >= disease->stats.wc)) 308 if (!force && (random_roll (0, 126, victim, PREFER_HIGH) >= disease->stats.wc))
312 return 0; 309 return 0;
313 310
314 /* do an immunity check */ 311 /* do an immunity check */
315 if (victim->head)
316 tmp = victim->head->inv;
317 else
318 tmp = victim->inv;
319 312
320 /* There used to (IMO) be a flaw in the below - it used to be the case 313 /* 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 314 * 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 315 * 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 316 * (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 317 * they were cast in that same order. Instead, change it so that
325 * if you diseased, you can't get diseased more. 318 * if you diseased, you can't get diseased more.
326 */ 319 */
327 320
328 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below) 321 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below)
329 {
330 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level) 322 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level)
331 return 0; /* Immune! */ 323 return 0; /* Immune! */
332 else if (tmp->type == DISEASE && tmp->name == disease->name) 324 else if (tmp->type == DISEASE && tmp->name == disease->name)
333 return 0; /* already diseased */ 325 return 0; /* already diseased */
334 }
335 326
336 /* If we've gotten this far, go ahead and infect the victim. */ 327 /* If we've gotten this far, go ahead and infect the victim. */
328
337 new_disease = disease->clone (); 329 new_disease = disease->clone ();
330
338 new_disease->stats.food = disease->stats.maxgrace; 331 new_disease->stats.food = disease->stats.maxgrace;
339 new_disease->value = disease->stats.maxhp; 332 new_disease->value = disease->stats.maxhp;
340 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */ 333 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
341 334
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' 335 /* This appears to be a horrible case of overloading 'NO_PASS'
370 * for meaning in the diseases. 336 * for meaning in the diseases.
371 */ 337 */
372 new_disease->move_block = 0; 338 new_disease->move_block = 0;
339
340 // insert before setting the owner
341 victim->head_ ()->insert (new_disease);
342
343 if (disease->owner)
344 new_disease->set_owner (disease->owner);
345 else if (object *pl = disease->in_player ())
346 /* for diseases which are passed by hitting, set owner and skill */
347 new_disease->set_owner (pl);
348
373 if (new_disease->owner && new_disease->owner->type == PLAYER) 349 if (new_disease->owner && new_disease->owner->type == PLAYER)
374 { 350 {
375 char buf[128]; 351 const char *buf;
376 352
377 /* if the disease has a title, it has a special infection message 353 /* if the disease has a title, it has a special infection message
378 * This messages is printed in the form MESSAGE victim 354 * This messages is printed in the form MESSAGE victim
379 */ 355 */
380 if (new_disease->title) 356 if (new_disease->title)
381 sprintf (buf, "%s %s!!", &disease->title, &victim->name); 357 buf = format ("%s %s!!", &disease->title, &victim->name);
382 else 358 else
383 sprintf (buf, "You infect %s with your disease, %s!", &victim->name, &new_disease->name); 359 buf = format ("You infect %s with your disease, %s!", &victim->name, &new_disease->name);
384 360
385 if (victim->type == PLAYER) 361 if (victim->type == PLAYER)
386 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf); 362 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf);
387 else 363 else
388 new_draw_info (0, 4, new_disease->owner, buf); 364 new_draw_info (0, 4, new_disease->owner, buf);
390 366
391 if (victim->type == PLAYER) 367 if (victim->type == PLAYER)
392 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill."); 368 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill.");
393 369
394 return 1; 370 return 1;
395
396} 371}
397 372
398/* this function monitors the symptoms caused by the disease (if any), 373/* this function monitors the symptoms caused by the disease (if any),
399causes symptoms, and modifies existing symptoms in the case of 374causes symptoms, and modifies existing symptoms in the case of
400existing diseases. */ 375existing diseases. */
423 398
424 symptom = find_symptom (disease); 399 symptom = find_symptom (disease);
425 if (!symptom) 400 if (!symptom)
426 { 401 {
427 /* no symptom? need to generate one! */ 402 /* no symptom? need to generate one! */
428 object *new_symptom;
429 403
430 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */ 404 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
431 if (!is_susceptible_to_disease (victim, disease)) 405 if (!is_susceptible_to_disease (victim, disease))
432 return 0; 406 return 0;
433 407
434 /* check for an actual immunity */ 408 /* check for an actual immunity */
435 /* do an immunity check */ 409 /* do an immunity check */
436 if (victim->head) 410 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 */ 411 if (tmp->type == SIGN) /* possibly an immunity, or diseased */
443 if (tmp->name == disease->name && tmp->level >= disease->level) 412 if (tmp->name == disease->name && tmp->level >= disease->level)
444 return 0; /*Immune! */ 413 return 0; /* Immune! */
445 414
446 new_symptom = get_archetype ("symptom"); 415 object *new_symptom = get_archetype ("symptom");
447 416
448 /* Something special done with dam. We want diseases to be more 417 /* 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 418 * 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. 419 * do random, note, this has a weird effect with progressive diseases.
451 */ 420 */
452 if (disease->stats.dam != 0) 421 if (disease->stats.dam)
453 { 422 {
454 int dam = disease->stats.dam; 423 int dam = disease->stats.dam;
455 424
456 /* reduce the damage, on average, 50%, and making things random. */ 425 /* reduce the damage, on average, 50%, and making things random. */
457 426
481 new_symptom->stats.exp = 0; 450 new_symptom->stats.exp = 0;
482 new_symptom->stats.hp = disease->stats.hp; 451 new_symptom->stats.hp = disease->stats.hp;
483 new_symptom->msg = disease->msg; 452 new_symptom->msg = disease->msg;
484 new_symptom->attacktype = disease->attacktype; 453 new_symptom->attacktype = disease->attacktype;
485 new_symptom->other_arch = disease->other_arch; 454 new_symptom->other_arch = disease->other_arch;
455 new_symptom->skill = disease->skill;
486 456
457 new_symptom->move_block = 0;
458
459 victim->head_ ()->insert (new_symptom);
460
461 // set owner last, as insert clears owner
487 new_symptom->set_owner (disease->owner); 462 new_symptom->set_owner (disease->owner);
488 463
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; 464 return 1;
495 } 465 }
496 466
497 /* now deal with progressing diseases: we increase the debility 467 /* now deal with progressing diseases: we increase the debility
498 * caused by the symptoms. 468 * caused by the symptoms.
508 symptom->stats.stat (i) = clamp (int (scale * disease->stats.stat (i)), -128, 127); 478 symptom->stats.stat (i) = clamp (int (scale * disease->stats.stat (i)), -128, 127);
509 479
510 symptom->stats.dam = clamp (scale * disease->stats.dam , -1024, 1024); 480 symptom->stats.dam = clamp (scale * disease->stats.dam , -1024, 1024);
511 symptom->stats.food = clamp (scale * disease->last_eat , -1024, 1024); 481 symptom->stats.food = clamp (scale * disease->last_eat , -1024, 1024);
512 symptom->stats.maxsp = clamp (scale * disease->stats.maxsp, -1024, 1024); 482 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); 483 symptom->stats.sp = clamp (scale * disease->stats.sp , -1024, 1024);
515 symptom->stats.hp = clamp (scale * disease->stats.hp , -1024, 1024); 484 symptom->stats.hp = clamp (scale * disease->stats.hp , -1024, 1024);
516 symptom->stats.exp = 0; 485 symptom->stats.exp = 0;
517 486 symptom->last_sp = disease->last_sp ? clamp (disease->last_sp / scale, 1, 1024) : 0;
518 symptom->msg = disease->msg; 487 symptom->msg = disease->msg;
519 symptom->attacktype = disease->attacktype; 488 symptom->attacktype = disease->attacktype;
520 symptom->other_arch = disease->other_arch; 489 symptom->other_arch = disease->other_arch;
521 } 490 }
522 491
534 object *walk; 503 object *walk;
535 504
536 /* Don't give immunity to this disease if last_heal is set. */ 505 /* Don't give immunity to this disease if last_heal is set. */
537 if (disease->last_heal) 506 if (disease->last_heal)
538 return 0; 507 return 0;
508
539 /* first, search for an immunity of the same name */ 509 /* first, search for an immunity of the same name */
540 for (walk = disease->env->inv; walk; walk = walk->below) 510 for (walk = disease->env->inv; walk; walk = walk->below)
541 {
542 if (walk->type == 98 && disease->name == walk->name) 511 if (walk->type == 98 && disease->name == walk->name)
543 { 512 {
544 walk->level = disease->level; 513 walk->level = disease->level;
545 return 1; /* just update the existing immunity. */ 514 return 1; /* just update the existing immunity. */
546 } 515 }
547 } 516
548 immunity = get_archetype ("immunity"); 517 immunity = get_archetype ("immunity");
518
549 immunity->name = disease->name; 519 immunity->name = disease->name;
550 immunity->level = disease->level; 520 immunity->level = disease->level;
551 immunity->move_block = 0; 521 immunity->move_block = 0;
522
552 insert_ob_in_ob (immunity, disease->env); 523 insert_ob_in_ob (immunity, disease->env);
524
553 return 1; 525 return 1;
554
555} 526}
556
557 527
558/* make the symptom do the nasty things it does */ 528/* make the symptom do the nasty things it does */
559
560int 529int
561move_symptom (object *symptom) 530move_symptom (object *symptom)
562{ 531{
563 object *victim = symptom->env; 532 object *victim = symptom->env;
564 object *new_ob; 533 object *new_ob;
565 int sp_reduce; 534 int sp_reduce;
566 535
567 if (victim == NULL || victim->map == NULL) 536 if (!victim || !victim->map)
568 { /* outside a monster/player, die immediately */ 537 { /* outside a monster/player, die immediately */
569 symptom->destroy (); 538 symptom->destroy ();
570 return 0; 539 return 0;
571 } 540 }
572 541
573 if (symptom->stats.dam > 0) 542 if (symptom->stats.dam > 0)
574 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); 543 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
575 else 544 else
576 hit_player (victim, (int) MAX (1, -victim->stats.maxhp * symptom->stats.dam / 100.0), symptom, symptom->attacktype, 1); 545 hit_player (victim, max (1, -victim->stats.maxhp * symptom->stats.dam / 100.0), symptom, symptom->attacktype, 1);
577 546
578 if (symptom->stats.maxsp > 0) 547 if (symptom->stats.maxsp > 0)
579 sp_reduce = symptom->stats.maxsp; 548 sp_reduce = symptom->stats.maxsp;
580 else 549 else
581 sp_reduce = (int) MAX (1, victim->stats.maxsp * symptom->stats.maxsp / 100.0); 550 sp_reduce = max (1, victim->stats.maxsp * symptom->stats.maxsp / 100.0);
551
582 victim->stats.sp = MAX (0, victim->stats.sp - sp_reduce); 552 victim->stats.sp = max (0, victim->stats.sp - sp_reduce);
583 553
584 /* create the symptom "other arch" object and drop it here 554 /* create the symptom "other arch" object and drop it here
585 * under every part of the monster 555 * under every part of the monster
586 * The victim may well have died. 556 * The victim may well have died.
587 */ 557 */
588
589 if (victim->map == NULL)
590 return 0;
591 if (symptom->other_arch) 558 if (symptom->other_arch && victim->map)
592 { 559 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 { 560 {
600 new_ob = arch_to_object (symptom->other_arch); 561 new_ob = arch_to_object (symptom->other_arch);
601 new_ob->x = tmp->x; 562 new_ob->x = tmp->x;
602 new_ob->y = tmp->y; 563 new_ob->y = tmp->y;
603 new_ob->map = victim->map; 564 new_ob->map = victim->map;
604 insert_ob_in_map (new_ob, victim->map, victim, 0); 565 insert_ob_in_map (new_ob, victim->map, victim, 0);
605 } 566 }
606 } 567
607 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); 568 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg);
608 569
609 return 1; 570 return 1;
610} 571}
611 572

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines