roh/conf.old/area/
roh/config/code/python/
roh/config/game/area/
roh/config/game/signs/
roh/help/dmhelp/
roh/help/help/
roh/log/
roh/log/staff/
roh/monsters/ocean/
roh/objects/misc/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.47e/
/*
 * dice.cpp
 *   Dice
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * 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-2012 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"

//*********************************************************************
//						Dice
//*********************************************************************

Dice::Dice() {
	clear();
}
Dice::Dice(unsigned short n, unsigned short s, short p) {
	clear();
	setNumber(n);
	setSides(s);
	setPlus(p);
}

//*********************************************************************
//						clear
//*********************************************************************

void Dice::clear() {
	number = sides = plus = 0;
	mean = 0.0;
}

//*********************************************************************
//						operators
//*********************************************************************

bool Dice::operator==(const Dice& d) const {
	if(	number != d.getNumber() ||
		plus != d.getPlus() ||
		sides != d.getSides() ||
		mean != d.getMean()
	)
		return(false);
	return(true);
}

bool Dice::operator!=(const Dice& d) const {
	return(!(*this==d));
}

//*********************************************************************
//						load
//*********************************************************************

void Dice::load(xmlNodePtr curNode) {
	xmlNodePtr childNode = curNode->children;
	clear();

	while(childNode) {
		if(NODE_NAME(childNode, "Number")) setNumber(xml::toNum<unsigned short>(childNode));
		else if(NODE_NAME(childNode, "Sides")) setSides(xml::toNum<unsigned short>(childNode));
		else if(NODE_NAME(childNode, "Plus")) setPlus(xml::toNum<short>(childNode));
		else if(NODE_NAME(childNode, "Mean")) setMean(xml::toNum<double>(childNode));

		childNode = childNode->next;
	}
}

//*********************************************************************
//						save
//*********************************************************************

void Dice::save(xmlNodePtr curNode, const char* name) const {
	if(!number && !sides && !plus && !mean)
		return;
	xmlNodePtr childNode = xml::newStringChild(curNode, name);

	xml::saveNonZeroNum(childNode, "Number", number);
	xml::saveNonZeroNum(childNode, "Sides", sides);
	xml::saveNonZeroNum(childNode, "Plus", plus);
	xml::saveNonZeroNum(childNode, "Mean", mean);
}

//*********************************************************************
//						roll
//*********************************************************************

int Dice::roll() const {
	if(mean)
		return(mrand(low(), high()));
	return(dice(number, sides, plus));
}

//*********************************************************************
//						average
//*********************************************************************

int Dice::average() const {
	if(mean)
		return((high() - low())/2 + low());
	return((number + number * sides) / 2 + plus);
}

//*********************************************************************
//						low
//*********************************************************************

int Dice::low() const {
	if(mean)
		return(MAX(1,mean*2/3));
	return(number + plus);
}

//*********************************************************************
//						high
//*********************************************************************

int Dice::high() const {
	if(mean)
		return(MAX(1,mean*1.35));
	return(number * sides + plus);
}

//*********************************************************************
//						str
//*********************************************************************

bstring Dice::str() const {
	std::ostringstream oStr;
	if(mean)
	{
		oStr << low() << "-" << high();
	}
	else
	{
		oStr << number << "d" << sides;
		if(plus)
			oStr << (plus > 0 ? "+" : "-") << plus;
	}
	return(oStr.str());
}

//*********************************************************************
//						getMean
//*********************************************************************

double Dice::getMean() const { return(mean); }

//*********************************************************************
//						getNumber
//*********************************************************************

unsigned short Dice::getNumber() const { return(number); }

//*********************************************************************
//						getSides
//*********************************************************************

unsigned short Dice::getSides() const { return(sides); }

//*********************************************************************
//						getPlus
//*********************************************************************

short Dice::getPlus() const { return(plus); }

//*********************************************************************
//						setMean
//*********************************************************************

void Dice::setMean(double m) { mean = m; }

//*********************************************************************
//						setNumber
//*********************************************************************

void Dice::setNumber(unsigned short n) { number = n; }

//*********************************************************************
//						setSides
//*********************************************************************

void Dice::setSides(unsigned short s) { sides = s; }

//*********************************************************************
//						setPlus
//*********************************************************************

void Dice::setPlus(short p) { plus = p; }