/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project. All
................................................ contributions are welcome.
....Copyright(C).1995.Melvin.Smith.............. Enjoy.
------------------------------------------------------------------------------
Melvin Smith (aka Fusion) msmith@falcon.mercer.peachnet.edu
MUD++ development mailing list mudpp-list@spice.com
------------------------------------------------------------------------------
nanny.cc
*/
#include "string.h"
#include "llist.h"
#include "server.h"
#include "screen.h"
#include "room.h"
#include "pc.h"
#include "indexable.h"
#include "global.h"
// These are at the bottom of file
extern const char * MAIN_MENU;
extern const char * RACE_MENU;
extern const char * CLASS_MENU;
extern const char * DISCLAIMER;
// Handle newly arrived players
// I used the name 'Nanny' just for old time's sake.
bool isConnected( const String & );
bool checkName( const String & str )
{
if( !str )
return false;
int i= 0;
while( str[i] )
{
if( !isalpha( str[i] ) )
return false;
i++;
}
return true;
}
void Nanny( PC *ch, String & arg )
{
String str;
String filename;
Room * room;
switch( ch->getState() )
{
default:
return;
case STATE_INIT:
ch->out("What shall we call you ? ");
ch->setState( STATE_GET_NAME );
return;
case STATE_GET_NAME:
arg.toProper();
if( isConnected( arg ) )
{
ch->out( "Already connected.\n\r" );
return;
}
if( !checkName( arg ) )
{
ch->out( "Illegal name.\n\r" );
ch->setState( STATE_BOOT );
return;
}
ch->setName( arg );
filename << PLAYER_DIR << '/' << arg[0] << '/'
<< arg;
if( ch->readFrom( filename ) )
{
ch->setState( STATE_GET_OLD_PASSWORD );
ch->out(INVERSE);
ch->out("Password:");
ch->out(NTEXT);
ch->flush();
ch->getSock()->echoOff();
return;
}
ch->setState( STATE_CONFIRM_NAME );
ch->out("Are you sure (y/n)?");
return;
case STATE_CONFIRM_NAME:
switch( arg[0] )
{
default:
ch->setState( STATE_BOOT );
return;
case 'y' :
case 'Y' :
ch->setShort( ch->getName() );
str << ch->getName() << " is here.";
ch->setLong( str );
ch->setState( STATE_GET_NEW_PASSWORD );
ch->out("Ok.\n\rGive me a password:");
ch->getSock()->echoOff();
return;
case 'n' :
case 'N' :
ch->out("What is it then?");
ch->setState( STATE_GET_NAME );
return;
}
return;
case STATE_GET_NEW_PASSWORD:
switch( arg[0] )
{
default:
ch->setPasswd( arg.crypt( ch->getName() ) );
ch->setState( STATE_CONFIRM_PASSWORD );
ch->out("\n\rAgain:");
return;
case '\0':
ch->setState( STATE_BOOT );
return;
}
return;
case STATE_CONFIRM_PASSWORD:
switch( arg[0] )
{
default:
if( arg.crypt( ch->getName() ) != ch->getPasswd() )
{
ch->setState( STATE_GET_NEW_PASSWORD );
ch->out("\n\rPasswords dont match, try again.\n\rPassword:");
return;
}
ch->getSock()->echoOn();
ch->setState( STATE_GET_CLASS );
ch->out("\n\r[ PRESS RETURN ]\n\r" );
return;
case '\0':
ch->setState( STATE_BOOT );
return;
}
return;
case STATE_GET_OLD_PASSWORD:
switch( arg[0] )
{
default:
// This is for empty passwd to allow access
if( ch->getPasswd()
&&
arg.crypt( ch->getName() ) != ch->getPasswd() )
{
ch->out("\n\rImposter!\n\r");
ch->setState( STATE_BOOT );
return;
}
ch->getSock()->echoOn();
ch->setState( STATE_MAIN_MENU );
ch->out( MAIN_MENU );
return;
case '\0':
case '\n':
if( !ch->getPasswd() )
{
ch->getSock()->echoOn();
ch->setState( STATE_MAIN_MENU );
ch->out( MAIN_MENU );
return;
}
else
{
ch->setState( STATE_BOOT );
return;
}
return;
}
case STATE_MAIN_MENU:
switch( arg[0] )
{
default:
ch->out( MAIN_MENU );
return;
case '0':
ch->setState( STATE_BOOT );
return;
case '1':
ch->out("May your stay be fun!\n\n\r" );
ch->out( DISCLAIMER );
ch->setState( STATE_PLAYING );
room = lookupRoom( "the-void:0" );
if( ! room )
{
ch->out( "MUD++ server panic. Can't lookup room." );
ch->setState( STATE_BOOT );
return;
}
room->addCharInv( ch );
ch->checkMail();
str << ch->getName() << " has entered the game.\n\r";
room->outAllCharExcept( str, ch, NULL );
return;
case '5':
ch->view( "../help/wizlist" );
ch->page( "" );
return;
}
case STATE_GET_CLASS:
switch( arg[0] )
{
default:
if( isdigit( arg[0] ) )
{
if( arg.asInt() > MAX_CLASS)
{
ch->out("Invalid class number.\n\r[HIT RETURN]\n\r" );
}
else
{
ch->setClass( arg.asInt() );
ch->setState( STATE_MAIN_MENU );
ch->out("\n\r[ PRESS RETURN ]\n\r" );
}
return;
}
ch->out( CLASS_MENU );
return;
case 'h':
ch->out( "Sorry, no helps yet.\n\r[HIT RETURN]\n\r" );
return;
}
}
}
bool isConnected( const String & name )
{
PC *pc;
LList<PC> tlist = pcs;
tlist.reset();
while( ( pc = tlist.peek() ) )
{
tlist.next();
if( pc->isName( name ) )
return true;
}
return false;
}
const char *DISCLAIMER = "\x1B[2J"
"\n\r"
"Attention : This is the development version of MUD++.\n\r"
" This is original code.\n\r"
" The game is nowhere near playable but you are\n\r"
" welcome to experiment, ie. crash the game. When\n\r"
" you do, please mail me with specifics.\n\r"
"\n\r"
" -Fusion <msmith@falcon.mercer.peachnet.edu>\n\n\n\r";
const char *MAIN_MENU = "\x1B[2J"
"\n\r"
" |\\|\\ | | |\\ _|_ _|_\n\r"
" | | | |_| |_| | | \n\r"
"\n\r"
" (M)ulti\n\r"
" (U)ser\n\r"
" /\\ (D)imension\n\r"
" /\\ / \\ + /\\ \n\r"
" / \\ \\ + /\\ / \\ \n\r"
" // \\ \\ // \\ \\ \n\r"
" -==============================================-\n\r"
" | Welcome to MUD++... |\n\r"
" |-==============================================-|\n\r"
" | [1] Enter the game. |\n\r"
" | [2] Change password. |\n\r"
" | [3] Delete this character. |\n\r"
" | [4] A little help to get started. |\n\r"
" | [5] List the resident Wizards. |\n\r"
" | [0] Quit. |\n\r"
" |________________________________________________|\n\r"
" Select -> ";
const char *CLASS_MENU = "\x1B[2J"
"-=====================================-\n\r"
" Type help <num> to see stats for class\n\r"
"-=====================================-\n\r"
" [1] Magic User\n\r"
" [2] Cleric\n\r"
" [3] Thief\n\r"
" [4] Warrior\n\r"
" [5] Monk\n\r"
" [6] Pscionicist\n\r"
"-=====================================-\n\r"
" Select a class -> ";
const char *RACE_MENU = "\x1B[2J"
"-========================================-\n\r"
" Type help <num> to display stats for race\n\r"
"-========================================-\n\r"
" [1] Human\n\r"
" [2] Draconian (cold blooded)\n\r"
" [3] Atlantian (water dweller)\n\r"
" [4] Troll (dumb and strong)\n\r"
" [5] Elf (small but quick)\n\r"
" [6] Faerie (small but smart)\n\r"
"-========================================-\n\r"
" Select a race -> ";