/*
* 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;
}