23 Jan, 2012, arholly wrote in the 1st comment:
Votes: 0
Hello:
I have a dominate command which should compel the victim, if the user get's enough successes, to do something. But, after looking at it, it does not look like it is affecting the victim. I'm looking at it and I think I see a few things wrong with it, but I'm not confident in my own coding yet to make sure.

Shouldn't the char buf[MAX_INPUT_LENGTH] be char buf [MAX_STRING_LENGTH]? And unless I'm mistaken, it's actually making the user say something regardless of what the command is, as opposed to what the compel should be doing or am I totally off base on it?

Can someone help me fix this? Thank you.

Arholly

void do_dominate1 (CHAR_DATA *ch, char *string)
{
int fail;
char arg[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;

string = one_argument(string,arg);
string = one_argument(string,buf);

if (ch->race != race_lookup("vampire") || !ch->disc[DISC_DOMINATE]) {
send_to_char("Huh?\n\r", ch);
return;
}

if(ch->power_timer > 0)
{
send_to_char("Your powers have not rejuvenated yet.\n\r", ch);
return;
}

if (arg[0] == '\0')
{
send_to_char("Command whom?\n\r", ch);
return;
}

if (buf[0] == '\0')
{
send_to_char("What do you want done?\n\r",ch);
return;
}

if (string[0] == '\0')
{
send_to_char("You have to say something to command someone!", ch);
return;
}

if (!str_prefix(buf,"delete") || !str_prefix(buf, "quit")
|| !str_prefix(buf, "concede"))
{
send_to_char("That will NOT be done.\n\r",ch);
return;
}

if (!str_prefix(buf, "influences"))
{
send_to_char("You don't have enough control for that.\n\r",ch);
return;
}

if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
send_to_char( "They aren't here.\n\r", ch );
return;
}

if ( victim == ch )
{
send_to_char( "Massochist! Just type the command.\n\r", ch );
return;
}

fail = dice_rolls( ch, (get_curr_stat(ch,STAT_MAN) + ch->ability[INTIMIDATION].value), victim->willpower );
ch->power_timer = 1;

if(IS_SET(ch->act2,ACT2_RESIST))
{
send_to_char("They seem to have a very strong willpower.\n\r", ch);
fail–;
victim->willpower–;
}


if (ch->trust < victim->trust || (ch->gen > victim->gen && !IS_NATURAL(victim)))
{
sprintf(buf, "%s is above your influence.\n\r", victim->name);
send_to_char(buf, ch);
return;
}

if (fail > 0)
{
do_function(ch, &do_say, string);
interpret( victim, buf );
return;
}
else
{
do_function(ch, &do_say, string);
return;
}
}
24 Jan, 2012, andril wrote in the 2nd comment:
Votes: 0
Well, as far as MAX_STRING_LENGTH vs. MAX_INPUT_LENGTH is concerned, MAX_INPUT_LENGTH should, according to my experience in Smaug, be used for arguments passed to the command, which you get with one_argument. MAX_STRING_LENGTH would be for the buffer for formatted output e.g. using sprintf. In most cases there's really not much use in specifying one or the other as you're usually looking at relatively short amounts of formatted text anyways. But it pays to be consistent. In this particular case buf is being conscripted into pulling double duty as both argument holder and formatted output on a fail. Up to you if you want to change buf to use MAX_STRING_LENGTH instead of MAX_INPUT_LENGTH but I would suggest you do so simply because that's the way things are done, so to speak.

Of course, I would also reorder the calls to one_argument to only be used as needed when you pass a previous check so you only use arg for arguments and then only as you need to validate the next bit.

Based on the argument processing it looks like the function is expecting something like "command <target> <some command> <some verbal order>" e.g. "command fido bark I order you to speak!", yes? So, if you successfully pass all your checks, and the victim fails to resist, you get the commanding character saying "I order you to speak!" and then the fido barking, assuming there's a command/social for that. Otherwise the commanding character still speaks but the fido does nothing.

On a somewhat unrelated bit: that last if/else for fail > 0 could be written as:
do_function( ch, &do_say, string );
if( fail > 0 )
interpret( victim, buf );

Just removes some extra typing and the redundant return calls.
24 Jan, 2012, Sharmair wrote in the 3rd comment:
Votes: 0
Assuming that MAX_INPUT_LENGTH (MIL)is actually the max size that command
input can be (in some muds, the max is actualy smaller then the setting of MIL -
in a lot of muds the actual max input is around 256 chars but MIL has been raised),
the size of buf should be OK as the size pulled off in the one_argument call will be
less then or equal to the input. The only problem might be in the use of buf in line
78 IF MIL is VERY small, and a name can be close to MIL (player names are normaly
limited to small length, but if a mob could use this command, and the name could
be the full input length, and MIL is NOT larger then the actual input max, there
could be a problem).

As for as how the command works, it seems to pull off two arguments, the first is
the name of the victim, and the 2nd the command to force the victim to do. Anything
after the 2nd argument is what the actor says to the victim and it might make sense
to have that be the same in all cases (though I would code it just once out of the if).
24 Jan, 2012, arholly wrote in the 4th comment:
Votes: 0
Thanks for the help and feedback. It also helped me realize that I was checking the wrong thing in one instance.
25 Jan, 2012, JohnnyStarr wrote in the 5th comment:
Votes: 0
You might want to write a few utility functions to handle some of these conditions.

For example:
if (!str_prefix(buf, "influences"))
{
send_to_char("You don't have enough control for that.\n\r",ch);
return;
}


Conditionals like this can really muck-up your command functions. You might
do something like:

if (expect(buf, "influences", "You don't have enough control for that.\n\r", ch)) return;
// expect handles send_to_char for you.


Just a thought.
0.0/5