version 1.9 | | version 1.10 |
---|
| | |
/* | | /* |
* static char *rcsid_disease_c = | | * static char *rcsid_disease_c = |
* "$Id: disease.c,v 1.9 2000/10/05 23:25:52 peterm Exp $"; | | * "$Id: disease.c,v 1.10 2000/11/14 08:37:11 peterm Exp $"; |
*/ | | */ |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
maxsp^ Mana deplete Saps mana. | | maxsp^ Mana deplete Saps mana. |
ac^ Progressiveness How the diseases increases in severity. | | ac^ Progressiveness How the diseases increases in severity. |
last_eat*^ Deplete food saps food if negative | | last_eat*^ Deplete food saps food if negative |
| | last_heal GrantImmunity If nonzero, disease does NOT grant immunity |
| | when it runs out |
| | |
exp experience experience awarded when plague cured | | exp experience experience awarded when plague cured |
hp*^ ReduceRegen reduces regeneration of disease-bearer | | hp*^ ReduceRegen reduces regeneration of disease-bearer |
| | |
#endif | | #endif |
#include <spells.h> | | #include <spells.h> |
#include <sounds.h> | | #include <sounds.h> |
| | #include <skills.h> |
| | |
/* IMPLEMENTATION NOTES | | /* IMPLEMENTATION NOTES |
| | |
| | |
/* check if victim is susceptible to disease. */ | | /* check if victim is susceptible to disease. */ |
static int is_susceptible_to_disease(object *victim, object *disease) | | static int is_susceptible_to_disease(object *victim, object *disease) |
{ | | { |
| | if(!QUERY_FLAG(victim,FLAG_ALIVE)) return 0; |
if(strstr(disease->race, "*") && !QUERY_FLAG(victim, FLAG_UNDEAD)) | | if(strstr(disease->race, "*") && !QUERY_FLAG(victim, FLAG_UNDEAD)) |
return 1; | | return 1; |
if(strstr(disease->race, "undead") && QUERY_FLAG(victim, FLAG_UNDEAD)) | | if(strstr(disease->race, "undead") && QUERY_FLAG(victim, FLAG_UNDEAD)) |
| | |
if((victim->race && strstr(disease->race, victim->race)) || | | if((victim->race && strstr(disease->race, victim->race)) || |
strstr(disease->race, victim->name)) | | strstr(disease->race, victim->name)) |
return 1; | | return 1; |
| | |
return 0; | | return 0; |
} | | } |
| | |
| | |
return 0; /*Immune! */ | | return 0; /*Immune! */ |
} | | } |
| | |
| | |
/* If we've gotten this far, go ahead and infect the victim. */ | | /* If we've gotten this far, go ahead and infect the victim. */ |
new_disease = get_object(); | | new_disease = get_object(); |
copy_object(disease,new_disease); | | copy_object(disease,new_disease); |
new_disease->stats.food=disease->stats.maxgrace; | | new_disease->stats.food=disease->stats.maxgrace; |
new_disease->value=disease->stats.maxhp; | | new_disease->value=disease->stats.maxhp; |
new_disease->stats.wc -= disease->armour; /* self-limiting factor */ | | new_disease->stats.wc -= disease->armour; /* self-limiting factor */ |
set_owner(new_disease,disease->owner); | | |
/* Unfortunately, set_owner does the wrong thing to the skills pointers | | /* Unfortunately, set_owner does the wrong thing to the skills pointers |
resulting in exp going into the owners *current* chosen skill. */ | | resulting in exp going into the owners *current* chosen skill. */ |
| | |
| | if(disease->owner) { |
| | set_owner(new_disease,disease->owner); |
new_disease->chosen_skill = disease->chosen_skill; | | new_disease->chosen_skill = disease->chosen_skill; |
new_disease->exp_obj = disease->exp_obj; | | new_disease->exp_obj = disease->exp_obj; |
| | } |
| | else { /* for diseases which are passed by hitting, set owner and praying skill*/ |
| | if(disease->env && disease->env->type==PLAYER) { |
| | object *player = disease->env; |
| | set_owner(new_disease,player); |
| | new_disease->chosen_skill = find_skill(player,SK_PRAYING); |
| | new_disease->exp_obj = new_disease->chosen_skill->exp_obj; |
| | } |
| | } |
| | |
insert_ob_in_ob(new_disease,victim); | | insert_ob_in_ob(new_disease,victim); |
CLEAR_FLAG(new_disease,FLAG_NO_PASS); | | CLEAR_FLAG(new_disease,FLAG_NO_PASS); |
if(disease->owner && disease->owner->type==PLAYER) { | | if(new_disease->owner && new_disease->owner->type==PLAYER) { |
char buf[128]; | | char buf[128]; |
sprintf(buf,"You infect %s with your disease, %s!",victim->name,disease->name); | | /* if the disease has a title, it has a special infection message */ |
| | /* This messages is printed in the form MESSAGE victim */ |
| | if(new_disease->title) |
| | sprintf(buf,"%s %s!!",disease->title,victim->name); |
| | else |
| | sprintf(buf,"You infect %s with your disease, %s!",victim->name,new_disease->name); |
if(victim->type == PLAYER) | | if(victim->type == PLAYER) |
new_draw_info(NDI_UNIQUE | NDI_RED, 0, disease->owner, buf); | | new_draw_info(NDI_UNIQUE | NDI_RED, 0, new_disease->owner, buf); |
else | | else |
new_draw_info(0, 4, disease->owner, buf); | | new_draw_info(0, 4, new_disease->owner, buf); |
} | | } |
if(victim->type==PLAYER) | | if(victim->type==PLAYER) |
new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,"You suddenly feel ill."); | | new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,"You suddenly feel ill."); |
| | |
int do_symptoms(object *disease) { | | int do_symptoms(object *disease) { |
object *symptom; | | object *symptom; |
object *victim; | | object *victim; |
| | object *tmp; |
victim = disease->env; | | victim = disease->env; |
/* This is a quick hack - for whatever reason, disease->env will point | | /* This is a quick hack - for whatever reason, disease->env will point |
* back to disease, causing endless loops. Why this happens really needs | | * back to disease, causing endless loops. Why this happens really needs |
| | |
is immune. If so, no symptoms! */ | | is immune. If so, no symptoms! */ |
if(!is_susceptible_to_disease(victim, disease)) return 0; | | if(!is_susceptible_to_disease(victim, disease)) return 0; |
| | |
| | /* check for an actual immunity */ |
| | |
| | /* do an immunity check */ |
| | if(victim->head) tmp = victim->head->inv; |
| | else tmp = victim->inv; |
| | |
| | for(/* tmp initialized in if, above */;tmp;tmp=tmp->below) { |
| | if(tmp->type == SIGN) /* possibly an immunity, or diseased*/ |
| | if(!strcmp(tmp->name,disease->name) && tmp->level >= disease->level) |
| | return 0; /*Immune! */ |
| | } |
| | |
new_symptom = get_archetype("symptom"); | | new_symptom = get_archetype("symptom"); |
| | |
/* Something special done with dam. We want diseases to be more | | /* Something special done with dam. We want diseases to be more |
| | |
int grant_immunity(object *disease) { | | int grant_immunity(object *disease) { |
object * immunity; | | object * immunity; |
object *walk; | | object *walk; |
| | /* Don't give immunity to this disease if last_heal is set. */ |
| | if(disease->last_heal) return 0; |
/* first, search for an immunity of the same name */ | | /* first, search for an immunity of the same name */ |
for(walk=disease->env->inv;walk;walk=walk->below) { | | for(walk=disease->env->inv;walk;walk=walk->below) { |
if(walk->type==98 && !strcmp(disease->name,walk->name)) { | | if(walk->type==98 && !strcmp(disease->name,walk->name)) { |
| | |
object *victim = symptom->env; | | object *victim = symptom->env; |
object *new_ob; | | object *new_ob; |
int sp_reduce; | | int sp_reduce; |
if(victim == NULL) { /* outside a monster/player, die immediately */ | | if(victim == NULL || victim->map==NULL) { /* outside a monster/player, die immediately */ |
remove_ob(symptom); | | remove_ob(symptom); |
free_object(symptom); | | free_object(symptom); |
return 0; | | return 0; |
| | |
else sp_reduce = MAX(1,victim->stats.maxsp * symptom->stats.maxsp/100.0); | | else sp_reduce = MAX(1,victim->stats.maxsp * symptom->stats.maxsp/100.0); |
victim->stats.sp = MAX(0,victim->stats.sp - sp_reduce); | | victim->stats.sp = MAX(0,victim->stats.sp - sp_reduce); |
| | |
/* create the symptom "other arch" object and drop it here */ | | /* create the symptom "other arch" object and drop it here |
| | * under every part of the monster */ |
| | /* The victim may well have died. */ |
| | if(victim->map==NULL) return 0; |
if(symptom->other_arch) { | | if(symptom->other_arch) { |
| | object *tmp; |
| | tmp=victim; |
| | if(tmp->head!=NULL) tmp=tmp->head; |
| | for(/*tmp initialized above */;tmp!=NULL;tmp=tmp->more) { |
new_ob = arch_to_object(symptom->other_arch); | | new_ob = arch_to_object(symptom->other_arch); |
new_ob->x = victim->x; | | new_ob->x = tmp->x; |
new_ob->y = victim->y; | | new_ob->y = tmp->y; |
new_ob->map = victim->map; | | new_ob->map = victim->map; |
insert_ob_in_map(new_ob,victim->map,victim); | | insert_ob_in_map(new_ob,victim->map,victim); |
} | | } |
| | } |
new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,symptom->msg); | | new_draw_info(NDI_UNIQUE | NDI_RED,0,victim,symptom->msg); |
| | |
return 1; | | return 1; |