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/
/*
 * builder.cpp
 *	 New routines for handling builder commands and involving building.
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * 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"
#include "dm.h"


//*********************************************************************
//						dmMakeBuilder
//*********************************************************************

int dmMakeBuilder(Player* player, cmd* cmnd) {
	Player	*target=0;

	if(!cmnd->str[1][0]) {
		player->print("Builderize whom?");
		return(0);
	}
	lowercize(cmnd->str[1], 1);
	target = gServer->findPlayer(cmnd->str[1]);
	if(!target || !player->canSee(target)) {
		player->print("%s is not on.\n", cmnd->str[1]);
		return(0);
	}

	if(target->isStaff()) {
		player->print("%s is already a member of the staff.\n", target->name);
		return(0);
	}
	if(target->getExperience()) {
		player->print("%s must have 0 experience to become a builder.\n", target->name);
		return(0);
	}

	target->setClass(BUILDER);
	target->setSecondClass(0);
	target->setDeity(0);
	target->initBuilder();
	target->setFlag(P_DM_INVIS);

	target->printColor("\n\n^yYou are now a building member of the staff.\n\n");
	player->print("%s is now a builder.\n", target->name);
	log_immort(true, player, "%s made %s a builder.\n", player->name, target->name);

	if(	!target->parent_rom ||
		!target->parent_rom->info.isArea(gConfig->defaultArea) ||
		target->parent_rom->info.id != ROOM_BUILDER_PERM_LOW
	) {
		Room* uRoom=0;
		CatRef cr;
		cr.id = ROOM_BUILDER_PERM_LOW;

		if(!loadRoom(cr, &uRoom)) {
			player->print("Error: could not load Builder Waiting Room (%s)\n", cr.str().c_str());
			return(0);
		}

		target->dmPoof(target->getRoom(), uRoom);

		target->deleteFromRoom();
		target->addToRoom(uRoom);
		target->doFollow();
	}

	target->save(true);
	return(0);
}

//*********************************************************************
//						checkRangeRestrict
//*********************************************************************

bool Player::checkRangeRestrict(CatRef cr, bool allowScroll) const {
	int		i=0;

	if(cClass != BUILDER)
		return(false);

	// 0 gets set in the ranges, but they cant modify that room
	if(cr.id <= 0)
		return(true);

	// hardcode this range
	if(	cr.id >= ROOM_BUILDER_PERM_LOW &&
		cr.id <= ROOM_BUILDER_PERM_HIGH &&
		cr.isArea(gConfig->defaultArea)
	)
		return(false);
	if(allowScroll && (cr.isArea("scroll") || cr.isArea("song")))
		return(false);

	for(; i<MAX_BUILDER_RANGE; i++) {
		if(bRange[i].belongs(cr))
			return(false);
	}

	return(true);
}


//*********************************************************************
//						checkBuilder
//*********************************************************************
// Checks against a builder's allowed room range. Returns true if legal,
// false if illegal.

bool Player::checkBuilder(Room* room, bool allowScroll) const {
	if(cClass != BUILDER)
		return(true);
	if(!room || !room->info.id)
		return(false);
	return(checkBuilder(room->info));
}

bool Player::checkBuilder(CatRef cr, bool allowScroll) const {
	if(cClass != BUILDER)
		return(true);

	if(checkRangeRestrict(cr, allowScroll)) {
		printColor("\n^r*** Number assignment violation.\n");
		print("Your range assignments are as follows:\n");

		listRanges(this);

		print("\n");
		return(false);
	}

	return(true);
}

//*********************************************************************
//						listRanges
//*********************************************************************

void Player::listRanges(const Player* viewer) const {

	if(viewer->fd == fd)
		viewer->print("Your assigned number ranges:\n\n");
	else
		viewer->print("Assigned number ranges for %s:\n\n", name);

	viewer->printColor("Perm:       ^ymisc^x: %5d to %d\n",
		ROOM_BUILDER_PERM_LOW, ROOM_BUILDER_PERM_HIGH);

	for(int i=0; i<MAX_BUILDER_RANGE; i++) {
		if(bRange[i].low.id == -1 && bRange[i].high == -1) {
			viewer->printColor("Range #%-2d:  ^y%s^x:  entire area\n", i+1,
				bRange[i].low.area.c_str());
		} else if(bRange[i].low.id && bRange[i].high) {
			viewer->printColor("Range #%-2d:  ^y%s^x: %5d to %-5d\n", i+1,
				bRange[i].low.area.c_str(), bRange[i].low.id, bRange[i].high);
		} else
			viewer->print("Range #%-2d:  empty\n", i+1);
	}
}


//*********************************************************************
//						dmRange
//*********************************************************************

int dmRange(Player* player, cmd* cmnd) {
	Player	*target=0;
	int		offline=0;

	if(player->getClass() == BUILDER || cmnd->num == 1) {
		player->listRanges(player);
		return(0);
	}

	cmnd->str[1][0] = up(cmnd->str[1][0]);
	target = gServer->findPlayer(cmnd->str[1]);
	if(!target) {
		if(!loadPlayer(cmnd->str[1], &target)) {
			player->print("Player does not exist.\n");
			return(0);
		} else
			offline = 1;
	}

	if(!target) {
		player->print("Player not found.\n");
		return(0);
	}

	target->listRanges(player);
	player->print("\n");


	if(offline)
		free_crt(target);

	return(0);
}


//*********************************************************************
//						initBuilder
//*********************************************************************

void Player::initBuilder() {

	if(cClass != BUILDER)
		return;

	bound.room.setArea("misc");
	bound.room.id = ROOM_BUILDER_PERM_LOW;
	bound.mapmarker.reset();
	cClass2 = 0;

	doDispelMagic();

	dmMax(this, 0);

	cureDisease();
	curePoison();
	removeEffect("petrification");

	// builders are always watching each other build
	setFlag(P_LOG_WATCH);
	setFlag(P_INCOGNITO);
}

//*********************************************************************
//						builderObj
//*********************************************************************

bool builderObj(const Creature* player) {
	return(player->canBuildObjects());
}

//*********************************************************************
//						builderMob
//*********************************************************************

bool builderMob(const Creature* player) {
	return(player->canBuildMonsters());
}

//*********************************************************************
//						canBuildObjects
//*********************************************************************

bool Creature::canBuildObjects() const {
	if(!isStaff())
		return(false);
	if(cClass == BUILDER && !flagIsSet(P_BUILDER_OBJS))
		return(false);
	return(true);
}

//*********************************************************************
//						canBuildMonsters
//*********************************************************************

bool Creature::canBuildMonsters() const {
	if(!isStaff())
		return(false);
	if(cClass == BUILDER && !flagIsSet(P_BUILDER_MOBS))
		return(false);
	return(true);
}

//*********************************************************************
//						builderCanEdit
//*********************************************************************

bool Player::builderCanEditRoom(bstring action) {
	if(cClass == BUILDER && !getRoom()->flagIsSet(R_CONSTRUCTION)) {
		print("You cannot %s while you are in a room that is not under construction.\n", action.c_str());
		return(false);
	}
	return(true);
}