/* ....[@@@..[@@@..............[@.................. 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 ------------------------------------------------------------------------------ pc_info.cc */ #include "string.h" #include "llist.h" #include "indexable.h" #include "room.h" #include "server.h" #include "area.h" #include "help.h" #include "screen.h" #include "env.h" #include "spell.h" #include "pc.h" #include "global.h" void PC::do_list( String & ) { Char * ch; Object * obj; String str; // Should be able to have player shopkeepers automated too. in_room->chars.reset(); while( ( ch = in_room->chars.peek() ) ) { in_room->chars.next(); if( ch == this ) continue; if( ch->isShopKeeper() ) break; } if( ! ch ) { out( "No merchant is here.\n\r" ); return; } str << "Goods for sale:\n"; ch->inv.reset(); while( ( obj = ch->inv.peek() ) ) { ch->inv.next(); if( obj->worn() ) continue; str << "[ " << obj->getCost() << " ] " << obj->getShort() << endl; } out( str ); } void PC::do_commands( String & ) { String str( BUF * 2 ); int count=1; int i; str << "MUD++ player commands.\n\n\r"; for( int ihash = 0; ihash < 27; ihash++ ) { i = 0; while( cmdlist[ihash][i].commd ) { str.sprintfAdd( "%11s", cmdlist[ihash][i].commd ); if( !( count++ % 5 ) ) str += "\n\r"; i++; } } out( str ); } void PC::do_wizhelp( String & ) { String str( BUF * 2 ); int count=1; int i; str << "MUD++ Wizard Commands.\n\n\r"; for( int ihash = 0; ihash < 27; ihash++ ) { i = 0; while( immcmdlist[ihash][i].commd ) { if( authorized( immcmdlist[ihash][i].bit ) ) { str.sprintfAdd( "%11s", immcmdlist[ihash][i].commd ); if( !( count++ % 5 ) ) str += "\n\r"; } i++; } } out( str ); } void PC::do_help( String & arg ) { if( !arg ) { // Simple help view( STANDARD_HELP ); } else { // Look through the help list for the keyword, if exists call // View( 'HELP_DIR+filename' ) // View is very efficient at reading in files and helps can be // modified while the game is running. // Memory usage is also decreased. String fname; for( int i=0;help_list[i];i++ ) { if( !help_list[i]->isName( arg ) ) continue; if( help_list[i]->getLevel() > level ) break; fname << HELP_DIR << '/' << help_list[i]->fileName(); view( fname.chars() ); return; } out("\n\rNo help on that.\n\r"); } } void PC::do_levels( String & ) { String str( BUF * 2 ); str << "Exp is per level, not cumalative.\n\r-===================-\n\r"; for( int i = 1; i<=MAX_PC_LEVEL; i++ ) { str.sprintf( " %2d %11d\n\r", i, exp_table[ i ] ); } str += "\n\r"; out( str ); } void PC::do_prompt( String & arg ) { int len = arg.len() + 1; if( len > 80 ) { out( "Prompt string too long. Must be < 80 characters.\n\r" ); return; } if( prompt ) delete [] prompt; prompt = arg.dup(); out( "Prompt string set.\n\r" ); putPrompt(); } void PC::do_clear( String & ) { out( "\x1B[2J" ); } void PC::do_areas( String & ) { String str( BUF * 2 ); str += (const char*)"\n\rAreas\n\r----------------------\n\r"; Area *pArea; areas.reset( ); while( ( pArea = areas.peek( ) ) ) { areas.next(); str << "[" << pArea->getKey() << "] " << pArea->getName() << "\n\r"; } out( str ); } void PC::do_look( String & arg ) { Object *obj; Object *obj2; Char *ch; String str( BUF * 2 ); String arg1; String arg2; arg.startArgs(); arg1 = arg.getArg(); arg2 = arg.getArg(); if( !arg1 ) { // No arg so do standard look str << "\n\r" << BCYAN << in_room->getName() << NORMAL << "\n\r" << CYAN << in_room->getDesc() << NORMAL << "\n\r"; // show the items in_room->inv.reset(); while( ( obj = in_room->inv.peek() ) ) { in_room->inv.next(); str << obj->getLong() << "\n\r"; } in_room->chars.reset(); while( ( ch = in_room->chars.peek() ) ) { in_room->chars.next(); if( ch == this ) continue; str << ch->getLong() << "\n\r"; } out( str ); do_exits( "" ); return; } else if( arg1 == "in" || arg1 == "inside" ) { // look at contents of a container (arg2) if( !arg2 ) { out( "Look inside what?\n\r" ); return; } // Look for object in chars inventory first obj = getObjInv( arg2 ); // If not then look in room. if( ! obj ) obj = in_room->getObj( arg2 ); if( !obj ) { out( "Nothing by that name here.\n\r" ); return; } if( !obj->isContainer() ) { out( "That isn't a container.\n\r" ); return; } // replace resetInv/getNexObjInv with a const LList & // access member function and assign to a temp readonly list // for iterating. // Reset object inventory list pointer obj->resetInv(); out( obj->getShort() ); out( " contains:\n\r-------------\n\r" ); if( !( obj2 = obj->getNextObjInv() ) ) { out( "Nothing.\n\r" ); return; } out( obj2->getShort() ); out( "\n\r" ); // Iterate while( ( obj2 = obj->getNextObjInv() ) ) { out( obj2->getShort() ); out( "\n\r" ); } return; } // Find object/mob/player to look at ch = in_room->getChar( arg1 ); if( ch ) { look( ch ); return; } // Look at an object obj = in_room->getObj( arg1 ); if( obj ) { look( obj ); return; } // Extra description keywords String ed = in_room->getExtraDesc( arg1 ); if( ed ) { out( ed ); out( "\n\r" ); return; } // Look in a direction int dir; if( ( dir = getDir( arg1[0] ) ) != DIR_UNDEFINED ) { const Exit *ex = in_room->getExit( dir ); if( !ex ) { out( "Nothing to see in that direction.\n\r" ); return; } if( ex->getDesc() ) out( ex->getDesc() ); else out( "You see nothing special in that direction." ); out( "\n\r" ); return; } out( "Look at what?\n\r" ); } void PC::do_save( String & ) { String fname; fname << PLAYER_DIR << "/" << name[0] << "/" << name.asProper(); if( writeTo( fname ) ) out( "\n\rOk. Saved.\n\r" ); else out( "\n\rError, not saved, report to immortal!!!\n\r" ); } void PC::do_password( String & arg ) { String orig; String newp; arg.startArgs(); orig = arg.getArg(); newp = arg.getArg(); if( !orig || !newp ) { out( "Usage: password <old> <new>\n\r" ); return; } orig.crypt( getName() ); if( getPasswd() && orig != getPasswd() ) { out( "Old password doesn't match. Password not changed.\n\r" ); return; } if( newp.hasChar( '~' ) ) { out( "Illegal character '~'. Password not changed.\n\r" ); return; } newp.crypt( getName() ); password = newp; out( "Ok. Password changed.\n\r" ); } void PC::do_score( String & ) { String str( 8192 ); str.sprintf( "You are %s.\n\rLevel: %d\n\r", name.chars(), levels[classnow]); str.sprintfAdd( "Security: %d\n\r", getSecurity() ); if( classnow != CLASS_WIZARD ) { str.sprintfAdd( "You have %ld experience points.\n\r", exp ); str.sprintfAdd( "You need %ld exp to level %d.\n\r", exp_table[levels[classnow]]-exp, levels[classnow]+1 ); } str.sprintfAdd( "Str: %d Int: %d Wis: %d Con: %d Spd: %d\n\r", getStr(), getInt(), getWis(), getCon(), getSpd() ); str.sprintfAdd( "%d(%d) hp %d(%d) mana\n\r", getHp(), getMaxHp(), getMana(), getMaxMana() ); str.sprintfAdd( "You are carrying %d items weighing %d stones.\n\r", getCarriedCount(), getCarriedWeight() ); str.sprintfAdd( "You are have %ld gold coins.\n\r", getGold() ); str.sprintfAdd( "Damroll: %d Hitroll: %d Armor: %d\n\r", getDamRoll(), getHitRoll(), getArmor() ); str.sprintfAdd( "Flags: " ); str += "\n\r"; if( fighting ) { str << "You are fighting " << fighting->getShort() << ".\n\r"; } str << "Affected by:\n\r"; Affect *paf; const Spell *spell; affects.reset(); while( ( paf = affects.peek() ) ) { affects.next(); if( ( spell = paf->getSpell() ) ) str.sprintfAdd( "Spell '%s' for %d hours.\n\r", spell->getName(), paf->getTimer() ); } out( str ); } void PC::do_time( String & ) { out( envir.getTime() ); } void PC::do_weather( String & ) { out( envir.getWeather() ); } void PC::do_who( String & ) { PC *ch; int count = 0; String str( BUF * 4 ); LList<PC> tlist = pcs; tlist.reset(); // reset the list str += " [ PCs ]\n\r"; str += " Level Class Name\n\r"; str += "----------------------------------\n\r"; while( ( ch = tlist.peek() ) ) { count++; str.sprintfAdd( " [%3d] [%7s] %s\n\r", ch->getLevel(), ch->className(), ch->getName().chars() ); tlist.next(); } str += "----------------------------------\n\r"; str.sprintfAdd( " Total - %d players\n\r", count ); out( str ); }