Crossfire Server, Branches 1.12  R18729
disease.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_disease_c =
3  * "$Id: disease.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 /*
6  CrossFire, A Multiplayer game for X-windows
7 
8  Copyright (C) 2006 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 
34 /*
35  * For DISEASES:
36  * Stat Property Definition
37  *
38  * attacktype Attack effects Attacktype of the disease. usu. AT_GODPOWER.
39  * other_arch Creation object created and dropped when symptom moved.
40  * title Message When the "disease" "infects" something, it will
41  * print "title victim!!!" to the player who owns
42  * the "disease".
43  * wc+ Infectiousness How well the plague spreads person-to-person
44  * magic+ Range range of infection
45  * Stats* Disability What stats are reduced by the disease (str con...)
46  * maxhp+ Persistence How long the disease can last OUTSIDE the host.
47  * * value TimeLeft Counter for persistence
48  * dam^ Damage How much damage it does (%?).
49  * maxgrace+ Duration How long before the disease is naturally cured.
50  * food DurCount Counter for Duration
51  *
52  * speed Speed How often the disease moves.
53  * last_sp^ Lethargy Percentage of max speed--10 = 10% speed.
54  *
55  * maxsp^ Mana deplete Saps mana.
56  * ac^ Progressiveness How the diseases increases in severity.
57  * last_eat*^ Deplete food saps food if negative
58  * last_heal GrantImmunity If nonzero, disease does NOT grant immunity
59  * when it runs out
60  *
61  * exp experience experience awarded when plague cured
62  * hp*^ ReduceRegen reduces regeneration of disease-bearer
63  * sp*^ ReduceSpRegen reduces spellpoint regeneration
64  *
65  * name Name Name of the plague
66  * msg message What the plague says when it strikes.
67  * race those affected species/race the plague strikes (* = everything)
68  * level Plague Level General description of the plague's deadliness
69  * armour Attenuation reduction in wc per generation of disease.
70  * This builds in a self-limiting factor.
71  *
72  *
73  * Explanations:
74  * * means this # should be negative to cause adverse effect.
75  * + means that this effect is modulated in spells by ldur
76  * ^ means that this effect is modulated in spells by ldam
77  *
78  * attacktype is the attacktype used by the disease to smite "dam" damage with.
79  *
80  * wc/127 is the chance of someone in range catching it.
81  *
82  * magic is the range at which infection may occur. If negative, the range is
83  * NOT level dependent.
84  *
85  * Stats are stat modifications. These should typically be negative.
86  *
87  * maxhp is how long the disease will persist if the host dies and "drops" it,
88  * in "disease moves", i.e., moves of the disease. If negative, permanent.
89  *
90  * value is the counter for maxhp, it starts at maxhp and drops...
91  *
92  * dam if positive, it is straight damage. if negative, a %-age.
93  *
94  * maxgrace how long in "disease moves" the disease lasts in the host, if negative,
95  * permanent until cured.
96  *
97  * food if negative, disease is permanent. otherwise, decreases at <speed>,
98  * disease goes away at food=0, set to "maxgrace" on infection.
99  *
100  * speed is the speed of the disease, how fast "disease moves" occur.
101  *
102  * last_sp is the lethargy imposed on the player by the disease. A lethargy
103  * of "1" reduces the players speed to 1% of its normal value.
104  *
105  * maxsp how much mana is sapped per "disease move". if negative, a %-age is
106  * taken.
107  *
108  * ac every "disease move" the severity of the symptoms are increased by
109  * ac/100. (severity = 1 + (accumlated_progression)/100)
110  *
111  * last_eat increases food usage if negative.
112  *
113  *
114  *
115  * For SYMPTOMS:
116  *
117  * Stats modify stats
118  * hp modify regen
119  * value progression counter (multiplier = value/100)
120  * food modify food use (from last_eat in DISEASE)
121  * maxsp suck mana ( as noted for DISEASE)
122  * last_sp Lethargy
123  * msg What to say
124  * speed speed of movement, from DISEASE
125  */
126 
127 #include <global.h>
128 #include <object.h>
129 #include <living.h>
130 #ifndef __CEXTRACT__
131 #include <sproto.h>
132 #endif
133 #include <spells.h>
134 #include <sounds.h>
135 #include <skills.h>
136 #include <assert.h>
137 
138 static void remove_symptoms(object *disease);
139 static object *find_symptom(object *disease);
140 static void check_infection(object *disease);
141 static void do_symptoms(object *disease);
142 static void grant_immunity(object *disease);
143 
144 
145 
146 /* IMPLEMENTATION NOTES
147 
148 Diseases may be contageous. They are objects which exist in a player's
149 inventory. They themselves do nothing, except modify Symptoms, or
150 spread to other live objects. Symptoms are what actually damage the player:
151 these are their own object. */
152 
165 static int is_susceptible_to_disease(object *victim, object *disease) {
166  /* Non living and DMs are immune. */
167  if (!QUERY_FLAG(victim, FLAG_ALIVE) || QUERY_FLAG(victim, FLAG_WIZ))
168  return 0;
169 
170  if (strstr(disease->race, "*") && !QUERY_FLAG(victim, FLAG_UNDEAD))
171  return 1;
172 
173  if ((disease->race == undead_name) && QUERY_FLAG(victim, FLAG_UNDEAD))
174  return 1;
175 
176  if ((victim->race && strstr(disease->race, victim->race))
177  || strstr(disease->race, victim->name))
178  return 1;
179 
180  return 0;
181 }
182 
192 int move_disease(object *disease) {
193  /* first task is to determine if the disease is inside or outside of someone.
194  * If outside, we decrement 'value' until we're gone.
195  */
196 
197  /* DMs don't infect, and don't suffer either. */
198  if (disease->env && QUERY_FLAG(disease->env, FLAG_WIZ))
199  return 0;
200 
201  if (disease->env == NULL) { /* we're outside of someone */
202  if (disease->stats.maxhp > 0)
203  disease->value--;
204  if (disease->value == 0) {
205  remove_ob(disease);
206  free_object(disease);
207  return 1;
208  }
209  } else {
210  /* if we're inside a person, have the disease run its course */
211  /* negative foods denote "perpetual" diseases. */
212  if (disease->stats.food > 0) {
213  disease->stats.food--;
214  if (disease->stats.food == 0) {
215  remove_symptoms(disease); /* remove the symptoms of this disease */
216  grant_immunity(disease);
217  remove_ob(disease);
218  free_object(disease);
219  return 1;
220  }
221  }
222  }
223  /* check to see if we infect others */
224  check_infection(disease);
225 
226  /* impose or modify the symptoms of the disease */
227  if (disease->env && is_susceptible_to_disease(disease->env, disease))
228  do_symptoms(disease);
229 
230  return 0;
231 }
232 
244 static void remove_symptoms(object *disease) {
245  object *symptom, *victim = NULL;
246 
247  assert(disease != NULL);
248 
249  while ((symptom = find_symptom(disease)) != NULL) {
250  if (!victim)
251  victim = symptom->env;
252  remove_ob(symptom);
253  free_object(symptom);
254  }
255  if (victim)
256  fix_object(victim);
257 }
258 
267 static object *find_symptom(object *disease) {
268  object *walk;
269 
270  assert(disease->env != NULL);
271 
272  /* check the inventory for symptoms */
273  for (walk = disease->env->inv; walk; walk = walk->below)
274  if (!strcmp(walk->name, disease->name) && walk->type == SYMPTOM)
275  return walk;
276  return NULL;
277 }
278 
285 static void check_infection(object *disease) {
286  int x, y, range, mflags;
287  mapstruct *map, *map2;
288  object *tmp;
289  sint16 i, j, i2, j2;
290 
291  range = abs(disease->magic);
292  if (disease->env) {
293  x = disease->env->x;
294  y = disease->env->y;
295  map = disease->env->map;
296  } else {
297  x = disease->x;
298  y = disease->y;
299  map = disease->map;
300  }
301 
302  if (map == NULL)
303  return;
304  for (i = x-range; i <= x+range; i++) {
305  for (j = y-range; j <= y+range; j++) {
306  mflags = get_map_flags(map, &map2, i, j, &i2, &j2);
307  if (!(mflags&P_OUT_OF_MAP) && (mflags&P_IS_ALIVE)) {
308  for (tmp = GET_MAP_OB(map2, i2, j2); tmp; tmp = tmp->above) {
309  infect_object(tmp, disease, 0);
310  }
311  }
312  }
313  }
314  return;
315 }
316 
336 int infect_object(object *victim, object *disease, int force) {
337  object *tmp;
338  object *new_disease;
339 
340  /* don't infect inanimate objects */
341  if (!QUERY_FLAG(victim, FLAG_MONSTER) && !(victim->type == PLAYER))
342  return 0;
343 
344  /* check and see if victim can catch disease: diseases
345  * are specific
346  */
347  if (!is_susceptible_to_disease(victim, disease))
348  return 0;
349 
350  /* If disease is on battleground, only infect other victims on battleground.
351  Not checking results in spectators being infected, which could lead to PK. */
352  if ((disease->map && op_on_battleground(disease, NULL, NULL, NULL))
353  || (disease->env && op_on_battleground(disease->env, NULL, NULL, NULL)))
354  if (!op_on_battleground(victim, NULL, NULL, NULL))
355  return 0;
356 
357  /* roll the dice on infection before doing the inventory check! */
358  if (!force && (random_roll(0, 126, victim, PREFER_HIGH) >= disease->stats.wc))
359  return 0;
360 
361  /* do an immunity check */
362  if (victim->head)
363  tmp = victim->head->inv;
364  else
365  tmp = victim->inv;
366 
367  /* There used to (IMO) be a flaw in the below - it used to be the case
368  * that if level check was done for both immunity and disease. This could
369  * result in a person with multiple afflictions of the same disease
370  * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
371  * they were cast in that same order. Instead, change it so that
372  * if you diseased, you can't get diseased more.
373  */
374 
375  for (/* tmp initialized in if, above */; tmp; tmp = tmp->below) {
376  if (tmp->type == SIGN && !strcmp(tmp->name, disease->name) && tmp->level >= disease->level)
377  return 0; /*Immune! */
378  else if (tmp->type == DISEASE && !strcmp(tmp->name, disease->name))
379  return 0; /* already diseased */
380  }
381 
382  /* If we've gotten this far, go ahead and infect the victim. */
383  new_disease = get_object();
384  copy_object(disease, new_disease);
385  new_disease->stats.food = disease->stats.maxgrace;
386  new_disease->value = disease->stats.maxhp;
387  new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
388 
389  /* Unfortunately, set_owner does the wrong thing to the skills pointers
390  * resulting in exp going into the owners *current *chosen skill.
391  */
392 
393  if (get_owner(disease)) {
394  set_owner(new_disease, disease->owner);
395 
396  /* Only need to update skill if different */
397  if (new_disease->skill != disease->skill) {
398  if (new_disease->skill)
399  free_string(new_disease->skill);
400  if (disease->skill)
401  new_disease->skill = add_refcount(disease->skill);
402  }
403  } else { /* for diseases which are passed by hitting, set owner and praying skill*/
404  if (disease->env && disease->env->type == PLAYER) {
405  object *player = disease->env;
406 
407  set_owner(new_disease, player);
408  /* the skill pointer for these diseases should already be set up -
409  * hardcoding in 'praying' is not the right approach.
410  */
411  }
412  }
413 
414  insert_ob_in_ob(new_disease, victim);
415  /* This appears to be a horrible case of overloading 'NO_PASS'
416  * for meaning in the diseases.
417  */
418  new_disease->move_block = 0;
419  if (new_disease->owner && new_disease->owner->type == PLAYER) {
420  char buf[128];
421 
422  /* if the disease has a title, it has a special infection message
423  * This messages is printed in the form MESSAGE victim
424  */
425  if (new_disease->title)
426  snprintf(buf, sizeof(buf), "%s %s!!", disease->title, victim->name);
427  else
428  snprintf(buf, sizeof(buf), "You infect %s with your disease, %s!", victim->name, new_disease->name);
429 
430  if (victim->type == PLAYER)
432  buf, buf);
433  else
435  buf, buf);
436  }
437  if (victim->type == PLAYER)
439  "You suddenly feel ill.", NULL);
440 
441  return 1;
442 }
443 
452 static void do_symptoms(object *disease) {
453  object *symptom;
454  object *victim;
455  object *tmp;
456  victim = disease->env;
457 
458  /* This is a quick hack - for whatever reason, disease->env will point
459  * back to disease, causing endless loops. Why this happens really needs
460  * to be found, but this should at least prevent the infinite loops.
461  */
462 
463  if (victim == NULL || victim == disease)
464  return;/* no-one to inflict symptoms on */
465 
466  /* DMs don't suffer from diseases. */
467  if (QUERY_FLAG(victim, FLAG_WIZ))
468  return;
469 
470  symptom = find_symptom(disease);
471  if (symptom == NULL) {
472  /* no symptom? need to generate one! */
473  object *new_symptom;
474 
475  /* first check and see if the carrier of the disease is immune. If so, no symptoms! */
476  if (!is_susceptible_to_disease(victim, disease))
477  return;
478 
479  /* check for an actual immunity */
480  /* do an immunity check */
481  if (victim->head)
482  tmp = victim->head->inv;
483  else
484  tmp = victim->inv;
485 
486  for (/* tmp initialized in if, above */; tmp; tmp = tmp->below) {
487  if (tmp->type == SIGN) /* possibly an immunity, or diseased*/
488  if (!strcmp(tmp->name, disease->name) && tmp->level >= disease->level)
489  return; /*Immune! */
490  }
491 
492  new_symptom = create_archetype(ARCH_SYMPTOM);
493 
494  /* Something special done with dam. We want diseases to be more
495  * random in what they'll kill, so we'll make the damage they
496  * do random, note, this has a weird effect with progressive diseases.
497  */
498  if (disease->stats.dam != 0) {
499  int dam = disease->stats.dam;
500 
501  /* reduce the damage, on average, 50%, and making things random. */
502 
503  dam = random_roll(1, FABS(dam), victim, PREFER_LOW);
504  if (disease->stats.dam < 0)
505  dam = -dam;
506  new_symptom->stats.dam = dam;
507  }
508 
509  new_symptom->stats.maxsp = disease->stats.maxsp;
510  new_symptom->stats.food = new_symptom->stats.maxgrace;
511 
512  FREE_AND_COPY(new_symptom->name, disease->name);
513  FREE_AND_COPY(new_symptom->name_pl, disease->name);
514  new_symptom->level = disease->level;
515  new_symptom->speed = disease->speed;
516  new_symptom->value = 0;
517  new_symptom->stats.Str = disease->stats.Str;
518  new_symptom->stats.Dex = disease->stats.Dex;
519  new_symptom->stats.Con = disease->stats.Con;
520  new_symptom->stats.Wis = disease->stats.Wis;
521  new_symptom->stats.Int = disease->stats.Int;
522  new_symptom->stats.Pow = disease->stats.Pow;
523  new_symptom->stats.Cha = disease->stats.Cha;
524  new_symptom->stats.sp = disease->stats.sp;
525  new_symptom->stats.food = disease->last_eat;
526  new_symptom->stats.maxsp = disease->stats.maxsp;
527  new_symptom->last_sp = disease->last_sp;
528  new_symptom->stats.exp = 0;
529  new_symptom->stats.hp = disease->stats.hp;
530  new_symptom->msg = add_string(disease->msg);
531  new_symptom->attacktype = disease->attacktype;
532  new_symptom->other_arch = disease->other_arch;
533 
534  set_owner(new_symptom, disease->owner);
535  if (new_symptom->skill != disease->skill) {
536  if (new_symptom->skill)
537  free_string(new_symptom->skill);
538  if (disease->skill)
539  new_symptom->skill = add_refcount(disease->skill);
540  }
541  new_symptom->move_block = 0;
542  insert_ob_in_ob(new_symptom, victim);
543  return;
544  }
545 
546  /* now deal with progressing diseases: we increase the debility
547  * caused by the symptoms.
548  */
549 
550  if (disease->stats.ac != 0) {
551  float scale;
552 
553  symptom->value += disease->stats.ac;
554  scale = 1.0+symptom->value/100.0;
555  /* now rescale all the debilities */
556  symptom->stats.Str = (int)(scale*disease->stats.Str);
557  symptom->stats.Dex = (int)(scale*disease->stats.Dex);
558  symptom->stats.Con = (int)(scale*disease->stats.Con);
559  symptom->stats.Wis = (int)(scale*disease->stats.Wis);
560  symptom->stats.Int = (int)(scale*disease->stats.Int);
561  symptom->stats.Pow = (int)(scale*disease->stats.Pow);
562  symptom->stats.Cha = (int)(scale*disease->stats.Cha);
563  symptom->stats.dam = (int)(scale*disease->stats.dam);
564  symptom->stats.sp = (int)(scale*disease->stats.sp);
565  symptom->stats.food = (int)(scale*disease->last_eat);
566  symptom->stats.maxsp = (int)(scale*disease->stats.maxsp);
567  symptom->last_sp = (int)(scale*disease->last_sp);
568  symptom->stats.exp = 0;
569  symptom->stats.hp = (int)(scale*disease->stats.hp);
570  symptom->msg = add_string(disease->msg);
571  symptom->attacktype = disease->attacktype;
572  symptom->other_arch = disease->other_arch;
573  }
574  SET_FLAG(symptom, FLAG_APPLIED);
575  fix_object(victim);
576 }
577 
584 static void grant_immunity(object *disease) {
585  object *immunity;
586  object *walk;
587 
588  /* Don't give immunity to this disease if last_heal is set. */
589  if (disease->last_heal)
590  return;
591 
592  assert(disease->env != NULL);
593 
594  /* first, search for an immunity of the same name */
595  for (walk = disease->env->inv; walk; walk = walk->below) {
596  if (walk->type == SIGN && !strcmp(disease->name, walk->name)) {
597  walk->level = disease->level;
598  return; /* just update the existing immunity. */
599  }
600  }
601  immunity = create_archetype("immunity");
602  immunity->name = add_string(disease->name);
603  immunity->level = disease->level;
604  immunity->move_block = 0;
605  insert_ob_in_ob(immunity, disease->env);
606  return;
607 }
608 
615 void move_symptom(object *symptom) {
616  object *victim = symptom->env;
617  object *new_ob;
618  int sp_reduce;
619  tag_t tag = symptom->count;
620 
621  if (victim == NULL || victim->map == NULL) { /* outside a monster/player, die immediately */
622  remove_ob(symptom);
623  free_object(symptom);
624  return;
625  }
626 
627  if (symptom->stats.dam > 0)
628  hit_player(victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
629  else
630  hit_player(victim, MAX(1, -victim->stats.maxhp*symptom->stats.dam/100.0), symptom, symptom->attacktype, 1);
631 
632  /* In most cases, if the victim has been freed, the logic that
633  * does that will also free the symptom, so check for that.
634  */
635  if (QUERY_FLAG(victim, FLAG_FREED)) {
636  if (!was_destroyed(symptom, tag)) {
637  remove_ob(symptom);
638  free_object(symptom);
639  }
640  return;
641  }
642 
643  if (symptom->stats.maxsp > 0)
644  sp_reduce = symptom->stats.maxsp;
645  else
646  sp_reduce = MAX(1, victim->stats.maxsp*symptom->stats.maxsp/100.0);
647  victim->stats.sp = MAX(0, victim->stats.sp-sp_reduce);
648 
649  /* create the symptom "other arch" object and drop it here
650  * under every part of the monster
651  * The victim may well have died.
652  */
653 
654  if (symptom->other_arch) {
655  object *tmp;
656 
657  tmp = victim;
658  if (tmp->head != NULL)
659  tmp = tmp->head;
660  for (/*tmp initialized above */; tmp != NULL; tmp = tmp->more) {
661  char name[MAX_BUF];
662 
663  new_ob = arch_to_object(symptom->other_arch);
664  snprintf(name, sizeof(name), "%s's %s", victim->name, new_ob->name);
665  FREE_AND_COPY(new_ob->name, name);
666  if (new_ob->name_pl != NULL) {
667  snprintf(name, sizeof(name), "%s's %s", victim->name, new_ob->name_pl);
668  FREE_AND_COPY(new_ob->name_pl, name);
669  }
670  new_ob->x = tmp->x;
671  new_ob->y = tmp->y;
672  new_ob->map = victim->map;
673  insert_ob_in_map(new_ob, victim->map, victim, 0);
674  }
675  }
676  if (!symptom->msg) {
677  LOG(llevError, "BUG: move_symptom(): symptom %d (%s) without message!\n", symptom->count, symptom->name);
678  return;
679  }
681  symptom->msg, symptom->msg);
682  return;
683 }
684 
694 void check_physically_infect(object *victim, object *hitter) {
695  object *walk;
696 
697  /* search for diseases, give every disease a chance to infect */
698  for (walk = hitter->inv; walk != NULL; walk = walk->below)
699  if (walk->type == DISEASE)
700  infect_object(victim, walk, 0);
701 }
702 
715 int cure_disease(object *sufferer, object *caster) {
716  object *disease, *next;
717  int casting_level;
718  int cure = 0;
719 
720  if (caster)
721  casting_level = caster->level;
722  else
723  casting_level = 1000; /* if null caster, CURE all. */
724 
725  for (disease = sufferer->inv; disease; disease = next) {
726  next = disease->below;
727 
728  if (disease->type == DISEASE && !QUERY_FLAG(disease, FLAG_STARTEQUIP)) {
729  /* attempt to cure this disease. God-given diseases are given by the god, so don't remove them */
730  /* If caster lvel is higher than disease level, cure chance
731  * is automatic. If lower, then the chance is basically
732  * 1 in level_diff - if there is a 5 level difference, chance
733  * is 1 in 5.
734  */
735  if ((casting_level >= disease->level)
736  || (!(random_roll(0, (disease->level-casting_level-1), caster, PREFER_LOW)))) {
737  remove_symptoms(disease);
738  remove_ob(disease);
739  cure = 1;
740  if (caster)
741  change_exp(caster, disease->stats.exp, caster->chosen_skill ? caster->chosen_skill->skill : NULL, 0);
742  free_object(disease);
743  }
744  }
745  }
746  if (cure) {
747  /* Only draw these messages once */
748  if (caster)
750  "You cure a disease!", NULL);
751 
753  "You no longer feel diseased.", NULL);
754  }
755  return cure;
756 }
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
Definition: map.c:330
sint8 Int
Definition: living.h:78
Definition: player.h:146
sint8 ac
Definition: living.h:79
#define DISEASE
Definition: define.h:331
signed short sint16
Definition: global.h:72
void change_exp(object *op, sint64 exp, const char *skill_name, int flag)
Definition: living.c:2015
const char * race
Definition: object.h:171
void set_owner(object *op, object *owner)
Definition: object.c:564
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_START
Definition: newclient.h:480
#define SET_FLAG(xyz, p)
Definition: define.h:510
sstring add_refcount(sstring str)
Definition: shstr.c:202
#define FABS(x)
Definition: define.h:61
sint32 last_heal
Definition: object.h:208
sint16 maxgrace
Definition: living.h:86
void free_string(sstring str)
Definition: shstr.c:272
#define PREFER_LOW
Definition: define.h:909
#define ARCH_SYMPTOM
Definition: object.h:406
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
sint32 last_sp
Definition: object.h:209
#define MSG_TYPE_SPELL
Definition: newclient.h:333
static void grant_immunity(object *disease)
Definition: disease.c:584
sint64 exp
Definition: living.h:88
struct obj * above
Definition: object.h:146
sint16 x
Definition: object.h:179
sint16 sp
Definition: living.h:83
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
static void check_infection(object *disease)
Definition: disease.c:285
struct archt * other_arch
Definition: object.h:264
#define PLAYER
Definition: define.h:113
#define MSG_TYPE_ATTRIBUTE_BAD_EFFECT_END
Definition: newclient.h:481
sint16 maxsp
Definition: living.h:84
sint8 Con
Definition: living.h:78
sint16 hp
Definition: living.h:81
#define FLAG_UNDEAD
Definition: define.h:566
uint32 tag_t
Definition: object.h:40
struct obj * chosen_skill
Definition: object.h:237
const char * title
Definition: object.h:170
void remove_ob(object *op)
Definition: object.c:1515
#define NDI_RED
Definition: newclient.h:198
sint16 maxhp
Definition: living.h:82
int cure_disease(object *sufferer, object *caster)
Definition: disease.c:715
#define FLAG_ALIVE
Definition: define.h:526
#define SYMPTOM
Definition: define.h:332
void move_symptom(object *symptom)
Definition: disease.c:615
const char * name_pl
Definition: object.h:168
object * create_archetype(const char *name)
Definition: arch.c:625
EXTERN const char * undead_name
Definition: global.h:239
#define MSG_TYPE_SPELL_HEAL
Definition: newclient.h:546
sint8 Wis
Definition: living.h:78
struct mapdef * map
Definition: object.h:155
sint16 dam
Definition: living.h:87
#define MSG_TYPE_ATTRIBUTE
Definition: newclient.h:327
const char * name
Definition: object.h:167
struct obj * env
Definition: object.h:151
object * get_owner(object *op)
Definition: object.c:524
struct obj * below
Definition: object.h:145
sint16 last_grace
Definition: object.h:210
sint8 Cha
Definition: living.h:78
#define P_OUT_OF_MAP
Definition: map.h:272
sint16 y
Definition: object.h:179
int op_on_battleground(object *op, int *x, int *y, archetype **trophy)
Definition: player.c:4002
#define MAX(x, y)
Definition: define.h:70
static int is_susceptible_to_disease(object *victim, object *disease)
Definition: disease.c:165
float speed
Definition: object.h:181
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define FLAG_WIZ
Definition: define.h:527
object * insert_ob_in_ob(object *op, object *where)
Definition: object.c:2510
#define MAX_BUF
Definition: define.h:81
object * get_object(void)
Definition: object.c:921
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
const char * skill
Definition: object.h:174
sint32 last_eat
Definition: object.h:207
#define SIGN
Definition: define.h:280
sint8 wc
Definition: living.h:79
sint8 Str
Definition: living.h:78
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
#define PREFER_HIGH
Definition: define.h:908
uint32 attacktype
Definition: object.h:193
static object * find_symptom(object *disease)
Definition: disease.c:267
struct obj * owner
Definition: object.h:228
#define FREE_AND_COPY(sv, nv)
Definition: global.h:288
void check_physically_infect(object *victim, object *hitter)
Definition: disease.c:694
tag_t count
Definition: object.h:157
living stats
Definition: object.h:219
sint8 Dex
Definition: living.h:78
#define FLAG_APPLIED
Definition: define.h:531
const char * msg
Definition: object.h:175
#define FLAG_STARTEQUIP
Definition: define.h:564
sstring add_string(const char *str)
Definition: shstr.c:116
#define MSG_TYPE_ATTACK_DID_HIT
Definition: newclient.h:527
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
static void remove_symptoms(object *disease)
Definition: disease.c:244
#define FLAG_MONSTER
Definition: define.h:541
sint8 Pow
Definition: living.h:78
struct obj * inv
Definition: object.h:148
#define NDI_UNIQUE
Definition: newclient.h:219
struct obj * head
Definition: object.h:154
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
#define was_destroyed(op, old_tag)
Definition: object.h:94
int move_disease(object *disease)
Definition: disease.c:192
MoveType move_block
Definition: object.h:278
void copy_object(object *op2, object *op)
Definition: object.c:758
void free_object(object *ob)
Definition: object.c:1238
Definition: map.h:346
#define P_IS_ALIVE
Definition: map.h:258
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:51
int infect_object(object *victim, object *disease, int force)
Definition: disease.c:336
sint16 level
Definition: object.h:202
void fix_object(object *op)
Definition: living.c:900
struct obj * more
Definition: object.h:153
object * arch_to_object(archetype *at)
Definition: arch.c:576
sint32 value
Definition: object.h:201
sint8 magic
Definition: object.h:199
int hit_player(object *op, int dam, object *hitter, uint32 type, int full_hit)
Definition: attack.c:1868
static void do_symptoms(object *disease)
Definition: disease.c:452
#define MSG_TYPE_ATTACK
Definition: newclient.h:331
uint8 type
Definition: object.h:189
sint32 food
Definition: living.h:89
#define FLAG_FREED
Definition: define.h:529