version 1.73 | | version 1.74 |
---|
| | |
/* | | /* |
* static char *rcsid_living_c = | | * static char *rcsid_living_c = |
* "$Id: living.c,v 1.73 2005/08/15 22:40:14 akirschbaum Exp $"; | | * "$Id: living.c,v 1.74 2005/11/16 08:16:00 mwedel Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
| | |
#define ORIG_S(xyz,abc) (op->contr->orig_stats.abc) | | #define ORIG_S(xyz,abc) (op->contr->orig_stats.abc) |
| | |
| | /* Rather than having a whole bunch of if (flag) new_draw.. else new_draw, |
| | * make this macro to clean those up. Not usuable outside change_abil |
| | * function since some of the values passed to new_draw_info are hardcoded. |
| | */ |
| | #define DIFF_MSG(flag, msg1, msg2) \ |
| | new_draw_info(NDI_UNIQUE, 0, op, (flag>0)?msg1:msg2); |
| | |
/* return 1 if we sucessfully changed a stat, 0 if nothing was changed. */ | | /* return 1 if we sucessfully changed a stat, 0 if nothing was changed. */ |
/* flag is set to 1 if we are applying the object, -1 if we are removing | | /* flag is set to 1 if we are applying the object, -1 if we are removing |
* the object. | | * the object. |
| | |
| | |
/* remember what object was like before it was changed. note that | | /* remember what object was like before it was changed. note that |
* refop is a local copy of op only to be used for detecting changes | | * refop is a local copy of op only to be used for detecting changes |
* found by fix_player. refop is not a real object */ | | * found by fix_player. refop is not a real object |
| | */ |
memcpy(&refop, op, sizeof(object)); | | memcpy(&refop, op, sizeof(object)); |
| | |
if(op->type==PLAYER) { | | if(op->type==PLAYER) { |
| | |
} | | } |
| | |
/* reset attributes that fix_player doesn't reset since it doesn't search | | /* reset attributes that fix_player doesn't reset since it doesn't search |
* everything to set */ | | * everything to set |
if(flag == -1) | | */ |
op->attacktype&=~tmp->attacktype, | | if(flag == -1) { |
op->path_attuned&=~tmp->path_attuned, | | op->attacktype&=~tmp->attacktype; |
op->path_repelled&=~tmp->path_repelled, | | op->path_attuned&=~tmp->path_attuned; |
| | op->path_repelled&=~tmp->path_repelled; |
op->path_denied&=~tmp->path_denied; | | op->path_denied&=~tmp->path_denied; |
| | /* Presuming here that creatures only have move_type, |
| | * and not the other move_ fields. |
| | */ |
| | op->move_type &= ~tmp->move_type; |
| | } |
| | |
/* call fix_player since op object could have whatever attribute due | | /* call fix_player since op object could have whatever attribute due |
* to multiple items. if fix_player always has to be called after | | * to multiple items. if fix_player always has to be called after |
| | |
*/ | | */ |
if(tmp->attacktype & AT_CONFUSION && tmp->type != BOW) { | | if(tmp->attacktype & AT_CONFUSION && tmp->type != BOW) { |
success=1; | | success=1; |
if(flag>0) | | DIFF_MSG(flag, "Your hands begin to glow red.", |
new_draw_info(NDI_UNIQUE, 0, op,"Your hands begin to glow red."); | | "Your hands stop glowing red."); |
else | | |
new_draw_info(NDI_UNIQUE, 0, op,"Your hands stop glowing red."); | | |
} | | } |
if ( QUERY_FLAG(op,FLAG_LIFESAVE) != QUERY_FLAG(&refop,FLAG_LIFESAVE)){ | | if ( QUERY_FLAG(op,FLAG_LIFESAVE) != QUERY_FLAG(&refop,FLAG_LIFESAVE)){ |
success=1; | | success=1; |
if(flag>0) { | | DIFF_MSG(flag, "You feel very protected.", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel very protected."); | | "You don't feel protected anymore."); |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You don't feel protected anymore."); | | |
} | | |
} | | } |
if ( QUERY_FLAG(op,FLAG_REFL_MISSILE) != QUERY_FLAG(&refop,FLAG_REFL_MISSILE)){ | | if ( QUERY_FLAG(op,FLAG_REFL_MISSILE) != QUERY_FLAG(&refop,FLAG_REFL_MISSILE)){ |
success=1; | | success=1; |
if(flag>0) { | | DIFF_MSG(flag, "A magic force shimmers around you.", |
new_draw_info(NDI_UNIQUE, 0, op,"A magic force shimmers around you."); | | "The magic force fades away."); |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"The magic force fades away."); | | |
} | | |
} | | } |
if ( QUERY_FLAG(op,FLAG_REFL_SPELL) != QUERY_FLAG(&refop,FLAG_REFL_SPELL)){ | | if ( QUERY_FLAG(op,FLAG_REFL_SPELL) != QUERY_FLAG(&refop,FLAG_REFL_SPELL)){ |
success=1; | | success=1; |
if(flag>0) { | | DIFF_MSG(flag, "You feel more safe now, somehow.", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel more safe now, somehow."); | | "Suddenly you feel less safe, somehow."); |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"Suddenly you feel less safe, somehow."); | | |
} | | } |
} | | /* movement type has changed. We don't care about cases where |
if(QUERY_FLAG(tmp,FLAG_FLYING)) { | | * user has multiple items giving the same type appled like we |
if(flag>0) { | | * used to - that is more work than what we gain, plus messages |
success=1; | | * can be misleading (a little higher could be miscontrued from |
/* if were already flying then now flying higher */ | | * from fly high) |
if ( QUERY_FLAG(op,FLAG_FLYING) == QUERY_FLAG(&refop,FLAG_FLYING)) | | */ |
new_draw_info(NDI_UNIQUE, 0, op,"You float a little higher in the air."); | | if (tmp->move_type && op->move_type != refop.move_type) { |
else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You start to float in the air!."); | | |
SET_FLAG(op,FLAG_FLYING); | | |
if(op->speed>1) | | |
op->speed=1; | | |
} | | |
} else { | | |
success=1; | | success=1; |
/* if were already flying then now flying lower */ | | |
if ( QUERY_FLAG(op,FLAG_FLYING) == QUERY_FLAG(&refop,FLAG_FLYING)) | | /* MOVE_FLY_HIGH trumps MOVE_FLY_LOW - changing your move_fly_low |
new_draw_info(NDI_UNIQUE, 0, op,"You float a little lower in the air."); | | * status doesn't make a difference if you are flying high |
else { | | */ |
new_draw_info(NDI_UNIQUE, 0, op,"You float down to the ground."); | | if (tmp->move_type & MOVE_FLY_LOW && !(op->move_type & MOVE_FLY_HIGH)) { |
check_walk_on (op, op); | | DIFF_MSG(flag, "You start to float in the air!.", "You float down to the ground."); |
} | | } |
| | |
| | if (tmp->move_type & MOVE_FLY_HIGH) { |
| | /* double conditional - second case covers if you have move_fly_low - |
| | * in that case, you don't actually land |
| | */ |
| | DIFF_MSG(flag, "You soar into the air air!.", |
| | (op->move_type&MOVE_FLY_LOW ? "You fly lower in the air": |
| | "You float down to the ground.")); |
} | | } |
| | if (tmp->move_type & MOVE_SWIM) |
| | DIFF_MSG(flag,"You feel ready for a swim", "You no longer feel like swimming"); |
| | |
| | /* Changing move status may mean you are affected by things you weren't before */ |
| | check_move_on(op, op); |
} | | } |
| | |
/* becoming UNDEAD... a special treatment for this flag. Only those not | | /* becoming UNDEAD... a special treatment for this flag. Only those not |
* originally undead may change their status */ | | * originally undead may change their status |
| | */ |
if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) | | if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) |
if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) { | | if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) { |
success=1; | | success=1; |
| | |
if(op->race) free_string(op->race); | | if(op->race) free_string(op->race); |
if(op->arch->clone.race) | | if(op->arch->clone.race) |
op->race=add_string(op->arch->clone.race); | | op->race=add_string(op->arch->clone.race); |
| | else |
| | op->race = NULL; |
new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!"); | | new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!"); |
} | | } |
} | | } |
| | |
if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){ | | if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){ |
success=1; | | success=1; |
if(flag>0) { | | DIFF_MSG(flag, "You walk more quietly.", "You walk more noisily."); |
new_draw_info(NDI_UNIQUE, 0, op,"You walk more quietly."); | | |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You walk more noisily."); | | |
} | | |
} | | } |
if ( QUERY_FLAG(op,FLAG_MAKE_INVIS) != QUERY_FLAG(&refop,FLAG_MAKE_INVIS)){ | | if ( QUERY_FLAG(op,FLAG_MAKE_INVIS) != QUERY_FLAG(&refop,FLAG_MAKE_INVIS)){ |
success=1; | | success=1; |
if(flag>0) { | | DIFF_MSG(flag, "You become transparent.", "You can see yourself."); |
new_draw_info(NDI_UNIQUE, 0, op,"You become transparent."); | | |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You can see yourself."); | | |
} | | |
} | | } |
/* blinded you can tell if more blinded since blinded player has minimal | | /* blinded you can tell if more blinded since blinded player has minimal |
* vision */ | | * vision |
| | */ |
if(QUERY_FLAG(tmp,FLAG_BLIND)) { | | if(QUERY_FLAG(tmp,FLAG_BLIND)) { |
success=1; | | success=1; |
if(flag>0) { | | if(flag>0) { |
| | |
| | |
if ( QUERY_FLAG(op,FLAG_SEE_IN_DARK) != QUERY_FLAG(&refop,FLAG_SEE_IN_DARK)){ | | if ( QUERY_FLAG(op,FLAG_SEE_IN_DARK) != QUERY_FLAG(&refop,FLAG_SEE_IN_DARK)){ |
success=1; | | success=1; |
if(flag>0) { | | |
new_draw_info(NDI_UNIQUE, 0, op,"Your vision is better in the dark."); | | |
if(op->type==PLAYER) | | |
op->contr->do_los=1; | | |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You see less well in the dark."); | | |
if(op->type==PLAYER) | | if(op->type==PLAYER) |
op->contr->do_los=1; | | op->contr->do_los=1; |
} | | DIFF_MSG(flag, "Your vision is better in the dark.", "You see less well in the dark."); |
} | | } |
| | |
if ( QUERY_FLAG(op,FLAG_XRAYS) != QUERY_FLAG(&refop,FLAG_XRAYS)){ | | if ( QUERY_FLAG(op,FLAG_XRAYS) != QUERY_FLAG(&refop,FLAG_XRAYS)){ |
| | |
} | | } |
} | | } |
} | | } |
| | |
if(tmp->stats.luck) { | | if(tmp->stats.luck) { |
success=1; | | success=1; |
if(flag*tmp->stats.luck>0) { | | DIFF_MSG(flag*tmp->stats.luck, "You feel more lucky.", "You feel less lucky."); |
new_draw_info(NDI_UNIQUE, 0, op,"You feel more lucky."); | | |
} else { | | |
new_draw_info(NDI_UNIQUE, 0, op,"You feel less lucky."); | | |
} | | |
} | | } |
| | |
if(tmp->stats.hp && op->type==PLAYER) { | | if(tmp->stats.hp && op->type==PLAYER) { |
success=1; | | success=1; |
if(flag*tmp->stats.hp>0) | | DIFF_MSG(flag*tmp->stats.hp, "You feel much more healthy!", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel much more healthy!"); | | "You feel much less healthy!"); |
else | | |
new_draw_info(NDI_UNIQUE, 0, op,"You feel much less healthy!"); | | |
} | | } |
| | |
if(tmp->stats.sp && op->type==PLAYER && tmp->type!=SKILL) { | | if(tmp->stats.sp && op->type==PLAYER && tmp->type!=SKILL) { |
success=1; | | success=1; |
if(flag*tmp->stats.sp>0) | | DIFF_MSG(flag*tmp->stats.sp, "You feel one with the powers of magic!", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel one with the powers of magic!"); | | "You suddenly feel very mundane."); |
else | | |
new_draw_info(NDI_UNIQUE, 0, op,"You suddenly feel very mundane."); | | |
} | | } |
| | |
/* for the future when artifacts set this -b.t. */ | | /* for the future when artifacts set this -b.t. */ |
if(tmp->stats.grace && op->type==PLAYER) { | | if(tmp->stats.grace && op->type==PLAYER) { |
success=1; | | success=1; |
if(flag*tmp->stats.grace>0) | | DIFF_MSG(flag*tmp->stats.grace, "You feel closer to your god!", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel closer to your god!"); | | "You suddenly feel less holy."); |
else | | |
new_draw_info(NDI_UNIQUE, 0, op,"You suddenly feel less holy."); | | |
} | | } |
| | |
if(tmp->stats.food && op->type==PLAYER) { | | if(tmp->stats.food && op->type==PLAYER) { |
success=1; | | success=1; |
if(tmp->stats.food*flag>0) | | DIFF_MSG(flag*tmp->stats.food, "You feel your digestion slowing down.", |
new_draw_info(NDI_UNIQUE, 0, op,"You feel your digestion slowing down."); | | "You feel your digestion speeding up."); |
else | | |
new_draw_info(NDI_UNIQUE, 0, op,"You feel your digestion speeding up."); | | |
} | | } |
| | |
/* Messages for changed resistance */ | | /* Messages for changed resistance */ |
| | |
for (j=0; j<NUM_STATS; j++) { | | for (j=0; j<NUM_STATS; j++) { |
if ((i=get_attr_value(&(tmp->stats),j))!=0) { | | if ((i=get_attr_value(&(tmp->stats),j))!=0) { |
success=1; | | success=1; |
if (i * flag > 0) | | DIFF_MSG(i * flag, gain_msg[j], lose_msg[j]); |
new_draw_info(NDI_UNIQUE, 0, op, gain_msg[j]); | | |
else | | |
new_draw_info(NDI_UNIQUE, 0, op, lose_msg[j]); | | |
} | | } |
} | | } |
} | | } |
| | |
op->slaying=NULL; | | op->slaying=NULL; |
} | | } |
if(!QUERY_FLAG(op,FLAG_WIZ)) { | | if(!QUERY_FLAG(op,FLAG_WIZ)) { |
if ( ! QUERY_FLAG (&op->arch->clone, FLAG_FLYING)) | | |
CLEAR_FLAG(op, FLAG_FLYING); | | |
CLEAR_FLAG(op, FLAG_XRAYS); | | CLEAR_FLAG(op, FLAG_XRAYS); |
CLEAR_FLAG(op, FLAG_MAKE_INVIS); | | CLEAR_FLAG(op, FLAG_MAKE_INVIS); |
} | | } |
| | |
op->path_repelled=op->arch->clone.path_repelled; | | op->path_repelled=op->arch->clone.path_repelled; |
op->path_denied=op->arch->clone.path_denied; | | op->path_denied=op->arch->clone.path_denied; |
op->glow_radius=op->arch->clone.glow_radius; | | op->glow_radius=op->arch->clone.glow_radius; |
| | op->move_type = op->arch->clone.move_type; |
op->chosen_skill = NULL; | | op->chosen_skill = NULL; |
| | |
/* initializing resistances from the values in player/monster's | | /* initializing resistances from the values in player/monster's |
| | |
op->path_repelled|=tmp->path_repelled; | | op->path_repelled|=tmp->path_repelled; |
op->path_denied|=tmp->path_denied; | | op->path_denied|=tmp->path_denied; |
op->stats.luck+=tmp->stats.luck; | | op->stats.luck+=tmp->stats.luck; |
| | op->move_type |= tmp->move_type; |
| | |
if(QUERY_FLAG(tmp,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); | | if(QUERY_FLAG(tmp,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); |
if(QUERY_FLAG(tmp,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); | | if(QUERY_FLAG(tmp,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); |
| | |
op->invisible=1; | | op->invisible=1; |
} | | } |
| | |
if(QUERY_FLAG(tmp,FLAG_FLYING)) { | | |
SET_FLAG(op,FLAG_FLYING); | | |
if(!QUERY_FLAG(op,FLAG_WIZ)) | | |
max=1; | | |
} | | |
| | |
if(tmp->stats.exp && tmp->type!=SKILL) { | | if(tmp->stats.exp && tmp->type!=SKILL) { |
if(tmp->stats.exp > 0) { | | if(tmp->stats.exp > 0) { |
added_speed+=(float)tmp->stats.exp/3.0; | | added_speed+=(float)tmp->stats.exp/3.0; |
| | |
else if (ac<-120) ac=-120; | | else if (ac<-120) ac=-120; |
op->stats.ac=ac; | | op->stats.ac=ac; |
| | |
| | /* if for some reason the creature doesn't have any move type, |
| | * give them walking as a default. |
| | * The second case is a special case - to more closely mimic the |
| | * old behaviour - if your flying, your not walking - just |
| | * one or the other. |
| | */ |
| | if (op->move_type == 0) op->move_type = MOVE_WALK; |
| | else if (op->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) op->move_type &= ~MOVE_WALK; |
| | |
update_ob_speed(op); | | update_ob_speed(op); |
} | | } |
| | |