ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/disease.C
Revision: 1.3
Committed: Sun Sep 3 00:18:42 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +16 -17 lines
Log Message:
THIS CODE WILL NOT COMPILE
use the STABLE tag instead.

- major changes in object lifetime and memory management
- replaced manual refcounting by shstr class
- removed quest system
- many optimisations
- major changes

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * static char *rcsid_disease_c =
3 root 1.3 * "$Id: disease.C,v 1.2 2006-08-29 08:01:37 root Exp $";
4 elmex 1.1 */
5     /*
6     CrossFire, A Multiplayer game for X-windows
7    
8     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
9     Copyright (C) 1992 Frank Tore Johansen
10    
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15    
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     GNU General Public License for more details.
20    
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24    
25     The authors can be reached via e-mail to crossfire-devel@real-time.com
26     */
27    
28     /* This file contains all the code implementing diseases,
29     except for odds and ends in attack.c and in
30 root 1.2 living.c*/
31 elmex 1.1
32    
33    
34     /*
35    
36     For DISEASES:
37     Stat Property Definition
38    
39     attacktype Attack effects Attacktype of the disease. usu. AT_GODPOWER.
40     other_arch Creation object created and dropped when symptom moved.
41     title Message When the "disease" "infects" something, it will
42     print "title victim!!!" to the player who owns
43 root 1.2 the "disease".
44 elmex 1.1 wc+ Infectiousness How well the plague spreads person-to-person
45     magic+ Range range of infection
46     Stats* Disability What stats are reduced by the disease (str con...)
47     maxhp+ Persistence How long the disease can last OUTSIDE the host.
48     value TimeLeft Counter for persistence
49     dam^ Damage How much damage it does (%?).
50     maxgrace+ Duration How long before the disease is naturally cured.
51     food DurCount Counter for Duration
52    
53     speed Speed How often the disease moves.
54     last_sp^ Lethargy Percentage of max speed--10 = 10% speed.
55    
56     maxsp^ Mana deplete Saps mana.
57     ac^ Progressiveness How the diseases increases in severity.
58     last_eat*^ Deplete food saps food if negative
59     last_heal GrantImmunity If nonzero, disease does NOT grant immunity
60     when it runs out
61    
62     exp experience experience awarded when plague cured
63     hp*^ ReduceRegen reduces regeneration of disease-bearer
64     sp*^ ReduceSpRegen reduces spellpoint regeneration
65    
66     name Name Name of the plague
67     msg message What the plague says when it strikes.
68     race those affected species/race the plague strikes (* = everything)
69     level Plague Level General description of the plague's deadliness
70     armour Attenuation reduction in wc per generation of disease.
71     This builds in a self-limiting factor.
72    
73    
74     Explanations:
75     * means this # should be negative to cause adverse effect.
76     + means that this effect is modulated in spells by ldur
77     ^ means that this effect is modulated in spells by ldam
78    
79     attacktype is the attacktype used by the disease to smite "dam" damage with.
80    
81     wc/127 is the chance of someone in range catching it.
82    
83     magic is the range at which infection may occur. If negative, the range is
84     NOT level dependent.
85    
86     Stats are stat modifications. These should typically be negative.
87    
88     maxhp is how long the disease will persist if the host dies and "drops" it,
89     in "disease moves", i.e., moves of the disease. If negative, permanent.
90    
91    
92     value is the counter for maxhp, it starts at maxhp and drops...
93    
94     dam if positive, it is straight damage. if negative, a %-age.
95    
96     maxgrace how long in "disease moves" the disease lasts in the host, if negative,
97     permanent until cured.
98    
99     food if negative, disease is permanent. otherwise, decreases at <speed>,
100     disease goes away at food=0, set to "maxgrace" on infection.
101    
102     speed is the speed of the disease, how fast "disease moves" occur.
103    
104     last_sp is the lethargy imposed on the player by the disease. A lethargy
105     of "1" reduces the players speed to 1% of its normal value.
106    
107     maxsp how much mana is sapped per "disease move". if negative, a %-age is
108     taken.
109    
110     ac every "disease move" the severity of the symptoms are increased by
111     ac/100. (severity = 1 + (accumlated_progression)/100)
112    
113     last_eat increases food usage if negative.
114    
115    
116    
117     For SYMPTOMS:
118    
119     Stats modify stats
120     hp modify regen
121     value progression counter (multiplier = value/100)
122     food modify food use (from last_eat in DISEASE)
123     maxsp suck mana ( as noted for DISEASE)
124     last_sp Lethargy
125     msg What to say
126     speed speed of movement, from DISEASE
127    
128    
129     */
130    
131    
132     #include <global.h>
133     #include <object.h>
134     #include <living.h>
135     #ifndef __CEXTRACT__
136     #include <sproto.h>
137     #endif
138     #include <spells.h>
139     #include <sounds.h>
140     #include <skills.h>
141    
142     /* IMPLEMENTATION NOTES
143 root 1.2
144     Diseases may be contageous. They are objects which exist in a player's
145 elmex 1.1 inventory. They themselves do nothing, except modify Symptoms, or
146     spread to other live objects. Symptoms are what actually damage the player:
147     these are their own object. */
148    
149     /* check if victim is susceptible to disease. */
150     static int is_susceptible_to_disease(object *victim, object *disease)
151     {
152     if(!QUERY_FLAG(victim,FLAG_ALIVE)) return 0;
153    
154     if(strstr(disease->race, "*") && !QUERY_FLAG(victim, FLAG_UNDEAD))
155 root 1.2 return 1;
156 elmex 1.1
157     if((disease->race == undead_name) && QUERY_FLAG(victim, FLAG_UNDEAD))
158 root 1.2 return 1;
159 elmex 1.1
160     if((victim->race && strstr(disease->race, victim->race)) ||
161     strstr(disease->race, victim->name))
162 root 1.2 return 1;
163 elmex 1.1
164     return 0;
165     }
166    
167     int move_disease(object *disease) {
168     /* first task is to determine if the disease is inside or outside of someone.
169     * If outside, we decrement 'value' until we're gone.
170     */
171    
172     if(disease->env==NULL) { /* we're outside of someone */
173 root 1.2 if ( disease->stats.maxhp > 0 ) disease->value--;
174     if(disease->value==0) {
175     remove_ob(disease);
176     free_object(disease);
177     return 1;
178     }
179 elmex 1.1 } else {
180 root 1.2 /* if we're inside a person, have the disease run its course */
181     /* negative foods denote "perpetual" diseases. */
182     if(disease->stats.food>0) {
183     disease->stats.food--;
184     if (disease->stats.food==0) {
185     remove_symptoms(disease); /* remove the symptoms of this disease */
186     grant_immunity(disease);
187     remove_ob(disease);
188     free_object(disease);
189     return 1;
190     }
191     }
192 elmex 1.1 }
193     /* check to see if we infect others */
194     check_infection(disease);
195    
196     /* impose or modify the symptoms of the disease */
197     if(disease->env && is_susceptible_to_disease(disease->env, disease))
198 root 1.2 do_symptoms(disease);
199 elmex 1.1
200     return 0;
201     }
202    
203     /* remove any symptoms of disease
204     * Modified by MSW 2003-03-28 do try to find all the symptom the
205     * player may have - I think through some odd interactoins with
206     * disease level and player level and whatnot, a player could get
207     * more than one symtpom to a disease.
208     */
209    
210     int remove_symptoms(object *disease) {
211     object *symptom, *victim=NULL;
212    
213     while ((symptom = find_symptom(disease)) != NULL) {
214 root 1.2 if (!victim) victim=symptom->env;
215     remove_ob(symptom);
216     free_object(symptom);
217 elmex 1.1 }
218     if(victim) fix_player(victim);
219     return 0;
220     }
221    
222     /* argument is a disease */
223     object * find_symptom(object *disease) {
224     object *walk;
225    
226     /* check the inventory for symptoms */
227     for(walk=disease->env->inv;walk;walk = walk->below)
228 root 1.2 if(!strcmp(walk->name,disease->name)&&walk->type==SYMPTOM) return walk;
229 elmex 1.1 return NULL;
230     }
231    
232     /* searches around for more victims to infect */
233     int check_infection(object *disease) {
234     int x,y,range, mflags;
235     mapstruct *map, *map2;
236     object *tmp;
237     sint16 i, j, i2, j2;
238    
239     range = abs(disease->magic);
240     if(disease->env) {
241 root 1.2 x = disease->env->x;
242     y = disease->env->y;
243     map=disease->env->map;
244 elmex 1.1 }
245     else {
246 root 1.2 x = disease->x;
247     y = disease->y;
248     map = disease->map;
249 elmex 1.1 }
250    
251     if(map == NULL) return 0;
252     for(i=x-range;i<=x+range;i++) {
253 root 1.2 for(j=y-range;j<=y+range;j++) {
254     mflags = get_map_flags(map,&map2, i,j, &i2, &j2);
255     if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) {
256     for(tmp=get_map_ob(map2,i2,j2);tmp;tmp=tmp->above) {
257     infect_object(tmp,disease,0);
258     }
259     }
260     }
261 elmex 1.1 }
262     return 1;
263     }
264    
265    
266     /* check to see if an object is infectable:
267     * objects with immunity aren't infectable.
268     * objects already infected aren't infectable.
269     * dead objects aren't infectable.
270     * undead objects are infectible only if specifically named.
271     */
272     int infect_object(object *victim, object *disease, int force) {
273     object *tmp;
274     object *new_disease;
275    
276     /* don't infect inanimate objects */
277     if(!QUERY_FLAG(victim,FLAG_MONSTER) && !(victim->type==PLAYER)) return 0;
278    
279     /* check and see if victim can catch disease: diseases
280     * are specific
281     */
282     if(!is_susceptible_to_disease(victim, disease)) return 0;
283    
284     /* roll the dice on infection before doing the inventory check! */
285     if(!force && (random_roll(0, 126, victim, PREFER_HIGH) >= disease->stats.wc))
286 root 1.2 return 0;
287 elmex 1.1
288     /* do an immunity check */
289     if(victim->head) tmp = victim->head->inv;
290     else tmp = victim->inv;
291    
292     /* There used to (IMO) be a flaw in the below - it used to be the case
293     * that if level check was done for both immunity and disease. This could
294     * result in a person with multiple afflictions of the same disease
295     * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
296     * they were cast in that same order. Instead, change it so that
297     * if you diseased, you can't get diseased more.
298     */
299    
300     for(/* tmp initialized in if, above */;tmp;tmp=tmp->below) {
301 root 1.2 if(tmp->type == SIGN && !strcmp(tmp->name,disease->name) && tmp->level >= disease->level)
302     return 0; /*Immune! */
303     else if (tmp->type==DISEASE && !strcmp(tmp->name,disease->name))
304     return 0; /* already diseased */
305 elmex 1.1 }
306    
307     /* If we've gotten this far, go ahead and infect the victim. */
308     new_disease = get_object();
309     copy_object(disease,new_disease);
310     new_disease->stats.food=disease->stats.maxgrace;
311     new_disease->value=disease->stats.maxhp;
312     new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
313    
314     /* Unfortunately, set_owner does the wrong thing to the skills pointers
315     * resulting in exp going into the owners *current* chosen skill.
316     */
317    
318     if(get_owner(disease)) {
319 root 1.2 set_owner(new_disease,disease->owner);
320 elmex 1.1
321 root 1.2 /* Only need to update skill if different */
322 root 1.3 if (new_disease->skill != disease->skill)
323     new_disease->skill = disease->skill;
324 elmex 1.1 }
325     else { /* for diseases which are passed by hitting, set owner and praying skill*/
326 root 1.2 if(disease->env && disease->env->type==PLAYER) {
327     object *player = disease->env;
328 elmex 1.1
329 root 1.2 set_owner(new_disease,player);
330     /* the skill pointer for these diseases should already be set up -
331     * hardcoding in 'praying' is not the right approach.
332     */
333     }
334 elmex 1.1 }
335    
336     insert_ob_in_ob(new_disease,victim);
337     /* This appears to be a horrible case of overloading 'NO_PASS'
338     * for meaning in the diseases.
339     */
340     new_disease->move_block = 0;
341     if(new_disease->owner && new_disease->owner->type==PLAYER) {
342 root 1.2 char buf[128];
343     /* if the disease has a title, it has a special infection message
344     * This messages is printed in the form MESSAGE victim
345     */
346     if(new_disease->title)
347 root 1.3 sprintf(buf,"%s %s!!",&disease->title,&victim->name);
348 root 1.2 else
349 root 1.3 sprintf(buf,"You infect %s with your disease, %s!",&victim->name,&new_disease->name);
350 root 1.2
351     if(victim->type == PLAYER)
352     new_draw_info(NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf);
353     else
354     new_draw_info(0, 4, new_disease->owner, buf);
355 elmex 1.1 }
356     if(victim->type==PLAYER)
357 root 1.2 new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,"You suddenly feel ill.");
358 elmex 1.1
359     return 1;
360    
361     }
362    
363    
364    
365     /* this function monitors the symptoms caused by the disease (if any),
366     causes symptoms, and modifies existing symptoms in the case of
367     existing diseases. */
368    
369     int do_symptoms(object *disease) {
370     object *symptom;
371     object *victim;
372     object *tmp;
373     victim = disease->env;
374    
375     /* This is a quick hack - for whatever reason, disease->env will point
376     * back to disease, causing endless loops. Why this happens really needs
377     * to be found, but this should at least prevent the infinite loops.
378     */
379    
380     if(victim == NULL || victim==disease)
381 root 1.2 return 0;/* no-one to inflict symptoms on */
382 elmex 1.1
383     symptom = find_symptom(disease);
384     if(symptom==NULL) {
385 root 1.2 /* no symptom? need to generate one! */
386     object *new_symptom;
387 elmex 1.1
388 root 1.2 /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
389     if(!is_susceptible_to_disease(victim, disease)) return 0;
390 elmex 1.1
391 root 1.2 /* check for an actual immunity */
392     /* do an immunity check */
393     if(victim->head) tmp = victim->head->inv;
394     else tmp = victim->inv;
395    
396     for(/* tmp initialized in if, above */;tmp;tmp=tmp->below) {
397     if(tmp->type == SIGN) /* possibly an immunity, or diseased*/
398     if(!strcmp(tmp->name,disease->name) && tmp->level >= disease->level)
399     return 0; /*Immune! */
400     }
401    
402     new_symptom = get_archetype(ARCH_SYMPTOM);
403    
404     /* Something special done with dam. We want diseases to be more
405     * random in what they'll kill, so we'll make the damage they
406     * do random, note, this has a weird effect with progressive diseases.
407     */
408     if(disease->stats.dam != 0) {
409     int dam = disease->stats.dam;
410    
411     /* reduce the damage, on average, 50%, and making things random. */
412    
413     dam = random_roll(1, FABS(dam), victim, PREFER_LOW);
414     if(disease->stats.dam < 0) dam = -dam;
415     new_symptom->stats.dam = dam;
416     }
417 elmex 1.1
418    
419 root 1.2 new_symptom->stats.maxsp = disease->stats.maxsp;
420     new_symptom->stats.food = new_symptom->stats.maxgrace;
421 elmex 1.1
422 root 1.3 new_symptom->name =
423     new_symptom->name_pl = disease->name;
424    
425 root 1.2 new_symptom->level = disease->level;
426     new_symptom->speed = disease->speed;
427     new_symptom->value = 0;
428     new_symptom->stats.Str =disease->stats.Str;
429     new_symptom->stats.Dex = disease->stats.Dex;
430     new_symptom->stats.Con = disease->stats.Con;
431     new_symptom->stats.Wis = disease->stats.Wis;
432     new_symptom->stats.Int = disease->stats.Int;
433     new_symptom->stats.Pow = disease->stats.Pow;
434     new_symptom->stats.Cha = disease->stats.Cha;
435     new_symptom->stats.sp = disease->stats.sp;
436     new_symptom->stats.food =disease->last_eat;
437     new_symptom->stats.maxsp = disease->stats.maxsp;
438     new_symptom->last_sp = disease->last_sp;
439     new_symptom->stats.exp = 0;
440     new_symptom->stats.hp = disease->stats.hp;
441 root 1.3 new_symptom->msg = disease->msg;
442 root 1.2 new_symptom->attacktype = disease->attacktype;
443     new_symptom->other_arch = disease->other_arch;
444    
445     set_owner(new_symptom,disease->owner);
446 root 1.3
447     if (new_symptom->skill != disease->skill)
448     new_symptom->skill = disease->skill;
449    
450 root 1.2 new_symptom->move_block=0;
451     insert_ob_in_ob(new_symptom,victim);
452     return 1;
453 elmex 1.1 }
454    
455     /* now deal with progressing diseases: we increase the debility
456     * caused by the symptoms.
457     */
458    
459     if(disease->stats.ac!=0) {
460 root 1.2 float scale;
461 elmex 1.1
462 root 1.2 symptom->value += disease->stats.ac;
463     scale = 1.0 + symptom->value/100.0;
464     /* now rescale all the debilities */
465     symptom->stats.Str = (int) (scale*disease->stats.Str);
466     symptom->stats.Dex = (int) (scale*disease->stats.Dex);
467     symptom->stats.Con = (int) (scale*disease->stats.Con);
468     symptom->stats.Wis = (int) (scale*disease->stats.Wis);
469     symptom->stats.Int = (int) (scale*disease->stats.Int);
470     symptom->stats.Pow = (int) (scale*disease->stats.Pow);
471     symptom->stats.Cha = (int) (scale*disease->stats.Cha);
472     symptom->stats.dam = (int) (scale*disease->stats.dam);
473     symptom->stats.sp = (int) (scale*disease->stats.sp);
474     symptom->stats.food = (int) (scale*disease->last_eat);
475     symptom->stats.maxsp = (int) (scale*disease->stats.maxsp);
476     symptom->last_sp = (int) (scale*disease->last_sp);
477     symptom->stats.exp = 0;
478     symptom->stats.hp = (int) (scale*disease->stats.hp);
479 root 1.3 symptom->msg = disease->msg;
480 root 1.2 symptom->attacktype = disease->attacktype;
481     symptom->other_arch = disease->other_arch;
482 elmex 1.1 }
483     SET_FLAG(symptom,FLAG_APPLIED);
484     fix_player(victim);
485     return 1;
486     }
487    
488    
489     /* grants immunity to plagues we've seen before. */
490     int grant_immunity(object *disease) {
491     object * immunity;
492     object *walk;
493     /* Don't give immunity to this disease if last_heal is set. */
494     if(disease->last_heal) return 0;
495     /* first, search for an immunity of the same name */
496     for(walk=disease->env->inv;walk;walk=walk->below) {
497 root 1.2 if(walk->type==98 && !strcmp(disease->name,walk->name)) {
498     walk->level = disease->level;
499     return 1; /* just update the existing immunity. */
500     }
501 elmex 1.1 }
502     immunity = get_archetype("immunity");
503 root 1.3 immunity->name = disease->name;
504 elmex 1.1 immunity->level = disease->level;
505     immunity->move_block = 0;
506     insert_ob_in_ob(immunity,disease->env);
507     return 1;
508    
509     }
510    
511    
512     /* make the symptom do the nasty things it does */
513    
514     int move_symptom(object *symptom) {
515     object *victim = symptom->env;
516     object *new_ob;
517     int sp_reduce;
518    
519     if(victim == NULL || victim->map==NULL) { /* outside a monster/player, die immediately */
520 root 1.2 remove_ob(symptom);
521     free_object(symptom);
522     return 0;
523 elmex 1.1 }
524    
525     if(symptom->stats.dam > 0) hit_player(victim,symptom->stats.dam,symptom,symptom->attacktype,1);
526     else hit_player(victim,(int) MAX(1,-victim->stats.maxhp * symptom->stats.dam / 100.0),symptom,symptom->attacktype,1);
527    
528     if(symptom->stats.maxsp>0) sp_reduce = symptom->stats.maxsp;
529     else sp_reduce = (int) MAX(1,victim->stats.maxsp * symptom->stats.maxsp/100.0);
530     victim->stats.sp = MAX(0,victim->stats.sp - sp_reduce);
531    
532     /* create the symptom "other arch" object and drop it here
533     * under every part of the monster
534     * The victim may well have died.
535     */
536    
537     if(victim->map==NULL) return 0;
538     if(symptom->other_arch) {
539 root 1.2 object *tmp;
540     tmp=victim;
541     if(tmp->head!=NULL) tmp=tmp->head;
542     for(/*tmp initialized above */;tmp!=NULL;tmp=tmp->more) {
543     new_ob = arch_to_object(symptom->other_arch);
544     new_ob->x = tmp->x;
545     new_ob->y = tmp->y;
546     new_ob->map = victim->map;
547     insert_ob_in_map(new_ob,victim->map,victim,0);
548     }
549 elmex 1.1 }
550     new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,symptom->msg);
551    
552     return 1;
553     }
554    
555    
556     /* possibly infect due to direct physical contact
557     i.e., AT_PHYSICAL-- called from "hit_player_attacktype" */
558    
559     int check_physically_infect(object *victim, object *hitter) {
560     object *walk;
561     /* search for diseases, give every disease a chance to infect */
562     for(walk=hitter->inv;walk!=NULL;walk=walk->below)
563 root 1.2 if(walk->type==DISEASE) infect_object(victim,walk,0);
564 elmex 1.1 return 1;
565     }
566    
567     /* find a disease in someone*/
568     object *find_disease(object *victim) {
569     object *walk;
570     for(walk=victim->inv;walk;walk=walk->below)
571 root 1.2 if(walk->type==DISEASE) return walk;
572 elmex 1.1 return NULL;
573     }
574 root 1.2
575 elmex 1.1 /* do the cure disease stuff, from the spell "cure disease" */
576    
577     int cure_disease(object *sufferer,object *caster) {
578     object *disease, *next;
579     int casting_level;
580     int cure=0;
581    
582     if(caster) casting_level = caster->level;
583     else casting_level = 1000; /* if null caster, CURE all. */
584    
585     for(disease=sufferer->inv;disease;disease=next) {
586 root 1.2 next=disease->below;
587 elmex 1.1
588 root 1.2 if(disease->type==DISEASE) { /* attempt to cure this disease */
589     /* If caster lvel is higher than disease level, cure chance
590     * is automatic. If lower, then the chance is basically
591     * 1 in level_diff - if there is a 5 level difference, chance
592     * is 1 in 5.
593     */
594     if ((casting_level >= disease->level) ||
595     ( ! (random_roll(0, (disease->level - casting_level - 1),
596     caster, PREFER_LOW) ))) {
597    
598     remove_symptoms(disease);
599     remove_ob(disease);
600     cure=1;
601     if(caster) change_exp(caster,disease->stats.exp,
602 root 1.3 caster->chosen_skill ? &caster->chosen_skill->skill : (const char *)0, 0);
603 root 1.2 free_object(disease);
604     }
605     }
606 elmex 1.1 }
607     if (cure) {
608 root 1.2 /* Only draw these messages once */
609     if (caster)
610     new_draw_info_format(NDI_UNIQUE,0,caster,"You cure a disease!");
611     new_draw_info(NDI_UNIQUE,0,sufferer,"You no longer feel diseased.");
612 elmex 1.1 }
613     return 1;
614     }
615    
616     /* reduces disease progression: reduce_symptoms
617     * return true if we actually reduce a disease.
618     */
619    
620     int reduce_symptoms(object *sufferer, int reduction) {
621     object *walk;
622     int success=0;
623    
624     for(walk=sufferer->inv;walk;walk=walk->below) {
625 root 1.2 if(walk->type==SYMPTOM) {
626     if(walk->value > 0) {
627     success=1;
628     walk->value = MAX(0,walk->value - 2*reduction);
629     /* give the disease time to modify this symptom,
630     * and reduce its severity. */
631     walk->speed_left = 0;
632     }
633     }
634 elmex 1.1 }
635     if (success)
636 root 1.2 new_draw_info(NDI_UNIQUE,0,sufferer,"Your illness seems less severe.");
637 elmex 1.1 return success;
638     }
639