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.4 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.31 by root, Tue Aug 7 22:57:57 2007 UTC

1
2/* 1/*
3 * static char *rcsid_disease_c = 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
4 * "$Id: disease.C,v 1.4 2006/09/10 15:59:57 root Exp $"; 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
5 */ 22 */
6 23
7/*
8 CrossFire, A Multiplayer game for X-windows
9
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 The authors can be reached via e-mail to crossfire-devel@real-time.com
28*/
29
30/* This file contains all the code implementing diseases, 24/* This file contains all the code implementing diseases,
31 except for odds and ends in attack.c and in 25 * except for odds and ends in attack.c and in
32 living.c*/ 26 * living.c
33 27 */
34
35 28
36/* 29/*
37 30
38For DISEASES: 31For DISEASES:
39Stat Property Definition 32Stat Property Definition
132 125
133 126
134#include <global.h> 127#include <global.h>
135#include <object.h> 128#include <object.h>
136#include <living.h> 129#include <living.h>
137#ifndef __CEXTRACT__
138# include <sproto.h> 130#include <sproto.h>
139#endif
140#include <spells.h> 131#include <spells.h>
141#include <sounds.h> 132#include <sounds.h>
142#include <skills.h> 133#include <skills.h>
143 134
144/* IMPLEMENTATION NOTES 135/* IMPLEMENTATION NOTES
156 return 0; 147 return 0;
157 148
158 if (strstr (disease->race, "*") && !QUERY_FLAG (victim, FLAG_UNDEAD)) 149 if (strstr (disease->race, "*") && !QUERY_FLAG (victim, FLAG_UNDEAD))
159 return 1; 150 return 1;
160 151
161 if ((disease->race == undead_name) && QUERY_FLAG (victim, FLAG_UNDEAD)) 152 if ((disease->race == shstr_undead) && QUERY_FLAG (victim, FLAG_UNDEAD))
162 return 1; 153 return 1;
163 154
164 if ((victim->race && strstr (disease->race, victim->race)) || strstr (disease->race, victim->name)) 155 if ((victim->race && strstr (disease->race, victim->race)) || strstr (disease->race, victim->name))
165 return 1; 156 return 1;
166 157
172{ 163{
173 /* first task is to determine if the disease is inside or outside of someone. 164 /* first task is to determine if the disease is inside or outside of someone.
174 * If outside, we decrement 'value' until we're gone. 165 * If outside, we decrement 'value' until we're gone.
175 */ 166 */
176 167
177 if (disease->env == NULL) 168 if (!disease->env)
178 { /* we're outside of someone */ 169 { /* we're outside of someone */
179 if (disease->stats.maxhp > 0) 170 if (disease->stats.maxhp > 0)
180 disease->value--; 171 disease->value--;
172
181 if (disease->value == 0) 173 if (!disease->value)
182 { 174 {
183 remove_ob (disease); 175 disease->destroy ();
184 free_object (disease);
185 return 1; 176 return 1;
186 } 177 }
187 } 178 }
188 else 179 else
189 { 180 {
190 /* if we're inside a person, have the disease run its course */ 181 /* if we're inside a person, have the disease run its course */
191 /* negative foods denote "perpetual" diseases. */ 182 /* negative/zero food denotes "perpetual" diseases. */
192 if (disease->stats.food > 0) 183 if (disease->stats.food > 0)
193 { 184 {
194 disease->stats.food--; 185 disease->stats.food--;
186
195 if (disease->stats.food == 0) 187 if (!disease->stats.food)
196 { 188 {
197 remove_symptoms (disease); /* remove the symptoms of this disease */ 189 remove_symptoms (disease); /* remove the symptoms of this disease */
198 grant_immunity (disease); 190 grant_immunity (disease);
199 remove_ob (disease); 191 disease->destroy ();
200 free_object (disease);
201 return 1; 192 return 1;
202 } 193 }
203 } 194 }
204 } 195 }
196
205 /* check to see if we infect others */ 197 /* check to see if we infect others */
206 check_infection (disease); 198 check_infection (disease);
207 199
208 /* impose or modify the symptoms of the disease */ 200 /* impose or modify the symptoms of the disease */
209 if (disease->env && is_susceptible_to_disease (disease->env, disease)) 201 if (disease->env && is_susceptible_to_disease (disease->env, disease))
226 218
227 while ((symptom = find_symptom (disease)) != NULL) 219 while ((symptom = find_symptom (disease)) != NULL)
228 { 220 {
229 if (!victim) 221 if (!victim)
230 victim = symptom->env; 222 victim = symptom->env;
231 remove_ob (symptom); 223
232 free_object (symptom); 224 symptom->destroy ();
233 } 225 }
226
234 if (victim) 227 if (victim)
235 fix_player (victim); 228 victim->update_stats ();
229
236 return 0; 230 return 0;
237} 231}
238 232
239/* argument is a disease */ 233/* argument is a disease */
240object * 234object *
242{ 236{
243 object *walk; 237 object *walk;
244 238
245 /* check the inventory for symptoms */ 239 /* check the inventory for symptoms */
246 for (walk = disease->env->inv; walk; walk = walk->below) 240 for (walk = disease->env->inv; walk; walk = walk->below)
247 if (!strcmp (walk->name, disease->name) && walk->type == SYMPTOM) 241 if (walk->name == disease->name && walk->type == SYMPTOM)
248 return walk; 242 return walk;
243
249 return NULL; 244 return NULL;
250} 245}
251 246
252/* searches around for more victims to infect */ 247/* searches around for more victims to infect */
253int 248int
254check_infection (object *disease) 249check_infection (object *disease)
255{ 250{
256 int x, y, range, mflags; 251 int x, y, range, mflags;
257 mapstruct *map, *map2; 252 maptile *map, *map2;
258 object *tmp; 253 object *tmp;
259 sint16 i, j, i2, j2;
260 254
261 range = abs (disease->magic); 255 range = abs (disease->magic);
256
262 if (disease->env) 257 if (disease->env)
263 { 258 {
264 x = disease->env->x; 259 x = disease->env->x;
265 y = disease->env->y; 260 y = disease->env->y;
266 map = disease->env->map; 261 map = disease->env->map;
267 } 262 }
268 else 263 else
269 { 264 {
270 x = disease->x; 265 x = disease->x;
271 y = disease->y; 266 y = disease->y;
272 map = disease->map; 267 map = disease->map;
273 } 268 }
274 269
275 if (map == NULL) 270 if (!map)
276 return 0; 271 return 0;
272
277 for (i = x - range; i <= x + range; i++) 273 for (int i = x - range; i <= x + range; i++)
278 {
279 for (j = y - range; j <= y + range; j++) 274 for (int j = y - range; j <= y + range; j++)
280 { 275 {
276 sint16 i2, j2;
281 mflags = get_map_flags (map, &map2, i, j, &i2, &j2); 277 mflags = get_map_flags (map, &map2, i, j, &i2, &j2);
278
282 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) 279 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE))
283 {
284 for (tmp = get_map_ob (map2, i2, j2); tmp; tmp = tmp->above) 280 for (tmp = GET_MAP_OB (map2, i2, j2); tmp; tmp = tmp->above)
285 {
286 infect_object (tmp, disease, 0); 281 infect_object (tmp, disease, 0);
287 }
288 }
289 } 282 }
290 } 283
291 return 1; 284 return 1;
292} 285}
293 286
294 287
295/* check to see if an object is infectable: 288/* check to see if an object is infectable:
330 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as 323 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
331 * they were cast in that same order. Instead, change it so that 324 * they were cast in that same order. Instead, change it so that
332 * if you diseased, you can't get diseased more. 325 * if you diseased, you can't get diseased more.
333 */ 326 */
334 327
335 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 328 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
336 { 329 {
337 if (tmp->type == SIGN && !strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 330 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level)
338 return 0; /*Immune! */ 331 return 0; /* Immune! */
339 else if (tmp->type == DISEASE && !strcmp (tmp->name, disease->name)) 332 else if (tmp->type == DISEASE && tmp->name == disease->name)
340 return 0; /* already diseased */ 333 return 0; /* already diseased */
341 } 334 }
342 335
343 /* If we've gotten this far, go ahead and infect the victim. */ 336 /* If we've gotten this far, go ahead and infect the victim. */
344 new_disease = get_object (); 337 new_disease = disease->clone ();
345 copy_object (disease, new_disease);
346 new_disease->stats.food = disease->stats.maxgrace; 338 new_disease->stats.food = disease->stats.maxgrace;
347 new_disease->value = disease->stats.maxhp; 339 new_disease->value = disease->stats.maxhp;
348 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */ 340 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
349 341
350 /* Unfortunately, set_owner does the wrong thing to the skills pointers 342 /* Unfortunately, set_owner does the wrong thing to the skills pointers
351 * resulting in exp going into the owners *current* chosen skill. 343 * resulting in exp going into the owners *current* chosen skill.
352 */ 344 */
353 345
354 if (get_owner (disease)) 346 if (disease->owner)
355 { 347 {
356 set_owner (new_disease, disease->owner); 348 new_disease->set_owner (disease->owner);
357 349
358 /* Only need to update skill if different */ 350 /* Only need to update skill if different */
359 if (new_disease->skill != disease->skill) 351 if (new_disease->skill != disease->skill)
360 new_disease->skill = disease->skill; 352 new_disease->skill = disease->skill;
361 } 353 }
363 { /* for diseases which are passed by hitting, set owner and praying skill */ 355 { /* for diseases which are passed by hitting, set owner and praying skill */
364 if (disease->env && disease->env->type == PLAYER) 356 if (disease->env && disease->env->type == PLAYER)
365 { 357 {
366 object *player = disease->env; 358 object *player = disease->env;
367 359
368 set_owner (new_disease, player); 360 new_disease->set_owner (player);
369 361
370 /* the skill pointer for these diseases should already be set up - 362 /* the skill pointer for these diseases should already be set up -
371 * hardcoding in 'praying' is not the right approach. 363 * hardcoding in 'praying' is not the right approach.
372 */ 364 */
373 } 365 }
374 } 366 }
375 367
376 insert_ob_in_ob (new_disease, victim); 368 insert_ob_in_ob (new_disease, victim->head_ ());
377 /* This appears to be a horrible case of overloading 'NO_PASS' 369 /* This appears to be a horrible case of overloading 'NO_PASS'
378 * for meaning in the diseases. 370 * for meaning in the diseases.
379 */ 371 */
380 new_disease->move_block = 0; 372 new_disease->move_block = 0;
381 if (new_disease->owner && new_disease->owner->type == PLAYER) 373 if (new_disease->owner && new_disease->owner->type == PLAYER)
393 if (victim->type == PLAYER) 385 if (victim->type == PLAYER)
394 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf); 386 new_draw_info (NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf);
395 else 387 else
396 new_draw_info (0, 4, new_disease->owner, buf); 388 new_draw_info (0, 4, new_disease->owner, buf);
397 } 389 }
390
398 if (victim->type == PLAYER) 391 if (victim->type == PLAYER)
399 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill."); 392 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, "You suddenly feel ill.");
400 393
401 return 1; 394 return 1;
402 395
403} 396}
404
405
406 397
407/* this function monitors the symptoms caused by the disease (if any), 398/* this function monitors the symptoms caused by the disease (if any),
408causes symptoms, and modifies existing symptoms in the case of 399causes symptoms, and modifies existing symptoms in the case of
409existing diseases. */ 400existing diseases. */
410
411int 401int
412do_symptoms (object *disease) 402do_symptoms (object *disease)
413{ 403{
414 object *symptom; 404 object *symptom;
415 object *victim; 405 object *victim;
416 object *tmp; 406 object *tmp;
417 407
418 victim = disease->env; 408 victim = disease->env;
409
410 if (!victim)
411 return 0; /* no-one to inflict symptoms on */
419 412
420 /* This is a quick hack - for whatever reason, disease->env will point 413 /* This is a quick hack - for whatever reason, disease->env will point
421 * back to disease, causing endless loops. Why this happens really needs 414 * back to disease, causing endless loops. Why this happens really needs
422 * to be found, but this should at least prevent the infinite loops. 415 * to be found, but this should at least prevent the infinite loops.
423 */ 416 */
424 417 //TODO: should no longer be the case, monitor, and remove
425 if (victim == NULL || victim == disease) 418 if (victim == disease)
426 return 0; /* no-one to inflict symptoms on */ 419 {
420 LOG (llevError | logBacktrace, "%s: disease->env points to itself", disease->debug_desc ());
421 return 0;
422 }
427 423
428 symptom = find_symptom (disease); 424 symptom = find_symptom (disease);
429 if (symptom == NULL) 425 if (!symptom)
430 { 426 {
431 /* no symptom? need to generate one! */ 427 /* no symptom? need to generate one! */
432 object *new_symptom; 428 object *new_symptom;
433 429
434 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */ 430 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
440 if (victim->head) 436 if (victim->head)
441 tmp = victim->head->inv; 437 tmp = victim->head->inv;
442 else 438 else
443 tmp = victim->inv; 439 tmp = victim->inv;
444 440
445 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 441 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
446 {
447 if (tmp->type == SIGN) /* possibly an immunity, or diseased */ 442 if (tmp->type == SIGN) /* possibly an immunity, or diseased */
448 if (!strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 443 if (tmp->name == disease->name && tmp->level >= disease->level)
449 return 0; /*Immune! */ 444 return 0; /*Immune! */
450 }
451 445
452 new_symptom = get_archetype (ARCH_SYMPTOM); 446 new_symptom = get_archetype ("symptom");
453 447
454 /* Something special done with dam. We want diseases to be more 448 /* Something special done with dam. We want diseases to be more
455 * random in what they'll kill, so we'll make the damage they 449 * random in what they'll kill, so we'll make the damage they
456 * do random, note, this has a weird effect with progressive diseases. 450 * do random, note, this has a weird effect with progressive diseases.
457 */ 451 */
459 { 453 {
460 int dam = disease->stats.dam; 454 int dam = disease->stats.dam;
461 455
462 /* reduce the damage, on average, 50%, and making things random. */ 456 /* reduce the damage, on average, 50%, and making things random. */
463 457
464 dam = random_roll (1, FABS (dam), victim, PREFER_LOW); 458 dam = random_roll (1, abs (dam), victim, PREFER_LOW);
465 if (disease->stats.dam < 0) 459 if (disease->stats.dam < 0)
466 dam = -dam; 460 dam = -dam;
461
467 new_symptom->stats.dam = dam; 462 new_symptom->stats.dam = dam;
468 } 463 }
469 464
470
471 new_symptom->stats.maxsp = disease->stats.maxsp; 465 new_symptom->stats.maxsp = disease->stats.maxsp;
472 new_symptom->stats.food = new_symptom->stats.maxgrace; 466 new_symptom->stats.food = new_symptom->stats.maxgrace;
473 467
474 new_symptom->name = new_symptom->name_pl = disease->name; 468 new_symptom->name = new_symptom->name_pl = disease->name;
475 469
476 new_symptom->level = disease->level; 470 new_symptom->level = disease->level;
477 new_symptom->speed = disease->speed; 471 new_symptom->speed = disease->speed;
478 new_symptom->value = 0; 472 new_symptom->value = 0;
473
474 for (int i = 0; i < NUM_STATS; ++i)
479 new_symptom->stats.Str = disease->stats.Str; 475 new_symptom->stats.stat (i) = disease->stats.stat (i);
480 new_symptom->stats.Dex = disease->stats.Dex; 476
481 new_symptom->stats.Con = disease->stats.Con;
482 new_symptom->stats.Wis = disease->stats.Wis;
483 new_symptom->stats.Int = disease->stats.Int;
484 new_symptom->stats.Pow = disease->stats.Pow;
485 new_symptom->stats.Cha = disease->stats.Cha;
486 new_symptom->stats.sp = disease->stats.sp; 477 new_symptom->stats.sp = disease->stats.sp;
487 new_symptom->stats.food = disease->last_eat; 478 new_symptom->stats.food = disease->last_eat;
488 new_symptom->stats.maxsp = disease->stats.maxsp; 479 new_symptom->stats.maxsp = disease->stats.maxsp;
489 new_symptom->last_sp = disease->last_sp; 480 new_symptom->last_sp = disease->last_sp;
490 new_symptom->stats.exp = 0; 481 new_symptom->stats.exp = 0;
491 new_symptom->stats.hp = disease->stats.hp; 482 new_symptom->stats.hp = disease->stats.hp;
492 new_symptom->msg = disease->msg; 483 new_symptom->msg = disease->msg;
493 new_symptom->attacktype = disease->attacktype; 484 new_symptom->attacktype = disease->attacktype;
494 new_symptom->other_arch = disease->other_arch; 485 new_symptom->other_arch = disease->other_arch;
495 486
496 set_owner (new_symptom, disease->owner); 487 new_symptom->set_owner (disease->owner);
497 488
498 if (new_symptom->skill != disease->skill) 489 if (new_symptom->skill != disease->skill)
499 new_symptom->skill = disease->skill; 490 new_symptom->skill = disease->skill;
500 491
501 new_symptom->move_block = 0; 492 new_symptom->move_block = 0;
502 insert_ob_in_ob (new_symptom, victim); 493 insert_ob_in_ob (new_symptom, victim);
503 return 1; 494 return 1;
504 } 495 }
505 496
506 /* now deal with progressing diseases: we increase the debility 497 /* now deal with progressing diseases: we increase the debility
507 * caused by the symptoms. 498 * caused by the symptoms.
508 */ 499 */
509
510 if (disease->stats.ac != 0) 500 if (disease->stats.ac)
511 { 501 {
512 float scale; 502 symptom->value = clamp (symptom->value + disease->stats.ac, 0, 100*100);
513 503
514 symptom->value += disease->stats.ac;
515 scale = 1.0 + symptom->value / 100.0; 504 float scale = 1.f + symptom->value / 100.f;
505
516 /* now rescale all the debilities */ 506 /* now rescale all the debilities */
517 symptom->stats.Str = (int) (scale * disease->stats.Str); 507 for (int i = 0; i < NUM_STATS; ++i)
518 symptom->stats.Dex = (int) (scale * disease->stats.Dex); 508 symptom->stats.stat (i) = clamp (int (scale * disease->stats.stat (i)), -128, 127);
519 symptom->stats.Con = (int) (scale * disease->stats.Con); 509
520 symptom->stats.Wis = (int) (scale * disease->stats.Wis);
521 symptom->stats.Int = (int) (scale * disease->stats.Int);
522 symptom->stats.Pow = (int) (scale * disease->stats.Pow);
523 symptom->stats.Cha = (int) (scale * disease->stats.Cha);
524 symptom->stats.dam = (int) (scale * disease->stats.dam); 510 symptom->stats.dam = clamp (scale * disease->stats.dam , -1024, 1024);
525 symptom->stats.sp = (int) (scale * disease->stats.sp);
526 symptom->stats.food = (int) (scale * disease->last_eat); 511 symptom->stats.food = clamp (scale * disease->last_eat , -1024, 1024);
527 symptom->stats.maxsp = (int) (scale * disease->stats.maxsp); 512 symptom->stats.maxsp = clamp (scale * disease->stats.maxsp, -1024, 1024);
528 symptom->last_sp = (int) (scale * disease->last_sp); 513 symptom->last_sp = clamp (scale * disease->last_sp , -1024, 1024);
514 symptom->stats.sp = clamp (scale * disease->stats.sp , -1024, 1024);
515 symptom->stats.hp = clamp (scale * disease->stats.hp , -1024, 1024);
529 symptom->stats.exp = 0; 516 symptom->stats.exp = 0;
530 symptom->stats.hp = (int) (scale * disease->stats.hp); 517
531 symptom->msg = disease->msg; 518 symptom->msg = disease->msg;
532 symptom->attacktype = disease->attacktype; 519 symptom->attacktype = disease->attacktype;
533 symptom->other_arch = disease->other_arch; 520 symptom->other_arch = disease->other_arch;
534 } 521 }
522
535 SET_FLAG (symptom, FLAG_APPLIED); 523 SET_FLAG (symptom, FLAG_APPLIED);
536 fix_player (victim); 524 victim->update_stats ();
525
537 return 1; 526 return 1;
538} 527}
539
540 528
541/* grants immunity to plagues we've seen before. */ 529/* grants immunity to plagues we've seen before. */
542int 530int
543grant_immunity (object *disease) 531grant_immunity (object *disease)
544{ 532{
549 if (disease->last_heal) 537 if (disease->last_heal)
550 return 0; 538 return 0;
551 /* first, search for an immunity of the same name */ 539 /* first, search for an immunity of the same name */
552 for (walk = disease->env->inv; walk; walk = walk->below) 540 for (walk = disease->env->inv; walk; walk = walk->below)
553 { 541 {
554 if (walk->type == 98 && !strcmp (disease->name, walk->name)) 542 if (walk->type == 98 && disease->name == walk->name)
555 { 543 {
556 walk->level = disease->level; 544 walk->level = disease->level;
557 return 1; /* just update the existing immunity. */ 545 return 1; /* just update the existing immunity. */
558 } 546 }
559 } 547 }
576 object *new_ob; 564 object *new_ob;
577 int sp_reduce; 565 int sp_reduce;
578 566
579 if (victim == NULL || victim->map == NULL) 567 if (victim == NULL || victim->map == NULL)
580 { /* outside a monster/player, die immediately */ 568 { /* outside a monster/player, die immediately */
581 remove_ob (symptom); 569 symptom->destroy ();
582 free_object (symptom);
583 return 0; 570 return 0;
584 } 571 }
585 572
586 if (symptom->stats.dam > 0) 573 if (symptom->stats.dam > 0)
587 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); 574 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
606 object *tmp; 593 object *tmp;
607 594
608 tmp = victim; 595 tmp = victim;
609 if (tmp->head != NULL) 596 if (tmp->head != NULL)
610 tmp = tmp->head; 597 tmp = tmp->head;
611 for ( /*tmp initialized above */ ; tmp != NULL; tmp = tmp->more) 598 for ( /*tmp initialised above */ ; tmp != NULL; tmp = tmp->more)
612 { 599 {
613 new_ob = arch_to_object (symptom->other_arch); 600 new_ob = arch_to_object (symptom->other_arch);
614 new_ob->x = tmp->x; 601 new_ob->x = tmp->x;
615 new_ob->y = tmp->y; 602 new_ob->y = tmp->y;
616 new_ob->map = victim->map; 603 new_ob->map = victim->map;
620 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); 607 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg);
621 608
622 return 1; 609 return 1;
623} 610}
624 611
625
626/* possibly infect due to direct physical contact 612/* possibly infect due to direct physical contact
627 i.e., AT_PHYSICAL-- called from "hit_player_attacktype" */ 613 * i.e., AT_PHYSICAL-- called from "hit_player_attacktype" */
628
629int 614int
630check_physically_infect (object *victim, object *hitter) 615check_physically_infect (object *victim, object *hitter)
631{ 616{
632 object *walk;
633
634 /* search for diseases, give every disease a chance to infect */ 617 /* search for diseases, give every disease a chance to infect */
635 for (walk = hitter->inv; walk != NULL; walk = walk->below) 618 for (object *disease = hitter->inv; disease; disease = disease->below)
636 if (walk->type == DISEASE) 619 if (disease->type == DISEASE)
637 infect_object (victim, walk, 0); 620 infect_object (victim, disease, 0);
621
638 return 1; 622 return 1;
639} 623}
640 624
641/* find a disease in someone*/ 625// find a disease in someone
642object * 626object *
643find_disease (object *victim) 627find_disease (object *victim)
644{ 628{
645 object *walk; 629 for (object *disease = victim->inv; disease; disease = disease->below)
646
647 for (walk = victim->inv; walk; walk = walk->below)
648 if (walk->type == DISEASE) 630 if (disease->type == DISEASE)
649 return walk; 631 return disease;
632
650 return NULL; 633 return 0;
651} 634}
652 635
653/* do the cure disease stuff, from the spell "cure disease" */ 636/* do the cure disease stuff, from the spell "cure disease" */
654
655int 637int
656cure_disease (object *sufferer, object *caster) 638cure_disease (object *sufferer, object *caster)
657{ 639{
658 object *disease, *next; 640 object *disease, *next;
659 int casting_level; 641 int casting_level;
668 { 650 {
669 next = disease->below; 651 next = disease->below;
670 652
671 if (disease->type == DISEASE) 653 if (disease->type == DISEASE)
672 { /* attempt to cure this disease */ 654 { /* attempt to cure this disease */
673 /* If caster lvel is higher than disease level, cure chance 655 /* If caster level is higher than disease level, cure chance
674 * is automatic. If lower, then the chance is basically 656 * is automatic. If lower, then the chance is basically
675 * 1 in level_diff - if there is a 5 level difference, chance 657 * 1 in level_diff - if there is a 5 level difference, chance
676 * is 1 in 5. 658 * is 1 in 5.
677 */ 659 */
678 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW)))) 660 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW))))
679 { 661 {
680
681 remove_symptoms (disease); 662 remove_symptoms (disease);
682 remove_ob (disease);
683 cure = 1; 663 cure = 1;
664
684 if (caster) 665 if (caster)
685 change_exp (caster, disease->stats.exp, caster->chosen_skill ? &caster->chosen_skill->skill : (const char *) 0, 0); 666 change_exp (caster, disease->stats.exp, caster->chosen_skill ? caster->chosen_skill->skill : (const char *) 0, 0);
686 free_object (disease); 667
668 disease->destroy ();
687 } 669 }
688 } 670 }
689 } 671 }
672
690 if (cure) 673 if (cure)
691 { 674 {
692 /* Only draw these messages once */ 675 /* Only draw these messages once */
693 if (caster) 676 if (caster)
694 new_draw_info_format (NDI_UNIQUE, 0, caster, "You cure a disease!"); 677 new_draw_info_format (NDI_UNIQUE, 0, caster, "You cure a disease!");
678
695 new_draw_info (NDI_UNIQUE, 0, sufferer, "You no longer feel diseased."); 679 new_draw_info (NDI_UNIQUE, 0, sufferer, "You no longer feel diseased.");
696 } 680 }
681
697 return 1; 682 return 1;
698} 683}
699 684
700/* reduces disease progression: reduce_symptoms 685/* reduces disease progression: reduce_symptoms
701 * return true if we actually reduce a disease. 686 * return true if we actually reduce a disease.
702 */ 687 */
703
704int 688int
705reduce_symptoms (object *sufferer, int reduction) 689reduce_symptoms (object *sufferer, int reduction)
706{ 690{
707 object *walk; 691 object *walk;
708 int success = 0; 692 int success = 0;
712 if (walk->type == SYMPTOM) 696 if (walk->type == SYMPTOM)
713 { 697 {
714 if (walk->value > 0) 698 if (walk->value > 0)
715 { 699 {
716 success = 1; 700 success = 1;
717 walk->value = MAX (0, walk->value - 2 * reduction); 701 walk->value = max (0, walk->value - 2 * reduction);
718 /* give the disease time to modify this symptom, 702 /* give the disease time to modify this symptom,
719 * and reduce its severity. */ 703 * and reduce its severity. */
720 walk->speed_left = 0; 704 walk->speed_left = 0;
721 } 705 }
722 } 706 }
723 } 707 }
708
724 if (success) 709 if (success)
725 new_draw_info (NDI_UNIQUE, 0, sufferer, "Your illness seems less severe."); 710 new_draw_info (NDI_UNIQUE, 0, sufferer, "Your illness seems less severe.");
711
726 return success; 712 return success;
727} 713}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines