/* * files2.cpp * Additional file routines, including memory management. * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute is granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #include "mud.h" //********************************************************************* // reloadRoom //********************************************************************* // This function reloads a room from disk, if it's already loaded. This // allows you to make changes to a room, and then reload it, even if it's // already in the memory room queue. bool Config::reloadRoom(BaseRoom* room) { Room* uRoom = room->getUniqueRoom(); if(uRoom) { bstring str = uRoom->info.str(); if( roomQueue.find(str) != roomQueue.end() && roomQueue[str].rom && reloadRoom(uRoom->info) >= 0 ) { roomQueue[str].rom->addPermCrt(); return(true); } } else { AreaRoom* aRoom = room->getAreaRoom(); char filename[256]; sprintf(filename, "%s/%d/%s", AREAROOMPATH, aRoom->area->id, aRoom->mapmarker.filename().c_str()); if(file_exists(filename)) { xmlDocPtr xmlDoc; xmlNodePtr rootNode; if((xmlDoc = xml::loadFile(filename, "AreaRoom")) == NULL) merror("Unable to read arearoom file", FATAL); rootNode = xmlDocGetRootElement(xmlDoc); Area *area = aRoom->area; aRoom->reset(); aRoom->area = area; aRoom->load(rootNode); return(true); } } return(false); } int Config::reloadRoom(CatRef cr) { Room *room=0; ctag *cp=0; otag *op=0; bstring str = cr.str(); if(roomQueue.find(str) == roomQueue.end()) return(0); if(!roomQueue[str].rom) return(0); // if(read_rom(fd, room) < 0) { if(!loadRoomFromFile(cr, &room)) return(-1); room->first_ply = roomQueue[str].rom->first_ply; roomQueue[str].rom->first_ply = 0; // have to do this in dmReloadRoom() now // room->addPermCrt(); if(!room->first_mon) { room->first_mon = roomQueue[str].rom->first_mon; roomQueue[str].rom->first_mon = 0; } if(!room->first_obj) { room->first_obj = roomQueue[str].rom->first_obj; roomQueue[str].rom->first_obj = 0; } delete roomQueue[str].rom; roomQueue[str].rom = room; cp = room->first_ply; while(cp) { cp->crt->parent_rom = room; *&cp->crt->room = *&room->info; cp = cp->next_tag; } cp = room->first_mon; while(cp) { cp->crt->parent_rom = room; cp->crt->room = room->info; cp = cp->next_tag; } op = room->first_obj; while(op) { op->obj->parent_room = room; op = op->next_tag; } return(0); } //********************************************************************* // resaveRoom //********************************************************************* // This function saves an already-loaded room back to memory without // altering its position on the queue. int saveRoomToFile(Room* pRoom, int permOnly); int Config::resaveRoom(CatRef cr) { bstring str = cr.str(); if(roomQueue[str].rom) roomQueue[str].rom->saveToFile(ALLITEMS); return(0); } int Config::saveStorage(Room* uRoom) { if(uRoom->flagIsSet(R_SHOP)) saveStorage(shopStorageRoom(uRoom)); return(saveStorage(uRoom->info)); } int Config::saveStorage(CatRef cr) { bstring str = cr.str(); if(!roomQueue[str].rom) return(0); if(roomQueue[str].rom->saveToFile(ALLITEMS) < 0) return(-1); return(0); } //******************************************************************** // resaveAllRooms //******************************************************************** // This function saves all memory-resident rooms back to disk. If the // permonly parameter is non-zero, then only permanent items in those // rooms are saved back. void Config::resaveAllRooms(char permonly) { qtag *qt = roomHead; while(qt) { if(roomQueue[qt->str].rom) { if(roomQueue[qt->str].rom->saveToFile(permonly) < 0) return; } qt = qt->next; } } //********************************************************************* // replaceMonsterInQueue //********************************************************************* void Config::replaceMonsterInQueue(CatRef cr, Monster *monster) { if(this->monsterInQueue(cr)) *monsterQueue[cr.str()].mob = *monster; else addMonsterQueue(cr, &monster); } //********************************************************************* // replaceObjectInQueue //********************************************************************* void Config::replaceObjectInQueue(CatRef cr, Object* object) { if(objectInQueue(cr)) *objectQueue[cr.str()].obj = *object; else addObjectQueue(cr, &object); } //********************************************************************* // save_all_ply //********************************************************************* // This function saves all players currently in memory. void save_all_ply() { std::pair<bstring, Player*> p; foreach(p, gServer->players) { if(!p.second->isConnected()) continue; p.second->save(true); } }