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/
/*
 * files1.cpp
 *   File I/O Routines.
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * 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"

//*********************************************************************
//						path functions
//*********************************************************************

char* objectPath(const CatRef cr) {
	static char filename[256];
	if(cr.id < 0)
		sprintf(filename, "%s/%s/", OBJPATH, cr.area.c_str());
	else
		sprintf(filename, "%s/%s/o%05d.xml", OBJPATH, cr.area.c_str(), cr.id);
	return(filename);
}
char* monsterPath(const CatRef cr) {
	static char filename[256];
	if(cr.id < 0)
		sprintf(filename, "%s/%s/", MONPATH, cr.area.c_str());
	else
		sprintf(filename, "%s/%s/m%05d.xml", MONPATH, cr.area.c_str(), cr.id);
	return(filename);
}
char* roomPath(const CatRef cr) {
	static char filename[256];
	if(cr.id < 0)
		sprintf(filename, "%s/%s/", ROOMPATH, cr.area.c_str());
	else
		sprintf(filename, "%s/%s/r%05d.xml", ROOMPATH, cr.area.c_str(), cr.id);
	return(filename);
}
char* roomBackupPath(const CatRef cr) {
	static char filename[256];
	if(cr.id < 0)
		sprintf(filename, "%s/%s/backup/", ROOMPATH, cr.area.c_str());
	else
		sprintf(filename, "%s/%s/backup/r%05d.xml", ROOMPATH, cr.area.c_str(), cr.id);
	return(filename);
}

//*********************************************************************
//						checkDirExists
//*********************************************************************

bool checkDirExists(bstring filename, bool create) {
	struct stat     f_stat;
	if(stat(filename.c_str(), &f_stat)) {
		if(!create)
			return(false);
		return(!mkdir(filename.c_str(), 0755));
	}
	return(true);
}

bool checkDirExists(bstring area, char* (*fn)(const CatRef cr)) {
	char	filename[256];
	CatRef	cr;

	// this will trigger the dir-only mode
	cr.setArea(area);
	cr.id = -1;
	strcpy(filename, (*fn)(cr));

	return(checkDirExists(filename, true));
}


//*********************************************************************
//						count_obj
//*********************************************************************
// Return the total number of objects contained within an object.
// If perm_only != 0, then only the permanent objects are counted.

int count_obj(Object* object, char perm_only) {
	otag	*op;
	int	total=0;

	op = object->first_obj;
	while(op) {
		if(!perm_only || (perm_only && (op->obj->flagIsSet(O_PERM_ITEM))))
			total++;
		op = op->next_tag;
	}
	return(total);
}

//*********************************************************************
//						count_inv
//*********************************************************************
// Returns the number of objects a creature has in their inventory.
// If perm_only != 0 then only those objects which are permanent
// will be counted.

int count_inv(Creature* creature, char perm_only) {
	otag	*op;
	int	total=0;

	op = creature->first_obj;
	while(op) {
		if(!perm_only || (perm_only && (op->obj->flagIsSet(O_PERM_ITEM))))
			total++;
		op = op->next_tag;
	}
	return(MIN(100,total));
}

//*********************************************************************
//						count_bag_inv
//*********************************************************************
int count_bag_inv(Creature* creature) {
	otag	*op;
	int	total=0;
	op = creature->first_obj;
	while(op) {
		total++;
		if(op->obj && op->obj->getType() == CONTAINER) {
			total += count_obj(op->obj, 0);
		}
		op = op->next_tag;
	}
	return(total);
}

//*********************************************************************
//						free_crt
//*********************************************************************
// This function releases the creature pointed to by the first parameter
// from memory. All items that creature has readied or carries will
// also be released. *ASSUMPTION*: This function will only be called
// from delete room. If it is called from somewhere else, unresolved
// links may remain and cause a game crash. *EXCEPTION*: This function
// can be called independently to free a player's information from
// memory (but not a monster).

void free_crt(Creature* creature, bool remove) {
	otag	*op=0, *tempo=0;
	etag	*ep=0, *tempe=0;
	ctag	*cp=0, *tempc=0;
	ttag	*tp=0, *tempt=0;
	int	i;
	for(i=0; i<MAXWEAR; i++) {
		if(creature->ready[i])
			creature->unequip(i+1, UNEQUIP_DELETE, false);
	}

	op = creature->first_obj;
	while(op) {
		tempo = op->next_tag;
		delete op->obj;
		delete op;
		op = tempo;
	}

	cp = creature->first_fol;
	while(cp) {
		tempc = cp->next_tag;
		if(cp->crt)
			free_crt(cp->crt);
		delete cp;
		cp = tempc;
	}

	ep = creature->first_enm;
	while(ep) {
		tempe = ep->next_tag;
		delete ep;
		ep = tempe;
	}

	tp = creature->first_tlk;
	creature->first_tlk = 0;
	while(tp) {
		tempt = tp->next_tag;
		if(tp->key)
			delete[] tp->key;
		if(tp->response)
			delete[] tp->response;
		if(tp->action)
			delete[] tp->action;
		if(tp->target)
			delete[] tp->target;
		delete tp;
		tp = tempt;
	}

	if(creature->isMonster())
		gServer->delActive(creature->getMonster());
	else if(remove)
		gServer->clearPlayer(creature->name);
	delete creature;
}