Welcome to the Builder Academy

Question in file error

More
25 Apr 2016 21:08 #5796 by JTP
in file error was created by JTP
In file error

I get this every time someone has a animate dead zombie in there Group:

Apr 25 14:54:24 :: SYSERR: Mob using '((ch)->player_specials->saved.pref)' at fi
ght.c:777.

if (GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) { <<--fight.c:777

Ideas ?

Please Log in or Create an account to join the conversation.

More
26 Apr 2016 20:55 #5797 by rudeboyrave
Replied by rudeboyrave on topic in file error

CyberASSAULT
www.cyberassault.org
cyberassault.org 11111
A post-apocalyptic, sci-fi MUD.

Please Log in or Create an account to join the conversation.

More
26 Apr 2016 21:20 #5798 by thomas
Replied by thomas on topic in file error
Nice, you found a BUG :):):)
Code:
die(victim, ch); if (GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) { 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 (dam); }

This code needs to be rewritten - the problem is that noone seems to have thought about this use case.

There are some options.

The easy fix - just makes the error go away:
Code:
die(victim, ch); - if (GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) { + if (!IS_NPC(ch) && GROUP(ch) && (local_gold > 0) && PRF_FLAGGED(ch, PRF_AUTOSPLIT) ) { 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 (dam); }
The easy fix doesn't "work" though - if my zombie kills the mob, nothing is looted, split or sac'ed.
Also, a long standing bug in this code is that if you are carrying too much to take all, do_sac just dumps the items on the ground.

Here's some Browser Code (*) that should fix this:
Code:
static int perform_auto_actions(struct char_data *ch, struct char_data *victim, long gold) { char gold_buf[256]; struct char_data *tmp_char; struct obj_data *corpse_obj; struct char_data *master = ch; sprintf(gold_buf,"%ld", gold); if (ch->master && IN_ROOM(ch) == IN_ROOM(ch->master)) { master = ch->master; } if (GROUP(master) && (gold > 0) && !IS_NPC(master) && PRF_FLAGGED(master, PRF_AUTOSPLIT) ) { generic_find("corpse", FIND_OBJ_ROOM, master, &tmp_char, &corpse_obj); if (corpse_obj) { do_get(master, "all.coin corpse", 0, 0); do_split(master, local_buf, 0, 0); } } else if (!IS_NPC(master) && (master != victim) && PRF_FLAGGED(master, PRF_AUTOGOLD)) { do_get(master, "all.coin corpse", 0, 0); } if (!IS_NPC(master) && (master != victim) && PRF_FLAGGED(master, PRF_AUTOLOOT)) { do_get(master, "all corpse", 0, 0); } if (IS_NPC(victim) && !IS_NPC(master) && PRF_FLAGGED(master, PRF_AUTOSAC)) { generic_find("corpse", FIND_OBJ_ROOM, master, &tmp_char, &corpse_obj); if (corpse_obj) { if (!corpse_obj->contents) { do_sac(ch,"corpse",0,0); } } } } /* This function returns the following codes: * < 0 Victim died. * = 0 No damage. * > 0 How much damage done. */ int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype) { long local_gold = 0, happy_gold = 0; if (GET_POS(victim) <= POS_DEAD) { /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */ if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET)) return (-1); log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.", GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch)); die(victim, ch); return (-1); /* -je, 7/7/92 */ } /* peaceful rooms */ if (ch->nr != real_mobile(DG_CASTER_PROXY) && ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); return (0); } /* shopkeeper and MOB_NOKILL protection */ if (!ok_damage_shopkeeper(ch, victim) || MOB_FLAGGED(victim, MOB_NOKILL)) { send_to_char(ch, "This mob is protected.\r\n"); return (0); } /* You can't damage an immortal! */ if (!IS_NPC(victim) && ((GET_LEVEL(victim) >= LVL_IMMORT) && PRF_FLAGGED(victim, PRF_NOHASSLE))) dam = 0; if (victim != ch) { /* Start the attacker fighting the victim */ if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL)) set_fighting(ch, victim); /* Start the victim fighting the attacker */ if (GET_POS(victim) > POS_STUNNED && (FIGHTING(victim) == NULL)) { set_fighting(victim, ch); if (MOB_FLAGGED(victim, MOB_MEMORY) && !IS_NPC(ch)) remember(victim, ch); } } /* If you attack a pet, it hates your guts */ if (victim->master == ch) stop_follower(victim); /* If the attacker is invisible, he becomes visible */ if (AFF_FLAGGED(ch, AFF_INVISIBLE) || AFF_FLAGGED(ch, AFF_HIDE)) appear(ch); /* Cut damage in half if victim has sanct, to a minimum 1 */ if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2) dam /= 2; /* Check for PK if this is not a PK MUD */ if (!CONFIG_PK_ALLOWED) { check_killer(ch, victim); if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim)) dam = 0; } /* Set the maximum damage per round and subtract the hit points */ dam = MAX(MIN(dam, 100), 0); GET_HIT(victim) -= dam; /* Gain exp for the hit */ if (ch != victim) gain_exp(ch, GET_LEVEL(victim) * dam); update_pos(victim); /* skill_message sends a message from the messages file in lib/misc. * dam_message just sends a generic "You hit $n extremely hard.". * skill_message is preferable to dam_message because it is more * descriptive. * * If we are _not_ attacking with a weapon (i.e. a spell), always use * skill_message. If we are attacking with a weapon: If this is a miss or a * death blow, send a skill_message if one exists; if not, default to a * dam_message. Otherwise, always send a dam_message. */ if (!IS_WEAPON(attacktype)) skill_message(dam, ch, victim, attacktype); else { if (GET_POS(victim) == POS_DEAD || dam == 0) { if (!skill_message(dam, ch, victim, attacktype)) dam_message(dam, ch, victim, attacktype); } else { dam_message(dam, ch, victim, attacktype); } } /* Use send_to_char -- act() doesn't send message if you are DEAD. */ switch (GET_POS(victim)) { case POS_MORTALLYW: act("$n is mortally wounded, and will die soon, if not aided.", TRUE, victim, 0, 0, TO_ROOM); send_to_char(victim, "You are mortally wounded, and will die soon, if not aided.\r\n"); break; case POS_INCAP: act("$n is incapacitated and will slowly die, if not aided.", TRUE, victim, 0, 0, TO_ROOM); send_to_char(victim, "You are incapacitated and will slowly die, if not aided.\r\n"); break; case POS_STUNNED: act("$n is stunned, but will probably regain consciousness again.", TRUE, victim, 0, 0, TO_ROOM); send_to_char(victim, "You're stunned, but will probably regain consciousness again.\r\n"); break; case POS_DEAD: act("$n is dead! R.I.P.", FALSE, victim, 0, 0, TO_ROOM); send_to_char(victim, "You are dead! Sorry...\r\n"); break; default: /* >= POSITION SLEEPING */ if (dam > (GET_MAX_HIT(victim) / 4)) send_to_char(victim, "That really did HURT!\r\n"); if (GET_HIT(victim) < (GET_MAX_HIT(victim) / 4)) { send_to_char(victim, "%sYou wish that your wounds would stop BLEEDING so much!%s\r\n", CCRED(victim, C_SPR), CCNRM(victim, C_SPR)); if (ch != victim && MOB_FLAGGED(victim, MOB_WIMPY)) do_flee(victim, NULL, 0, 0); } if (!IS_NPC(victim) && GET_WIMP_LEV(victim) && (victim != ch) && GET_HIT(victim) < GET_WIMP_LEV(victim) && GET_HIT(victim) > 0) { send_to_char(victim, "You wimp out, and attempt to flee!\r\n"); do_flee(victim, NULL, 0, 0); } break; } /* Help out poor linkless people who are attacked */ if (!IS_NPC(victim) && !(victim->desc) && GET_POS(victim) > POS_STUNNED) { do_flee(victim, NULL, 0, 0); if (!FIGHTING(victim)) { act("$n is rescued by divine forces.", FALSE, victim, 0, 0, TO_ROOM); GET_WAS_IN(victim) = IN_ROOM(victim); char_from_room(victim); char_to_room(victim, 0); } } /* stop someone from fighting if they're stunned or worse */ if (GET_POS(victim) <= POS_STUNNED && FIGHTING(victim) != NULL) stop_fighting(victim); /* Uh oh. Victim died. */ if (GET_POS(victim) == POS_DEAD) { if (ch != victim && (IS_NPC(victim) || victim->desc)) { if (GROUP(ch)) group_gain(ch, victim); else solo_gain(ch, victim); } if (!IS_NPC(victim)) { mudlog(BRF, LVL_IMMORT, TRUE, "%s killed by %s at %s", GET_NAME(victim), GET_NAME(ch), world[IN_ROOM(victim)].name); if (MOB_FLAGGED(ch, MOB_MEMORY)) forget(ch, victim); } /* Cant determine GET_GOLD on corpse, so do now and store */ if (IS_NPC(victim)) { if ((IS_HAPPYHOUR) && (IS_HAPPYGOLD)) { happy_gold = (long)(GET_GOLD(victim) * (((float)(HAPPY_GOLD))/(float)100)); happy_gold = MAX(0, happy_gold); increase_gold(victim, happy_gold); } local_gold = GET_GOLD(victim); } die(victim, ch); perform_auto_actions(ch, victim, local_gold); return (-1); } return (dam); }




* Browser code == untested, uncompiled, bugridden and generally nasty code. Take it as inspiration.

Please Log in or Create an account to join the conversation.

More
28 Apr 2016 20:08 - 28 Apr 2016 20:09 #5800 by JTP
Replied by JTP on topic in file error
So its the one in a Group who get the last hit and kills the mob, that loots, split and sac? Hmm
Last edit: 28 Apr 2016 20:09 by JTP.

Please Log in or Create an account to join the conversation.

Time to create page: 0.254 seconds