Crossfire Server, Trunk
disease.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 /*
21  * For DISEASES:
22  * Stat Property Definition
23  *
24  * attacktype Attack effects Attacktype of the disease. usu. AT_GODPOWER.
25  * other_arch Creation object created and dropped when symptom moved.
26  * title Message When the "disease" "infects" something, it will
27  * print "title victim!!!" to the player who owns
28  * the "disease".
29  * wc+ Infectiousness How well the plague spreads person-to-person
30  * magic+ Range range of infection
31  * Stats* Disability What stats are reduced by the disease (str con...)
32  * maxhp+ Persistence How long the disease can last OUTSIDE the host.
33  * * value TimeLeft Counter for persistence
34  * dam^ Damage How much damage it does (%?).
35  * maxgrace+ Duration How long before the disease is naturally cured.
36  * food DurCount Counter for Duration
37  *
38  * speed Speed How often the disease moves.
39  * last_sp^ Lethargy Percentage of max speed--10 = 10% speed.
40  *
41  * maxsp^ Mana deplete Saps mana.
42  * ac^ Progressiveness How the diseases increases in severity.
43  * last_eat*^ Deplete food saps food if negative
44  * last_heal GrantImmunity If nonzero, disease does NOT grant immunity
45  * when it runs out
46  *
47  * exp experience experience awarded when plague cured
48  * hp*^ ReduceRegen reduces regeneration of disease-bearer
49  * sp*^ ReduceSpRegen reduces spellpoint regeneration
50  *
51  * name Name Name of the plague
52  * msg message What the plague says when it strikes.
53  * race those affected species/race the plague strikes (* = everything)
54  * level Plague Level General description of the plague's deadliness
55  * armour Attenuation reduction in wc per generation of disease.
56  * This builds in a self-limiting factor.
57  *
58  *
59  * Explanations:
60  * * means this # should be negative to cause adverse effect.
61  * + means that this effect is modulated in spells by ldur
62  * ^ means that this effect is modulated in spells by ldam
63  *
64  * attacktype is the attacktype used by the disease to smite "dam" damage with.
65  *
66  * wc/127 is the chance of someone in range catching it.
67  *
68  * magic is the range at which infection may occur. If negative, the range is
69  * NOT level dependent.
70  *
71  * Stats are stat modifications. These should typically be negative.
72  *
73  * maxhp is how long the disease will persist if the host dies and "drops" it,
74  * in "disease moves", i.e., moves of the disease. If negative, permanent.
75  *
76  * value is the counter for maxhp, it starts at maxhp and drops...
77  *
78  * dam if positive, it is straight damage. if negative, a %-age.
79  *
80  * maxgrace how long in "disease moves" the disease lasts in the host, if negative,
81  * permanent until cured.
82  *
83  * food if negative, disease is permanent. otherwise, decreases at <speed>,
84  * disease goes away at food=0, set to "maxgrace" on infection.
85  *
86  * speed is the speed of the disease, how fast "disease moves" occur.
87  *
88  * last_sp is the lethargy imposed on the player by the disease. A lethargy
89  * of "1" reduces the players speed to 1% of its normal value.
90  *
91  * maxsp how much mana is sapped per "disease move". if negative, a %-age is
92  * taken.
93  *
94  * ac every "disease move" the severity of the symptoms are increased by
95  * ac/100. (severity = 1 + (accumlated_progression)/100)
96  *
97  * last_eat increases food usage if negative.
98  *
99  *
100  *
101  * For SYMPTOMS:
102  *
103  * Stats modify stats
104  * hp modify regen
105  * value progression counter (multiplier = value/100)
106  * food modify food use (from last_eat in DISEASE)
107  * maxsp suck mana ( as noted for DISEASE)
108  * last_sp Lethargy
109  * msg What to say
110  * speed speed of movement, from DISEASE
111  */
112 
113 #include "global.h"
114 
115 #include <assert.h>
116 #include <stdlib.h>
117 #include <string.h>
118 
119 #include "living.h"
120 #include "object.h"
121 #include "skills.h"
122 #include "sounds.h"
123 #include "spells.h"
124 #include "sproto.h"
125 
126 static void remove_symptoms(object *disease);
127 static object *find_symptom(object *disease);
128 static void check_infection(object *disease);
129 static void do_symptoms(object *disease);
130 static void grant_immunity(object *disease);
131 
132 
133 
134 /* IMPLEMENTATION NOTES
135 
136 Diseases may be contageous. They are objects which exist in a player's
137 inventory. They themselves do nothing, except modify Symptoms, or
138 spread to other live objects. Symptoms are what actually damage the player:
139 these are their own object. */
140 
153 static int is_susceptible_to_disease(object *victim, object *disease) {
154  /* Non living and DMs are immune. */
156  return 0;
157 
158  if (strstr(disease->race, "*") && !QUERY_FLAG(victim, FLAG_UNDEAD))
159  return 1;
160 
161  if ((disease->race == undead_name) && QUERY_FLAG(victim, FLAG_UNDEAD))
162  return 1;
163 
164  if ((victim->race && strstr(disease->race, victim->race))
165  || strstr(disease->race, victim->name))
166  return 1;
167 
168  return 0;
169 }
170 
180 int move_disease(object *disease) {
181  /* first task is to determine if the disease is inside or outside of someone.
182  * If outside, we decrement 'value' until we're gone.
183  */
184 
185  /* DMs don't infect, and don't suffer either. */
186  if (disease->env && QUERY_FLAG(disease->env, FLAG_WIZ))
187  return 0;
188 
189  if (disease->env == NULL) { /* we're outside of someone */
190  if (disease->stats.maxhp > 0)
191  disease->value--;
192  if (disease->value == 0) {
193  object_remove(disease);
195  return 1;
196  }
197  } else {
198  /* if we're inside a person, have the disease run its course */
199  /* negative foods denote "perpetual" diseases. */
200  if (disease->stats.food > 0) {
201  disease->stats.food--;
202  if (disease->stats.food == 0) {
203  remove_symptoms(disease); /* remove the symptoms of this disease */
204  grant_immunity(disease);
205  object_remove(disease);
207  return 1;
208  }
209  }
210  }
211  /* check to see if we infect others */
212  check_infection(disease);
213 
214  /* impose or modify the symptoms of the disease */
215  if (disease->env && is_susceptible_to_disease(disease->env, disease))
216  do_symptoms(disease);
217 
218  return 0;
219 }
220 
232 static void remove_symptoms(object *disease) {
233  object *symptom, *victim = NULL;
234 
235  assert(disease != NULL);
236 
237  while ((symptom = find_symptom(disease)) != NULL) {
238  if (!victim)
239  victim = symptom->env;
240  object_remove(symptom);
242  }
243  if (victim)
245 }
246 
255 static object *find_symptom(object *disease) {
256  assert(disease->env != NULL);
257 
258  /* check the inventory for symptoms */
259  return object_find_by_type_and_name(disease->env, SYMPTOM, disease->name);
260 }
261 
268 static void check_infection(object *disease) {
269  int x, y, range, mflags;
270  mapstruct *map, *map2;
271  int16_t i, j, i2, j2;
272 
273  range = abs(disease->magic);
274  if (disease->env) {
275  x = disease->env->x;
276  y = disease->env->y;
277  map = disease->env->map;
278  } else {
279  x = disease->x;
280  y = disease->y;
281  map = disease->map;
282  }
283 
284  if (map == NULL)
285  return;
286  for (i = x-range; i <= x+range; i++) {
287  for (j = y-range; j <= y+range; j++) {
288  mflags = get_map_flags(map, &map2, i, j, &i2, &j2);
289  if (!(mflags&P_OUT_OF_MAP) && (mflags&P_IS_ALIVE)) {
290  FOR_MAP_PREPARE(map2, i2, j2, tmp)
291  infect_object(tmp, disease, 0);
292  FOR_MAP_FINISH();
293  }
294  }
295  }
296 }
297 
317 int infect_object(object *victim, object *disease, int force) {
318  object *tmp;
319  object *new_disease;
320  object *owner;
321 
322  victim = HEAD(victim);
323 
324  /* don't infect inanimate objects */
325  if (!QUERY_FLAG(victim, FLAG_MONSTER) && !(victim->type == PLAYER))
326  return 0;
327 
328  /* check and see if victim can catch disease: diseases
329  * are specific
330  */
331  if (!is_susceptible_to_disease(victim, disease))
332  return 0;
333 
334  /* If disease is on battleground, only infect other victims on battleground.
335  Not checking results in spectators being infected, which could lead to PK. */
336  if ((disease->map && op_on_battleground(disease, NULL, NULL, NULL))
337  || (disease->env && op_on_battleground(disease->env, NULL, NULL, NULL)))
338  if (!op_on_battleground(victim, NULL, NULL, NULL))
339  return 0;
340 
341  /* roll the dice on infection before doing the inventory check! */
342  if (!force && (random_roll(0, 126, victim, PREFER_HIGH) >= disease->stats.wc))
343  return 0;
344 
345  /* do an immunity check */
346 
347  /* There used to (IMO) be a flaw in the below - it used to be the case
348  * that if level check was done for both immunity and disease. This could
349  * result in a person with multiple afflictions of the same disease
350  * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
351  * they were cast in that same order. Instead, change it so that
352  * if you diseased, you can't get diseased more.
353  */
355  if (tmp != NULL && tmp->level >= disease->level)
356  return 0; /*Immune! */
358  if (tmp != NULL)
359  return 0; /* already diseased; XXX: increase disease level? */
360 
361  /* If we've gotten this far, go ahead and infect the victim. */
362  new_disease = object_new();
363  object_copy(disease, new_disease);
364  new_disease->stats.food = disease->stats.maxgrace;
365  new_disease->value = disease->stats.maxhp;
366  new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
367 
368  /* Unfortunately, object_set_owner does the wrong thing to the skills pointers
369  * resulting in exp going into the owners *current *chosen skill.
370  */
371  owner = object_get_owner(disease);
372  if (owner) {
373  object_set_owner(new_disease, owner);
374 
375  /* Only need to update skill if different */
376  if (new_disease->skill != disease->skill) {
377  if (new_disease->skill)
378  free_string(new_disease->skill);
379  if (disease->skill)
380  new_disease->skill = add_refcount(disease->skill);
381  }
382  } else { /* for diseases which are passed by hitting, set owner and praying skill*/
383  if (disease->env && disease->env->type == PLAYER) {
384  object *player = disease->env;
385 
386  object_set_owner(new_disease, player);
387  /* the skill pointer for these diseases should already be set up -
388  * hardcoding in 'praying' is not the right approach.
389  */
390  }
391  }
392 
393  object_insert_in_ob(new_disease, victim);
394  /* This appears to be a horrible case of overloading 'NO_PASS'
395  * for meaning in the diseases.
396  */
397  new_disease->move_block = 0;
398  owner = object_get_owner(new_disease);
399  if (owner && owner->type == PLAYER) {
400  char buf[128];
401 
402  /* if the disease has a title, it has a special infection message
403  * This messages is printed in the form MESSAGE victim
404  */
405  if (new_disease->title)
406  snprintf(buf, sizeof(buf), "%s %s!!", disease->title, victim->name);
407  else
408  snprintf(buf, sizeof(buf), "You infect %s with your disease, %s!", victim->name, new_disease->name);
409 
410  if (victim->type == PLAYER)
412  buf);
413  else
415  buf);
416  }
417  if (victim->type == PLAYER)
419  "You suddenly feel ill.");
420 
421  return 1;
422 }
423 
432 static void do_symptoms(object *disease) {
433  object *symptom;
434  object *victim;
435  object *tmp;
436  victim = disease->env;
437 
438  /* This is a quick hack - for whatever reason, disease->env will point
439  * back to disease, causing endless loops. Why this happens really needs
440  * to be found, but this should at least prevent the infinite loops.
441  */
442 
443  if (victim == NULL || victim == disease)
444  return;/* no-one to inflict symptoms on */
445 
446  /* DMs don't suffer from diseases. */
447  if (QUERY_FLAG(victim, FLAG_WIZ))
448  return;
449 
450  symptom = find_symptom(disease);
451  if (symptom == NULL) {
452  /* no symptom? need to generate one! */
453  object *new_symptom;
454  int reduce_level = 0;
455 
456  /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
457  if (!is_susceptible_to_disease(victim, disease))
458  return;
459 
460  /* check for an actual immunity */
461  /* do an immunity check */
463  if (tmp != NULL) {
464  if (tmp->level >= disease->level)
465  return; /*Immune! */
466  /* partially immune */
467  reduce_level = tmp->level;
468  }
469 
470  new_symptom = create_archetype(ARCH_SYMPTOM);
471 
472  /* Something special done with dam. We want diseases to be more
473  * random in what they'll kill, so we'll make the damage they
474  * do random, note, this has a weird effect with progressive diseases.
475  */
476  if (disease->stats.dam != 0) {
477  int dam = disease->stats.dam;
478 
479  /* reduce the damage, on average, 50%, and making things random. */
480 
481  dam = random_roll(1, FABS(dam), victim, PREFER_LOW);
482  if (disease->stats.dam < 0)
483  dam = -dam;
484  new_symptom->stats.dam = dam;
485  }
486 
487  new_symptom->stats.maxsp = disease->stats.maxsp;
488  new_symptom->stats.food = new_symptom->stats.maxgrace;
489 
490  FREE_AND_COPY(new_symptom->name, disease->name);
491  FREE_AND_COPY(new_symptom->name_pl, disease->name);
492  new_symptom->level = disease->level - reduce_level;
493  new_symptom->speed = disease->speed;
494  new_symptom->value = 0;
495  new_symptom->stats.Str = disease->stats.Str;
496  new_symptom->stats.Dex = disease->stats.Dex;
497  new_symptom->stats.Con = disease->stats.Con;
498  new_symptom->stats.Wis = disease->stats.Wis;
499  new_symptom->stats.Int = disease->stats.Int;
500  new_symptom->stats.Pow = disease->stats.Pow;
501  new_symptom->stats.Cha = disease->stats.Cha;
502  new_symptom->stats.sp = disease->stats.sp;
503  new_symptom->stats.food = disease->last_eat;
504  new_symptom->stats.maxsp = disease->stats.maxsp;
505  new_symptom->last_sp = disease->last_sp;
506  new_symptom->stats.exp = 0;
507  new_symptom->stats.hp = disease->stats.hp;
508  object_set_msg(new_symptom, disease->msg);
509  new_symptom->attacktype = disease->attacktype;
510  new_symptom->other_arch = disease->other_arch;
511 
512  object_set_owner(new_symptom, object_get_owner(disease));
513  if (new_symptom->skill != disease->skill) {
514  if (new_symptom->skill)
515  free_string(new_symptom->skill);
516  if (disease->skill)
517  new_symptom->skill = add_refcount(disease->skill);
518  }
519  new_symptom->move_block = 0;
520  object_insert_in_ob(new_symptom, victim);
521  return;
522  }
523 
524  /* now deal with progressing diseases: we increase the debility
525  * caused by the symptoms.
526  */
527 
528  if (disease->stats.ac != 0) {
529  float scale;
530  int i;
531  int8_t cur_stat;
532 
533  symptom->value += disease->stats.ac;
534  scale = 1.0+symptom->value/100.0;
535  /* now rescale all the debilities */
536  for (i = 0; i<NUM_STATS; i++) {
537  cur_stat = get_attr_value(&disease->stats, i);
538  cur_stat = (int)(scale * cur_stat);
539  set_attr_value(&symptom->stats, i, cur_stat);
540  }
542 
543  symptom->stats.dam = (int)(scale*disease->stats.dam);
544  symptom->stats.sp = (int)(scale*disease->stats.sp);
545  symptom->stats.food = (int)(scale*disease->last_eat);
546  symptom->stats.maxsp = (int)(scale*disease->stats.maxsp);
547  symptom->last_sp = (int)(scale*disease->last_sp);
548  symptom->stats.exp = 0;
549  symptom->stats.hp = (int)(scale*disease->stats.hp);
550  object_set_msg(symptom, disease->msg);
551  symptom->attacktype = disease->attacktype;
552  symptom->other_arch = disease->other_arch;
553  }
554  SET_FLAG(symptom, FLAG_APPLIED);
556 }
557 
564 static void grant_immunity(object *disease) {
565  object *immunity;
566 
567  /* Don't give immunity to this disease if last_heal is set. */
568  if (disease->last_heal)
569  return;
570 
571  assert(disease->env != NULL);
572 
573  /* first, search for an immunity of the same name */
574  immunity = object_find_by_type_and_name(disease->env, SIGN, disease->name);
575  if (immunity != NULL) {
576  immunity->level = disease->level;
577  return; /* just update the existing immunity. */
578  }
579  immunity = create_archetype("immunity");
580  immunity->name = add_string(disease->name);
581  immunity->level = disease->level;
582  immunity->move_block = 0;
583  object_insert_in_ob(immunity, disease->env);
584 }
585 
592 void move_symptom(object *symptom) {
593  object *victim = symptom->env;
594  object *new_ob;
595  int sp_reduce;
596  tag_t tag = symptom->count;
597 
598  if (victim == NULL || victim->map == NULL) { /* outside a monster/player, die immediately */
599  object_remove(symptom);
601  return;
602  }
603 
604  if (symptom->stats.dam > 0)
605  hit_player(victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
606  else
607  hit_player(victim, MAX(1, -victim->stats.maxhp*symptom->stats.dam/100.0), symptom, symptom->attacktype, 1);
608 
609  /* In most cases, if the victim has been freed, the logic that
610  * does that will also free the symptom, so check for that.
611  */
612  if (QUERY_FLAG(victim, FLAG_FREED)) {
613  if (!object_was_destroyed(symptom, tag)) {
614  object_remove(symptom);
616  }
617  return;
618  }
619 
620  if (symptom->stats.maxsp > 0)
621  sp_reduce = symptom->stats.maxsp;
622  else
623  sp_reduce = MAX(1, victim->stats.maxsp*symptom->stats.maxsp/100.0);
624  victim->stats.sp = MAX(0, victim->stats.sp-sp_reduce);
625 
626  /* create the symptom "other arch" object and drop it here
627  * under every part of the monster
628  * The victim may well have died.
629  */
630 
631  if (symptom->other_arch) {
632  object *tmp;
633 
634  for (tmp = HEAD(victim); tmp != NULL; tmp = tmp->more) {
635  char name[MAX_BUF];
636 
637  new_ob = arch_to_object(symptom->other_arch);
638  snprintf(name, sizeof(name), "%s's %s", victim->name, new_ob->name);
639  FREE_AND_COPY(new_ob->name, name);
640  if (new_ob->name_pl != NULL) {
641  snprintf(name, sizeof(name), "%s's %s", victim->name, new_ob->name_pl);
642  FREE_AND_COPY(new_ob->name_pl, name);
643  }
644  object_insert_in_map_at(new_ob, tmp->map, victim, 0, tmp->x, tmp->y);
645  }
646  }
647  if (!symptom->msg) {
648  LOG(llevError, "BUG: move_symptom(): symptom %d (%s) without message!\n", symptom->count, symptom->name);
649  return;
650  }
652  symptom->msg);
653 }
654 
663 void check_physically_infect(object *victim, object *hitter) {
664  /* search for diseases, give every disease a chance to infect */
665  FOR_INV_PREPARE(hitter, walk)
666  if (walk->type == DISEASE)
667  infect_object(victim, walk, 0);
668  FOR_INV_FINISH();
669 }
670 
685 int cure_disease(object *sufferer, object *caster, sstring skill) {
686  int casting_level;
687  int cure = 0;
688 
689  if (caster)
690  casting_level = caster->level;
691  else
692  casting_level = 1000; /* if null caster, CURE all. */
693 
694  FOR_INV_PREPARE(sufferer, disease) {
695  if (disease->type == DISEASE && !QUERY_FLAG(disease, FLAG_STARTEQUIP)) {
696  /* attempt to cure this disease. God-given diseases are given by the god, so don't remove them */
697  /* If caster lvel is higher than disease level, cure chance
698  * is automatic. If lower, then the chance is basically
699  * 1 in level_diff - if there is a 5 level difference, chance
700  * is 1 in 5.
701  */
702  if ((casting_level >= disease->level)
703  || (!(random_roll(0, (disease->level-casting_level-1), caster, PREFER_LOW)))) {
704  remove_symptoms(disease);
705  object_remove(disease);
706  cure = 1;
707  if (caster)
708  change_exp(caster, disease->stats.exp, skill, 0);
710  }
711  }
712  } FOR_INV_FINISH();
713  if (cure) {
714  /* Only draw these messages once */
715  if (caster)
717  "You cure a disease!");
718 
720  "You no longer feel diseased.");
721  }
722  return cure;
723 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
PLAYER
@ PLAYER
Definition: object.h:107
global.h
add_refcount
sstring add_refcount(sstring str)
Definition: shstr.c:210
liv::dam
int16_t dam
Definition: living.h:46
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
object_remove
void object_remove(object *op)
Definition: object.c:1819
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
obj::move_block
MoveType move_block
Definition: object.h:430
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
SYMPTOM
@ SYMPTOM
Definition: object.h:245
FLAG_UNDEAD
#define FLAG_UNDEAD
Definition: define.h:270
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
infect_object
int infect_object(object *victim, object *disease, int force)
Definition: disease.c:317
diamondslots.x
x
Definition: diamondslots.py:15
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Definition: define.h:268
obj::count
tag_t count
Definition: object.h:302
obj::map
struct mapdef * map
Definition: object.h:300
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
obj::race
sstring race
Definition: object.h:321
liv::maxgrace
int16_t maxgrace
Definition: living.h:45
obj::value
int32_t value
Definition: object.h:355
liv::wc
int8_t wc
Definition: living.h:37
op_on_battleground
int op_on_battleground(object *op, int *x, int *y, archetype **trophy)
Definition: player.c:4213
liv::Str
int8_t Str
Definition: living.h:36
object_new
object * object_new(void)
Definition: object.c:1255
MSG_TYPE_ATTACK_DID_HIT
#define MSG_TYPE_ATTACK_DID_HIT
Definition: newclient.h:612
liv::maxhp
int16_t maxhp
Definition: living.h:41
pl
Definition: player.h:105
PREFER_LOW
#define PREFER_LOW
Definition: define.h:564
grant_immunity
static void grant_immunity(object *disease)
Definition: disease.c:564
liv::hp
int16_t hp
Definition: living.h:40
MSG_TYPE_ATTRIBUTE
#define MSG_TYPE_ATTRIBUTE
Definition: newclient.h:405
Ice.tmp
int tmp
Definition: Ice.py:207
NDI_RED
#define NDI_RED
Definition: newclient.h:245
SIGN
@ SIGN
Definition: object.h:211
obj::msg
sstring msg
Definition: object.h:325
skills.h
P_IS_ALIVE
#define P_IS_ALIVE
Definition: map.h:238
FLAG_APPLIED
#define FLAG_APPLIED
Definition: define.h:235
MAX
#define MAX(x, y)
Definition: compat.h:24
MSG_TYPE_SPELL_HEAL
#define MSG_TYPE_SPELL_HEAL
Definition: newclient.h:631
settings
struct Settings settings
Definition: init.c:39
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
obj::last_heal
int32_t last_heal
Definition: object.h:362
undead_name
const EXTERN char * undead_name
Definition: global.h:153
free_string
void free_string(sstring str)
Definition: shstr.c:280
liv::maxsp
int16_t maxsp
Definition: living.h:43
check_infection
static void check_infection(object *disease)
Definition: disease.c:268
liv::exp
int64_t exp
Definition: living.h:47
move_symptom
void move_symptom(object *symptom)
Definition: disease.c:592
PREFER_HIGH
#define PREFER_HIGH
Definition: define.h:563
disinfect.map
map
Definition: disinfect.py:4
obj::name
sstring name
Definition: object.h:314
cure_disease
int cure_disease(object *sufferer, object *caster, sstring skill)
Definition: disease.c:685
MSG_TYPE_ATTRIBUTE_BAD_EFFECT_START
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_START
Definition: newclient.h:565
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:1064
liv::Cha
int8_t Cha
Definition: living.h:36
obj::name_pl
sstring name_pl
Definition: object.h:318
HEAD
#define HEAD(op)
Definition: object.h:593
FLAG_FREED
#define FLAG_FREED
Definition: define.h:233
MSG_TYPE_ATTACK
#define MSG_TYPE_ATTACK
Definition: newclient.h:409
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Definition: global.h:201
obj::x
int16_t x
Definition: object.h:330
fix_object
void fix_object(object *op)
Definition: living.c:1126
CFweardisguise.tag
tag
Definition: CFweardisguise.py:25
obj::other_arch
struct archt * other_arch
Definition: object.h:418
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
sstring
const typedef char * sstring
Definition: global.h:40
obj::speed
float speed
Definition: object.h:332
tag_t
uint32_t tag_t
Definition: object.h:12
obj::env
struct obj * env
Definition: object.h:296
liv::Con
int8_t Con
Definition: living.h:36
sproto.h
liv::food
int32_t food
Definition: living.h:48
mapdef
Definition: map.h:317
MSG_TYPE_SPELL
#define MSG_TYPE_SPELL
Definition: newclient.h:411
liv::Int
int8_t Int
Definition: living.h:36
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
object_set_owner
void object_set_owner(object *op, object *owner)
Definition: object.c:844
P_OUT_OF_MAP
#define P_OUT_OF_MAP
Definition: map.h:250
MAX_BUF
#define MAX_BUF
Definition: define.h:35
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:281
random_roll
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
obj::y
int16_t y
Definition: object.h:330
obj::title
sstring title
Definition: object.h:320
object_set_msg
void object_set_msg(object *op, const char *msg)
Definition: object.c:4781
sounds.h
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
obj::type
uint8_t type
Definition: object.h:343
obj::last_grace
int16_t last_grace
Definition: object.h:364
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:262
spells.h
obj::stats
living stats
Definition: object.h:373
check_physically_infect
void check_physically_infect(object *victim, object *hitter)
Definition: disease.c:663
remove_symptoms
static void remove_symptoms(object *disease)
Definition: disease.c:232
liv::Dex
int8_t Dex
Definition: living.h:36
reputation.victim
victim
Definition: reputation.py:14
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
DISEASE
@ DISEASE
Definition: object.h:244
liv::Wis
int8_t Wis
Definition: living.h:36
check_stat_bounds
void check_stat_bounds(living *stats, int8_t min_stat, int8_t max_stat)
Definition: living.c:355
Settings::max_stat
uint8_t max_stat
Definition: global.h:319
is_susceptible_to_disease
static int is_susceptible_to_disease(object *victim, object *disease)
Definition: disease.c:153
obj::last_sp
int32_t last_sp
Definition: object.h:363
hit_player
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.c:1860
diamondslots.y
y
Definition: diamondslots.py:16
buf
StringBuffer * buf
Definition: readable.c:1610
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
change_exp
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Definition: living.c:2168
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2833
obj::last_eat
int32_t last_eat
Definition: object.h:361
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
make_face_from_files.int
int
Definition: make_face_from_files.py:26
MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
Definition: newclient.h:567
liv::ac
int8_t ac
Definition: living.h:38
obj::skill
sstring skill
Definition: object.h:324
do_symptoms
static void do_symptoms(object *disease)
Definition: disease.c:432
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:2080
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:309
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1546
move_disease
int move_disease(object *disease)
Definition: disease.c:180
object_find_by_type_and_name
object * object_find_by_type_and_name(const object *who, int type, const char *name)
Definition: object.c:4079
find_symptom
static object * find_symptom(object *disease)
Definition: disease.c:255
death_message.hitter
hitter
Definition: death_message.py:33
obj::attacktype
uint32_t attacktype
Definition: object.h:347
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:301
liv::sp
int16_t sp
Definition: living.h:42
living.h
obj::magic
int8_t magic
Definition: object.h:353
NUM_STATS
@ NUM_STATS
Definition: living.h:18
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
ARCH_SYMPTOM
#define ARCH_SYMPTOM
Definition: object.h:577
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:319
liv::Pow
int8_t Pow
Definition: living.h:36
object.h
obj::level
int16_t level
Definition: object.h:356
give.name
name
Definition: give.py:27
dragon_attune.force
force
Definition: dragon_attune.py:45
object_get_owner
object * object_get_owner(object *op)
Definition: object.c:808