Currently if you use %force% %actor% or %force% %self% in a player-attached script it causes a crash. After running GDB it seemed to be being caused by:
if (ch->desc && (GET_LEVEL(ch->desc->original) < LVL_IMPL))
return;
The intent of those lines seems fairly redundant as best as I can tell.
Changing it to:
if (ch->desc && (GET_LEVEL(ch-) < LVL_IMPL))
return;
gets rid of the crash, but makes %force% %actor% <stuff> still not work on a player-attached script.
Removing the two lines completely makes it "still" not work, but, at this point is sends:
[ Mob ((null), VNum 65535):: mforce: forcing self ]
That's caused by
if (victim == ch) {
mob_log(ch, "mforce: forcing self");
return;
}
I'd probably change that to be:
if (victim == ch && IS_NPC(ch)) {
mob_log(ch, "mforce: forcing self");
return;
}
This way you retain the functionality of getting that error when a script on a mob is written to do %force% %self%, which isn't harmful, but also won't work so it's nice to retain the message as error detection.
I don't see any issues with this fix, I still can't type mforce or %force% to manually abuse anything.
The full function and proposed changes are below in case anyone else sees an issue with the changes.
Code:
ACMD(do_mforce)
{
char arg[MAX_INPUT_LENGTH];
if (!MOB_OR_IMPL(ch)) {
send_to_char(ch, "%s", CONFIG_HUH);
return;
}
if (AFF_FLAGGED(ch, AFF_CHARM))
return;
- if (ch->desc && (GET_LEVEL(ch->desc->original) < LVL_IMPL))
- return;
argument = one_argument(argument, arg);
if (!*arg || !*argument) {
mob_log(ch, "mforce: bad syntax");
return;
}
if (!str_cmp(arg, "all")) {
struct descriptor_data *i;
char_data *vch;
for (i = descriptor_list; i ; i = i->next) {
if ((i->character != ch) && !i->connected &&
(IN_ROOM(i->character) == IN_ROOM(ch))) {
vch = i->character;
if (GET_LEVEL(vch) < GET_LEVEL(ch) && CAN_SEE(ch, vch) &&
valid_dg_target(vch, 0)) {
command_interpreter(vch, argument);
}
}
}
} else {
char_data *victim;
if (*arg == UID_CHAR) {
if (!(victim = get_char(arg))) {
mob_log(ch, "mforce: victim (%s) does not exist",arg);
return;
}
} else if ((victim = get_char_room_vis(ch, arg, NULL)) == NULL) {
mob_log(ch, "mforce: no such victim");
return;
}
- if (victim == ch) {
+ if (victim == ch && IS_NPC(ch)) {
mob_log(ch, "mforce: forcing self");
return;
}
if (valid_dg_target(victim, 0))
command_interpreter(victim, argument);
}
}