/* ....[@@@..[@@@..............[@.................. 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 ------------------------------------------------------------------------------ area.cc */ #include "io.h" #include "string.h" #include "llist.h" #include "indexable.h" #include "room.h" #include "area.h" #include "pc.h" #include "shop.h" extern LList<PC> pcs; extern LList<NPC> npcs; extern LList<Area> areas; extern IndexList<Object> objIndex; extern IndexList<NPC> npcIndex; extern IndexList<Room> roomIndex; void Area::setFile( const String & x ) { file = x; } const String & Area::getFile() { return file; } int Area::reload() { // This leaves invalid pointers in other areas so it is imperative // that a global relink be done immediately following an area reload roomIndex.clr(); npcIndex.clr(); objIndex.clr(); rmDirtyBit(); return readFrom(); } // will change to readProtoFrom /* int Area::readFrom( const char * str ) { InFile in( str ); if( !in ) return -1; return readFrom( in ); } */ // will change to readProtoFrom int Area::readFrom( InFile &in ) { char buf[BUF]; Index index; // Read area header for( ; ; ) { in.getword( buf ); switch( *buf ) { default : continue; case '{': // nest++; unused for now continue; case '}': // nest--; break; case 'B': if( !str_cmp( buf, "Builder" ) ) builder = in.getstring( buf ); continue; case 'N': if( !str_cmp( buf, "Name" ) ) setName( in.getstring( buf ) ); continue; case 'R': if( !str_cmp( buf, "RepopMes" ) ) setRepopMessg( in.getstring( buf ) ); else if( !str_cmp( buf, "RepopTime" ) ) repop_time = in.getnum(); continue; case 'S': if( !str_cmp( buf, "Security" ) ) { security = in.getnum(); continue; } continue; case 'V': //if( !str_cmp( buf, "Version" ) ) //version = in.getnum(); continue; } break; } while(in) { in.getword( buf ); if( !in ) break; if( *buf == 'R' ) // Room { index = in.getword( buf ); Room *newRoom = new Room( this, index.getKey() ); // This = Area * // will change to readProtoFrom newRoom->readFrom( in ); roomIndex.addIndex( index, newRoom ); } else if( *buf == 'N' ) // NPC { NPC *newNPC = new NPC; index = in.getword( buf ); // will change to readProtoFrom newNPC->readFrom( in ); npcIndex.addIndex( index, newNPC ); } else if( *buf == 'S' ) // ShopKeeper { NPC *newSK = new ShopKeeper; index =in.getword( buf ); // will change to readProtoFrom newSK->readFrom( in ); npcIndex.addIndex( index, newSK ); } else if( *buf == 'O' ) // Object { Object *newObj = new Object; index = in.getword( buf ); newObj->readProtoFrom( in ); objIndex.addIndex( index, newObj ); } else if( *buf == '#' ) return 0; else return -1; } return 0; } // will change to writeProtoTo /* int Area::writeTo( const char * str ) { OutFile out( str ); if( !out ) return -1; return writeTo( out ); } */ // will change to writeProtoTo int Area::writeTo( OutFile & out ) const { out << "{\n" << "Name " << name << "~\n" << "Security " << security << "\n" << "RepopMes " << repop_messg << "~\n" << "RepopTime " << repop_time << "\n" << "Builder " << builder << "~\n" << "}\n\n"; NPC *npc; out << "NPCS\n"; npcIndex.reset(); while( ( npc = npcIndex.peek() ) ) { npcIndex.next(); // Will change to writeProtoTo if( !npc->isShopKeeper() ) npc->writeTo( out ); } out << "#\n\n"; out << "SHOPKEEPERS\n"; npcIndex.reset(); while( ( npc = npcIndex.peek() ) ) { npcIndex.next(); if( !npc->isShopKeeper() ) continue; // Will change to writeProtoTo npc->writeTo( out ); } out << "#\n\n"; out << "ITEMS\n"; objIndex.reset(); Object *obj; while( ( obj = (Object *)objIndex.peek() ) ) { objIndex.next(); obj->writeProtoTo( out ); } out << "#\n\n"; out << "ROOMS\n"; roomIndex.reset(); Room *room; while( ( room = (Room *)roomIndex.peek() ) ) { roomIndex.next(); // Will change to writeProtoTo room->writeTo( out ); } out << "#\n"; return 1; } int Area::addRoom( Room * room ) { // Add checks later Index x; x.setKey( room->getKey() ); roomIndex.addIndex( x, room ); return 0; } const String & Area::getRepopMessg() { return repop_messg; } void Area::setRepopMessg( const String & x ) { repop_messg = x; } void Area::setRepopTime( int t ) { if( t > 0 ) repop_time = t; } int Area::getRepopTime() { return repop_time; } void Area::repop() { Room * room; roomIndex.reset(); while( ( room = roomIndex.peek() ) ) { roomIndex.next(); room->repop(); } outAllChar( repop_messg ); timer = 0; } int Area::getSecurity() const { return security; } const String & Area::getBuilder() { return builder; } void Area::Builder( const String & strBuilder ) { if( builder == strBuilder ) ; //else builder = strBuilder; } Room *Area::getRoom( const Index & ) { return 0; } Object *Area::lookupObj( const Index & x ) { return objIndex.lookup( x ); } Object *Area::createObj( const Index & x ) { Object *obj; obj = objIndex.lookup( x ); if( !obj ) return 0; // call the Object copy constructor to correctly clone the Object return new Object( *obj ); } NPC *Area::lookupNPC( const Index & x ) { return npcIndex.lookup( x ); } NPC *Area::createNPC( const Index & x ) { NPC *npc = npcIndex.lookup( x ); if( npc ) // call the NPC copy constructor to correctly clone the Object return new NPC( *npc ); return 0; } // Inline these later Room *Area::lookupRoom( const String & x ) { return roomIndex.lookup( x ); } Room *Area::lookupRoom( const char * x ) { return roomIndex.lookup( x ); } Room *Area::lookupRoom( const Index & x ) { return roomIndex.lookup( x.getKey() ); } void Area::hardLink() { Room *room; roomIndex.reset(); while( ( room = roomIndex.peek() ) ) { roomIndex.next(); room->hardLink(); } } void Area::outAllChar( const char * str ) { PC *pc; LList<PC> tList = pcs; tList.reset(); while( ( pc = tList.peek() ) ) { tList.next(); // Add check for awake after position implemented if( !pc->isPlaying() ) continue; else if( pc->inRoom()->getArea() != this ) continue; else { pc->out( str ); } } } void Area::outAllCharExcept( const char * str, PC * skip ) { PC *pc; LList<PC> tList = pcs; tList.reset(); while( ( pc = tList.peek() ) ) { tList.next(); // Add check for awake after position implemented if( !pc->isPlaying() ) continue; else if( pc->inRoom()->getArea() != this ) continue; else if( pc == skip ) continue; else { pc->out( str ); } } } Area * lookupArea( const String & x ) { Area *area; LList<Area> tlist = areas; tlist.reset(); while( ( area = tlist.peek() ) ) { tlist.next(); if( area->getKey() == x ) return area; } return 0; } Area * lookupArea( const char * x ) { return lookupArea( String( x ) ); }