Yeah I was about to suggest function pointers until I read lower in your
post, so I'll just enhance the idea of function pointers a bit :D you
could also have a sort of 'stage' variable associated w/ the function,
so that you could do something similar to the following, after adding
some kind of command lookup function (as opposed to the default code in
void interpret which just loops through the table):

void do_player( CHAR_DATA *ch, char *argument )
{
   int cn = cmd_lookup("player");

   switch( ch->cmd_stage )
   {
        case 0:
           // initial output display w/ listing of players, and a prompt
to ask if you wish to delete so-and-so...
           // upon success of the command, and verification that cn !=
-1, it'll do something like this:
           ch->cmd_func = *cmd_table[cn].do_fun;
           ch->cmd_stage++;
           break;

        case 1:
           // Takes a yes or no argument as an answer to the question
asked in case 0...
           // upon success of the command, and verification that cn !=
-1 (if any checks fail we'd reset their cmd_func to NULL and cmd_stage
to 0, perhaps even implement a question to verify that they absolutely
want to delete the character, and then:
           // ch->cmd_func should already be equal to this do_fun, so we
don't need to reset it...
           ch->cmd_stage++;
           break;

        case 2:
           // Takes a yes or no argument as an answer to the
verification, performs the deletion of the pfile, echos a success
message (or failure), and resets cmd data:
           ch->cmd_func = NULL;
           ch->cmd_stage = 0;
           break;

        default: // Check for sanity
           // Outputs some kind of error message that they're in an
unknown stage setting, perhaps does a loop through the cmd_table to find
a matching do_fun value in case some other function forgot to reset its
data, and we could log that to help hunt down any mistakes in other
functions, and then reset the data:
           ch->cmd_func = NULL;
           ch->cmd_stage = 0;
           break;
   }

   return;
}

If you wanted, you could also make some sort of macro to set the command
data, like SET_CMD(ch) ((ch)->cmd_func = cn == -1 ? NULL :
*cmd_table[cn].do_fun; (ch)->cmd_stage++;) although that syntax may have
an error, it might need braces or something, and then you could just do
all of your validity checks in the case statement and do a SET_CMD(ch);

Anyhoo, that's just an expansion on Jeremy's idea :)

Richard Lindsey 

-----Original Message-----
From: Jeremy Hill [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, February 15, 2005 3:23 AM
To: [email protected]
Subject: Re: How do I... (yes or no input question)

Unfortunately, ROM does not work this way--other posters will probably 
provide different specifics, but I'll provide a general "here's how ROM 
handles commands" dealy.

In comm.c, the game is defined as looping like this:

while (the game is running)
{
    -->Add new connections to the game
    -->Kick out errored connections
    -->Process input from connections
    -->Refresh the MUD--mobile positions, combat, etc
    -->Process output from connections
    -->sleep (last_time + 1/PULSE_PER_SECOND - now)
}

So here's what's going on:

You type "player delete <name>"

    -->Process input from connections
It processes this input, now command is "player delete <name>"
In this input block, it executes the next available command.  If nothing
was
queued up before this "player delete" command, it'll execute it.

It executes the function below, where the function to be called is 
"player" and the argument passed in is "delete <name>".
It gets to here:
---------------------------------
sprintf( buf, "Would you like to delete %s?{x\n\r", ep->d_name );
stc(buf,ch);
/* Broken Piece o.... This is where it doesnt let me do anything, any 
advice? */
if (argument[0] == '\0' || UPPER(argument[0]) == 'No')
 {
 stc("Player not deleted.\n\r",ch);
/* ??? If i do this, i dont think it will continue through the 
directory... */
 return;
 }

But--and I'd like to emphasize this--the MUD DOES NOT STOP AND WILL 
NEVER STOP to accept a command here.  It only checks to see if argument 
is what it needs.  It isn't--argument is NULL here because "delete 
<name>" were stripped out of argument earlier in the function, so it
bails.

---
    -->Refresh the MUD--mobile positions, combat, etc
The MUD updates itself.

    -->Process output from connections
You NOW receive this:
"{x Would you like to delete %s?\n\rPlayer not deleted. "

----------------------
That probably confused you.  Sorry.  Here's a solution:
- Implement and use events and event handling.

Here's some similar functionality solutions:
- Make a 'hacked event'--make certain commands set a function pointer on

a character (as well as a char* for the previous command), then change 
interpret to check to see if the func pointer is NULL or not.  If it 
isn't, it'll execute the last command automatically with (or without) 
the previous command line as well as the new input.  E.g. it strcats the

two lines to provide the functionality you want.
- Set and use a boolean flag on a char.
- Set and use some other simplified char * on a char.

I really do recommend using events for what you want.  Alternatively, 
you can take a look at how the SkullMUD technology preview server has 
"menus" that may provide the functionality you want:

Example from SkullMUD:
<30000hp 100c 100e 100f 100l 274mv> skedit foobar
Hit a number plus its corresponding arguments to change a field.
Example:
 > 1 chi
Hit ? to view this skill again, or enter Q or X to quit.
Skillbuilder> ?
 0. [name] Name of skill [locked]: foobar
 1. [mag] Primary type of magic: chi
 2. [lvl] Levels of magic required:  0 chi 0 elemental 0 fae 0 ley 0 
combat 0 adventuring
 3. [tar] Valid skill targets: ignore
 4. [fla] Skill flags: 0
 5. [cos] Base cast costs: 0 chi 0 elemental 0 fae 0 ley 0 combat 0 
adventuring
 6. [ukc] Upkeep costs per upkeep round: 0 chi 0 elemental 0 fae 0 ley 0

combat 0 adventuring
 7. [lag] Readiness lag (RT seconds): 0
 8. [las] Base last seconds: 0
 9. [upk] Upkeep time: 0
...
------------------------------------------------------------------------
--------
Skillbuilder> 1 elemental
Magic type of skill changed to elemental.
Skillbuilder>
 0. [name] Name of skill [locked]: foobar
 1. [mag] Primary type of magic: elemental
 2. [lvl] Levels of magic required:  0 chi 0 elemental 0 fae 0 ley 0 
combat 0 adventuring
 3. [tar] Valid skill targets: ignore
 4. [fla] Skill flags: 0
 5. [cos] Base cast costs: 0 chi 0 elemental 0 fae 0 ley 0 combat 0 
adventuring
 6. [ukc] Upkeep costs per upkeep round: 0 chi 0 elemental 0 fae 0 ley 0

combat 0 adventuring
 7. [lag] Readiness lag (RT seconds): 0
 8. [las] Base last seconds: 0
 9. [upk] Upkeep time: 0
...
------------------------------------------------------------------------
--------
Skillbuilder>


What you could do is have the function take "player delete <name>", this

creates a menu with 2 options:
Sample menu:
Really delete <name>?
1. Yes.
2. No.
<30000hp 100c 100e 100f 100l 274mv> 1

Player <name> has been deleted.

<30000hp 100c 100e 100f 100l 274mv>





SkullMUD is available on www.mudmagic.com.



Phideaux wrote:

> Hi list, I have been working on a player information (how 
> active/inactive theyve been)  function.  Using a snippet from 
> mudmagic, I have made it show me players in three rows.  I also have 
> it doing this
>
> Hope          81  days  Horrendus     56  days  Hospiria      69  days
> Imah          95  days
> Would you like to delete Imah?
> Player not deleted.
>
> The problem is, it does not ask for my wait for my input... it for 
> some reason assumes i type nothing and finishes the function.    So my

> question is, how do I get the code to wait for "Yes" or "No"   before 
> continu-ing through.  here is some of the snippet.
>
> if ( fImmortal )
> {
> /* Dont show anything for Imms */
> stc("{x",ch);
> }
> else
> if (days > 90) /* If the file is inactive for 90 days, ask to delete
*/
> {
> sprintf( buf, "%-13s %s%-3d{x days{x\n\r",
>  ep->d_name, "{R", days );
> stc(buf,ch);
> /* The big question /*
> sprintf( buf, "Would you like to delete %s?{x\n\r", ep->d_name );
> stc(buf,ch);
> /* Broken Piece o.... This is where it doesnt let me do anything, any 
> advice? */
> if (argument[0] == '\0' || UPPER(argument[0]) == 'No')
>  {
>  stc("Player not deleted.\n\r",ch);
> /* ??? If i do this, i dont think it will continue through the 
> directory... */
>  return;
>  }
> /*havent got this far */
> if (UPPER(argument[0]) == 'Y' )
> {
> sprintf(buf,"%s deleted.", ep->d_name);
> stc(buf,ch);
> sprintf(buf,"%s/%s", PLAYER_DIR, ep->d_name);
> unlink(buf);
> sprintf(buf,"%s deleted.", ep->d_name);
> stc(buf,ch);
> }
> }
> else
>
>    sprintf( buf, "%-13s %s%-3d{x days{x\t",
>  ep->d_name, days > 30 ? "{r" : days > 20 ? "{Y" : days > 10 ? "{g" : 
> "{G", days );
>  send_to_char(buf, ch);
>                col++;
>                if (col==3)
>                {
>                  send_to_char("\n\r",ch);
>                  col=0;
>                }
>
> If you'd like me to post the whole function, let me know
>
> ATM!
> Forgotten-Empire.no-ip.com:9000
>
>

-- 
ROM mailing list
[email protected]
http://www.rom.org/cgi-bin/mailman/listinfo/rom


Reply via email to