int cast_cure_disease(string str) { int skill; mixed ret; str = (string)this_player()->expand_nickname(str); skill = (int)this_player()->query_skill("faith.spells.curing.target"); if (skill<MIN_LVL) { notify_fail("You are not skillful enough.\n"); return 0; } skill = (int)this_player()->query_skill_bonus("faith.spells.defensive.target"); ret = cure_disease(str, skill, 1); if (stringp(ret)) { notify_fail(ret); return 0; } write("You cast Cure disease.\n"); return 1; }
/** * If the player should die (lack of hp, food, etc), we call this. * * Will remove diseases, apply death penalties, and so on. * @param op The player in jeopardy. */ void kill_player(object *op) { char buf[HUGE_BUF]; int x, y, i; /* this is for resurrection */ mapstruct *map; object *tmp; int z; int num_stats_lose; int lost_a_stat; int lose_this_stat; int this_stat; if (pvp_area(NULL, op)) { new_draw_info(NDI_UNIQUE | NDI_NAVY, op, "You have been defeated in combat!"); new_draw_info(NDI_UNIQUE | NDI_NAVY, op, "Local medics have saved your life..."); /* Restore player */ cast_heal(op, MAXLEVEL, op, SP_CURE_POISON); /* Remove any disease */ cure_disease(op, NULL); op->stats.hp = op->stats.maxhp; if (op->stats.food <= 0) { op->stats.food = 999; } /* Create a bodypart-trophy to make the winner happy */ tmp = arch_to_object(find_archetype("finger")); if (tmp != NULL) { char race[MAX_BUF]; snprintf(buf, sizeof(buf), "%s's finger", op->name); FREE_AND_COPY_HASH(tmp->name, buf); snprintf(buf, sizeof(buf), "This finger has been cut off %s the %s, when %s was defeated at level %d by %s.", op->name, player_get_race_class(op, race, sizeof(race)), gender_subjective[object_get_gender(op)], op->level, CONTR(op)->killer[0] == '\0' ? "something nasty" : CONTR(op)->killer); FREE_AND_COPY_HASH(tmp->msg, buf); tmp->value = 0, tmp->material = 0, tmp->type = 0; tmp->x = op->x, tmp->y = op->y; insert_ob_in_map(tmp, op->map, op, 0); } /* Teleport defeated player to new destination */ transfer_ob(op, MAP_ENTER_X(op->map), MAP_ENTER_Y(op->map), 0, NULL, NULL); return; } if (save_life(op)) { return; } /* Trigger the DEATH event */ if (trigger_event(EVENT_DEATH, NULL, op, NULL, NULL, 0, 0, 0, SCRIPT_FIX_ALL)) { return; } /* Trigger the global GDEATH event */ trigger_global_event(EVENT_GDEATH, NULL, op); play_sound_player_only(CONTR(op), SOUND_PLAYER_DIES, SOUND_NORMAL, 0, 0); /* Save the map location for corpse, gravestone */ x = op->x; y = op->y; map = op->map; /* Basically two ways to go - remove a stat permanently, or just * make it depletion. This bunch of code deals with that aspect * of death. */ if (settings.balanced_stat_loss) { /* If stat loss is permanent, lose one stat only. */ /* Lower level chars don't lose as many stats because they suffer more if they do. */ if (settings.stat_loss_on_death) { num_stats_lose = 1; } else { num_stats_lose = 1 + op->level / BALSL_NUMBER_LOSSES_RATIO; } } else { num_stats_lose = 1; } lost_a_stat = 0; /* Only decrease stats if you are level 3 or higher. */ for (z = 0; z < num_stats_lose; z++) { if (settings.stat_loss_on_death && op->level > 3) { /* Pick a random stat and take a point off it. Tell the * player what he lost. */ i = rndm(1, NUM_STATS) - 1; change_attr_value(&(op->stats), i, -1); check_stat_bounds(&(op->stats)); change_attr_value(&(CONTR(op)->orig_stats), i, -1); check_stat_bounds(&(CONTR(op)->orig_stats)); new_draw_info(NDI_UNIQUE, op, lose_msg[i]); lost_a_stat = 1; } else if (op->level > 3) { /* Deplete a stat */ archetype *deparch = find_archetype("depletion"); object *dep; i = rndm(1, NUM_STATS) - 1; dep = present_arch_in_ob(deparch, op); if (!dep) { dep = arch_to_object(deparch); insert_ob_in_ob(dep, op); } lose_this_stat = 1; if (settings.balanced_stat_loss) { /* Get the stat that we're about to deplete. */ this_stat = get_attr_value(&(dep->stats), i); if (this_stat < 0) { int loss_chance = 1 + op->level / BALSL_LOSS_CHANCE_RATIO; int keep_chance = this_stat * this_stat; /* Yes, I am paranoid. Sue me. */ if (keep_chance < 1) { keep_chance = 1; } /* There is a maximum depletion total per level. */ if (this_stat < -1 - op->level / BALSL_MAX_LOSS_RATIO) { lose_this_stat = 0; } else { /* Take loss chance vs keep chance to see if we retain the stat. */ if (rndm(0, loss_chance + keep_chance - 1) < keep_chance) { lose_this_stat = 0; } } } } if (lose_this_stat) { this_stat = get_attr_value(&(dep->stats), i); /* We could try to do something clever like find another * stat to reduce if this fails. But chances are, if * stats have been depleted to -50, all are pretty low * and should be roughly the same, so it shouldn't make a * difference. */ if (this_stat >= -50) { change_attr_value(&(dep->stats), i, -1); SET_FLAG(dep, FLAG_APPLIED); new_draw_info(NDI_UNIQUE, op, lose_msg[i]); fix_player(op); lost_a_stat = 1; } } } } /* If no stat lost, tell the player. */ if (!lost_a_stat) { const char *god = determine_god(op); if (god && god != shstr_cons.none) { new_draw_info_format(NDI_UNIQUE, op, "For a brief moment you feel the holy presence of %s protecting you.", god); } else { new_draw_info(NDI_UNIQUE, op, "For a brief moment you feel a holy presence protecting you."); } } /* Put a gravestone up where the character 'almost' died. */ tmp = arch_to_object(find_archetype("gravestone")); snprintf(buf, sizeof(buf), "%s's gravestone", op->name); FREE_AND_COPY_HASH(tmp->name, buf); FREE_AND_COPY_HASH(tmp->msg, gravestone_text(op)); tmp->x = op->x, tmp->y = op->y; insert_ob_in_map(tmp, op->map, NULL, 0); /* Subtract the experience points, if we died because of food give us * food, and reset HP... */ /* Remove any poisoning the character may be suffering. */ cast_heal(op, MAXLEVEL, op, SP_CURE_POISON); /* Remove any disease */ cure_disease(op, NULL); /* Apply death experience penalty. */ apply_death_exp_penalty(op); if (op->stats.food < 0) { op->stats.food = 900; } op->stats.hp = op->stats.maxhp; op->stats.sp = op->stats.maxsp; op->stats.grace = op->stats.maxgrace; hiscore_check(op, 1); /* Otherwise the highscore can get entries like 'xxx was killed by pudding * on map Wilderness' even if they were killed in a dungeon. */ CONTR(op)->killer[0] = '\0'; /* Check to see if the player is in a shop. Ii so, then check to see * if the player has any unpaid items. If so, remove them and put * them back in the map. */ tmp = get_map_ob(op->map, op->x, op->y); if (tmp && tmp->type == SHOP_FLOOR) { remove_unpaid_objects(op->inv, op); } /* Move player to his current respawn position (last savebed). */ enter_player_savebed(op); /* Show a nasty message */ new_draw_info(NDI_UNIQUE, op, "YOU HAVE DIED."); save_player(op, 1); return; }