ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/disease.C
Revision: 1.69
Committed: Tue Jan 3 11:25:36 2012 UTC (12 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.68: +1 -1 lines
Log Message:
update copyrights to 2012

File Contents

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