roh/conf/area/
roh/game/talk/
roh/help/
roh/monsters/ocean/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.44b/
/*
 * 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);
	}
}