Find the correct corpse when autosplitting and sac-ing.

Fixes #147
This commit is contained in:
Thomas Arp 2025-07-16 21:31:25 +02:00
parent 56312d7fe6
commit a40e8d3f97
2 changed files with 59 additions and 32 deletions

View file

@ -56,7 +56,7 @@ static struct char_data *next_combat_list = NULL;
/* local file scope utility functions */ /* local file scope utility functions */
static void perform_group_gain(struct char_data *ch, int base, struct char_data *victim); static void perform_group_gain(struct char_data *ch, int base, struct char_data *victim);
static void dam_message(int dam, struct char_data *ch, struct char_data *victim, int w_type); static void dam_message(int dam, struct char_data *ch, struct char_data *victim, int w_type);
static void make_corpse(struct char_data *ch); static obj_data *make_corpse(struct char_data *ch);
static void change_alignment(struct char_data *ch, struct char_data *victim); static void change_alignment(struct char_data *ch, struct char_data *victim);
static void group_gain(struct char_data *ch, struct char_data *victim); static void group_gain(struct char_data *ch, struct char_data *victim);
static void solo_gain(struct char_data *ch, struct char_data *victim); static void solo_gain(struct char_data *ch, struct char_data *victim);
@ -161,7 +161,7 @@ void stop_fighting(struct char_data *ch)
update_pos(ch); update_pos(ch);
} }
static void make_corpse(struct char_data *ch) static obj_data *make_corpse(struct char_data *ch)
{ {
char buf2[MAX_NAME_LENGTH + 64]; char buf2[MAX_NAME_LENGTH + 64];
struct obj_data *corpse, *o; struct obj_data *corpse, *o;
@ -229,6 +229,7 @@ static void make_corpse(struct char_data *ch)
IS_CARRYING_W(ch) = 0; IS_CARRYING_W(ch) = 0;
obj_to_room(corpse, IN_ROOM(ch)); obj_to_room(corpse, IN_ROOM(ch));
return corpse;
} }
/* When ch kills victim */ /* When ch kills victim */
@ -250,9 +251,10 @@ void death_cry(struct char_data *ch)
send_to_room(world[IN_ROOM(ch)].dir_option[door]->to_room, "Your blood freezes as you hear someone's death cry.\r\n"); send_to_room(world[IN_ROOM(ch)].dir_option[door]->to_room, "Your blood freezes as you hear someone's death cry.\r\n");
} }
void raw_kill(struct char_data * ch, struct char_data * killer) struct obj_data *raw_kill(struct char_data *ch, struct char_data *killer)
{ {
struct char_data *i; struct char_data *i;
obj_data *corpse;
if (FIGHTING(ch)) if (FIGHTING(ch))
stop_fighting(ch); stop_fighting(ch);
@ -284,23 +286,24 @@ struct char_data *i;
update_pos(ch); update_pos(ch);
make_corpse(ch); corpse = make_corpse(ch);
extract_char(ch); extract_char(ch);
if (killer) { if (killer) {
autoquest_trigger_check(killer, NULL, NULL, AQ_MOB_SAVE); autoquest_trigger_check(killer, NULL, NULL, AQ_MOB_SAVE);
autoquest_trigger_check(killer, NULL, NULL, AQ_ROOM_CLEAR); autoquest_trigger_check(killer, NULL, NULL, AQ_ROOM_CLEAR);
} }
return corpse;
} }
void die(struct char_data * ch, struct char_data * killer) struct obj_data *die(struct char_data *ch, struct char_data *killer)
{ {
gain_exp(ch, -(GET_EXP(ch) / 2)); gain_exp(ch, -(GET_EXP(ch) / 2));
if (!IS_NPC(ch)) { if (!IS_NPC(ch)) {
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_KILLER); REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_KILLER);
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_THIEF); REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
} }
raw_kill(ch, killer); return raw_kill(ch, killer);
} }
static void perform_group_gain(struct char_data *ch, int base, static void perform_group_gain(struct char_data *ch, int base,
@ -581,16 +584,54 @@ int skill_message(int dam, struct char_data *ch, struct char_data *vict,
return (0); return (0);
} }
static void perform_autohandling(char_data *ch, const char_data *victim, int local_gold, const obj_data *corpse_obj) {
char local_buf[256];
obj_data *i;
int count = 0, found = FALSE;
if (IN_ROOM(ch) == NOWHERE || ch == victim) {
return;
}
// find the last corpse in the room
for (i = world[IN_ROOM(ch)].contents; i ; i = i->next_content) {
if (is_name("corpse", i->name) && CAN_SEE_OBJ(ch, i)) {
count++;
}
if (i == corpse_obj) {
found = TRUE;
break; // stop looking
}
}
if (count == 0 || !found) {
return; // no corpse here - it may have been removed by some other method.
}
if (GROUP(ch) && local_gold > 0 && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) {
sprintf(local_buf,"all.coin %d.corpse", count);
do_get(ch, local_buf, 0, 0);
sprintf(local_buf,"%d", local_gold);
do_split(ch, local_buf, 0, 0);
} else if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOGOLD)) {
sprintf(local_buf,"all.coin %d.corpse", count);
do_get(ch, local_buf, 0, 0);
}
if (!IS_NPC(ch) && (ch != victim) && PRF_FLAGGED(ch, PRF_AUTOLOOT)) {
sprintf(local_buf,"all %d.corpse", count);
do_get(ch, local_buf, 0, 0);
}
if (IS_NPC(victim) && !IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOSAC)) {
sprintf(local_buf,"%d.corpse", count);
do_sac(ch, local_buf,0,0);
}
}
/* This function returns the following codes: /* This function returns the following codes:
* < 0 Victim died. * < 0 Victim died.
* = 0 No damage. * = 0 No damage.
* > 0 How much damage done. */ * > 0 How much damage done. */
int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype) int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype)
{ {
long local_gold = 0, happy_gold = 0; int local_gold = 0, happy_gold = 0;
char local_buf[256]; obj_data *corpse_obj;
struct char_data *tmp_char;
struct obj_data *corpse_obj;
if (GET_POS(victim) <= POS_DEAD) { if (GET_POS(victim) <= POS_DEAD) {
/* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */ /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */
@ -758,31 +799,15 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
if (IS_NPC(victim)) { if (IS_NPC(victim)) {
if ((IS_HAPPYHOUR) && (IS_HAPPYGOLD)) if ((IS_HAPPYHOUR) && (IS_HAPPYGOLD))
{ {
happy_gold = (long)(GET_GOLD(victim) * (((float)(HAPPY_GOLD))/(float)100)); happy_gold = (int)(GET_GOLD(victim) * (((float)(HAPPY_GOLD))/(float)100));
happy_gold = MAX(0, happy_gold); happy_gold = MAX(0, happy_gold);
increase_gold(victim, happy_gold); increase_gold(victim, happy_gold);
} }
local_gold = GET_GOLD(victim); local_gold = GET_GOLD(victim);
sprintf(local_buf,"%ld", (long)local_gold);
} }
die(victim, ch); corpse_obj = die(victim, ch);
if (GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) { perform_autohandling(ch, victim, local_gold, corpse_obj);
generic_find("corpse", FIND_OBJ_ROOM, ch, &tmp_char, &corpse_obj);
if (corpse_obj) {
do_get(ch, "all.coin corpse", 0, 0);
do_split(ch, local_buf, 0, 0);
}
/* need to remove the gold from the corpse */
} else if (!IS_NPC(ch) && (ch != victim) && PRF_FLAGGED(ch, PRF_AUTOGOLD)) {
do_get(ch, "all.coin corpse", 0, 0);
}
if (!IS_NPC(ch) && (ch != victim) && PRF_FLAGGED(ch, PRF_AUTOLOOT)) {
do_get(ch, "all corpse", 0, 0);
}
if (IS_NPC(victim) && !IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOSAC)) {
do_sac(ch,"corpse",0,0);
}
return (-1); return (-1);
} }
return (dam); return (dam);

View file

@ -26,10 +26,12 @@ void check_killer(struct char_data *ch, struct char_data *vict);
int compute_armor_class(struct char_data *ch); int compute_armor_class(struct char_data *ch);
int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype); int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype);
void death_cry(struct char_data *ch); void death_cry(struct char_data *ch);
void die(struct char_data * ch, struct char_data * killer);
struct obj_data *die(struct char_data *ch, struct char_data *killer);
void hit(struct char_data *ch, struct char_data *victim, int type); void hit(struct char_data *ch, struct char_data *victim, int type);
void perform_violence(void); void perform_violence(void);
void raw_kill(struct char_data * ch, struct char_data * killer);
struct obj_data *raw_kill(struct char_data *ch, struct char_data *killer);
void set_fighting(struct char_data *ch, struct char_data *victim); void set_fighting(struct char_data *ch, struct char_data *victim);
int skill_message(int dam, struct char_data *ch, struct char_data *vict, int skill_message(int dam, struct char_data *ch, struct char_data *vict,
int attacktype); int attacktype);