btmux-0.6-rc4/doc/
btmux-0.6-rc4/event/
btmux-0.6-rc4/game/
btmux-0.6-rc4/game/maps/
btmux-0.6-rc4/game/mechs/
btmux-0.6-rc4/game/text/help/
btmux-0.6-rc4/game/text/help/cat_faction/
btmux-0.6-rc4/game/text/help/cat_inform/
btmux-0.6-rc4/game/text/help/cat_misc/
btmux-0.6-rc4/game/text/help/cat_mux/
btmux-0.6-rc4/game/text/help/cat_mux/cat_commands/
btmux-0.6-rc4/game/text/help/cat_mux/cat_functions/
btmux-0.6-rc4/game/text/help/cat_templates/
btmux-0.6-rc4/game/text/wizhelp/
btmux-0.6-rc4/include/
btmux-0.6-rc4/misc/
btmux-0.6-rc4/python/
btmux-0.6-rc4/src/hcode/btech/
btmux-0.6-rc4/tree/
/*
 * $Id: mech.c3i.c,v 1.1.1.1 2005/01/11 21:18:12 kstevens Exp $
 *
 * Author: Cord Awtry <kipsta@mediaone.net>
 * Author: Cord Awtry <kipsta@mediaone.net>
 *  Copyright (c) 2000-2002 Cord Awtry
 *       All rights reserved
 *
 * Based on work that was:
 *  Copyright (c) 1997 Markus Stenberg
 *  Copyright (c) 1998-2000 Thomas Wouters
 */

#include "mech.h"
#include "mech.events.h"
#include "p.mech.c3i.h"
#include "p.mech.c3.misc.h"
#include "p.mech.utils.h"
#include "p.mech.los.h"
#include "p.mech.contacts.h"

#define C3_POS_IN_NETWORK -1
#define C3_POS_NO_ROOM		-2

int getFreeC3iNetworkPos(MECH * mech, MECH * mechToAdd)
{
	int i;
	dbref otherRef;

	validateC3iNetwork(mech);

	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		otherRef = MechC3iNetworkElem(mech, i);

		if(otherRef > 0) {
			if(otherRef == mechToAdd->mynum)
				return C3_POS_IN_NETWORK;
		} else
			return i;
	}

	return C3_POS_NO_ROOM;
}

void replicateC3iNetwork(MECH * mechSrc, MECH * mechDest)
{
	int i;
	dbref otherRef;

	debugC3(tprintf("REPLICATE: %d's C3i network to %d", mechSrc->mynum,
					mechDest->mynum));

	clearC3iNetwork(mechDest, 0);

	MechC3iNetworkElem(mechDest, 0) = mechSrc->mynum;
	MechC3iNetworkSize(mechDest) = 1;

	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		otherRef = MechC3iNetworkElem(mechSrc, i);

		if(otherRef != mechDest->mynum) {
			MechC3iNetworkElem(mechDest, MechC3iNetworkSize(mechDest)) =
				otherRef;
			MechC3iNetworkSize(mechDest) += 1;
		}
	}

	validateC3iNetwork(mechDest);
}

void addMechToC3iNetwork(MECH * mech, MECH * mechToAdd)
{
	MECH *otherMech;
	MECH *otherNotifyMech;
	dbref otherRef;
	int i;
	int wPos = -1;

	debugC3(tprintf("ADD: %d to the C3i network of %d", mechToAdd->mynum,
					mech->mynum));

	/* Find a position to add the new mech into my network */
	wPos = getFreeC3iNetworkPos(mech, mechToAdd);

	/* If we have a number that's less than 0, then we have an invalid position. Either we're already in the network or there's not enough room */
	if(wPos < 0)
		return;

	/* Well, we have a valid position, so let's put this mech in the network */
	MechC3iNetworkElem(mech, wPos) = mechToAdd->mynum;
	MechC3iNetworkSize(mech) += 1;

	mech_notify(mech, MECHALL,
				tprintf("%s connects to your C3i network.",
						GetMechToMechID(mech, mechToAdd)));

	/* Now let's replicate the new network across the system so that everyone has the same network settings */
	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		otherRef = MechC3iNetworkElem(mech, i);

		otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 0);

		if(!otherMech)
			continue;

		if(!Good_obj(otherMech->mynum))
			continue;

		if(otherRef != mechToAdd->mynum) {
			otherNotifyMech = getOtherMechInNetwork(mech, i, 1, 1, 1, 0);

			if(otherNotifyMech)
				mech_notify(otherNotifyMech, MECHALL,
							tprintf("%s connects to your C3i network.",
									GetMechToMechID(otherNotifyMech,
													mechToAdd)));
		}

		replicateC3iNetwork(mech, otherMech);
	}

	/* Last, but not least, one final validation of the network */
	validateC3iNetwork(mech);
}

void clearMechFromC3iNetwork(dbref refToClear, MECH * mech)
{
	int i;

	debugC3(tprintf("CLEAR: %d from the C3i network of %d", refToClear,
					mech->mynum));

	if(!MechC3iNetworkSize(mech))
		return;

	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		if(MechC3iNetworkElem(mech, i) == refToClear)
			MechC3iNetworkElem(mech, i) = -1;
	}

	validateC3iNetwork(mech);
}

void clearC3iNetwork(MECH * mech, int tClearFromOthers)
{
	MECH *otherMech;
	int i;

	debugC3(tprintf("CLEAR: %d's C3i network", mech->mynum));

	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 0);

		MechC3iNetworkElem(mech, i) = -1;

		if(tClearFromOthers) {
			if(!otherMech)
				continue;

			if(!Good_obj(otherMech->mynum))
				continue;

			clearMechFromC3iNetwork(mech->mynum, otherMech);
		}
	}

	MechC3iNetworkSize(mech) = 0;
}

void validateC3iNetwork(MECH * mech)
{
	MECH *otherMech;
	dbref myTempNetwork[C3I_NETWORK_SIZE];
	int i;
	int networkSize = 0;

	debugC3(tprintf("VALIDATE: %d's C3i network", mech->mynum));

	if(!HasC3i(mech) || Destroyed(mech) || C3iDestroyed(mech)) {
		clearC3iNetwork(mech, 1);

		return;
	}

	if(MechC3iNetworkSize(mech) < 0) {
		clearC3iNetwork(mech, 1);

		return;
	}

	for(i = 0; i < C3I_NETWORK_SIZE; i++) {
		otherMech = getOtherMechInNetwork(mech, i, 0, 0, 0, 0);

		if(!otherMech)
			continue;

		if(!Good_obj(otherMech->mynum))
			continue;

		debugC3(tprintf("VALIDATE INFO: %d is now in %d's C3i network",
						otherMech->mynum, mech->mynum));

		myTempNetwork[networkSize++] = otherMech->mynum;
	}

	clearC3iNetwork(mech, 0);

	for(i = 0; i < networkSize; i++)
		MechC3iNetworkElem(mech, i) = myTempNetwork[i];

	MechC3iNetworkSize(mech) = networkSize;

	debugC3(tprintf("VALIDATE INFO: %d's C3i network is %d elements",
					mech->mynum, MechC3iNetworkSize(mech)));
}

void mech_c3i_join_leave(dbref player, void *data, char *buffer)
{
	MECH *mech = (MECH *) data, *target;
	MAP *objMap;
	char *args[2];
	dbref refTarget;
	int LOS = 1;
	float range = 0.0;

	cch(MECH_USUALO);

	DOCHECK(mech_parseattributes(buffer, args, 2) != 1,
			"Invalid number of arguments to function!");

	DOCHECK(!HasC3i(mech), "This unit is not equipped with C3i!");
	DOCHECK(C3iDestroyed(mech), "Your C3i system is destroyed!");
	DOCHECK(AnyECMDisturbed(mech),
			"Your C3i system is not currently operational!");

	validateC3iNetwork(mech);

	/* Clear our C3i Network */
	if(!strcmp(args[0], "-")) {
		if(MechC3iNetworkSize(mech) <= 0) {
			mech_notify(mech, MECHALL,
						"You are not connected to a C3i network!");

			return;
		}

		clearC3iNetwork(mech, 1);

		mech_notify(mech, MECHALL, "You disconnect from the C3i network.");

		return;
	}

	/* Well, if we're here then we wanna connect to a network */
	/* Let's check to see if we're already in one... can't be in two at the same time */
	DOCHECK(MechC3iNetworkSize(mech) > 0,
			"You are already in a C3i network!");

	objMap = getMap(mech->mapindex);

	/* Find who we're trying to connect to */
	refTarget = FindTargetDBREFFromMapNumber(mech, args[0]);
	target = getMech(refTarget);

	if(target) {
		LOS =
			InLineOfSight(mech, target, MechX(target), MechY(target), range);
	} else
		refTarget = 0;

	DOCHECK((refTarget < 1) ||
			!LOS, "That is not a valid targetID. Try again.");
	DOCHECK(MechTeam(mech) != MechTeam(target),
			"You can't use the C3i network of unfriendly units!");
	DOCHECK(mech == target, "You can't connect to yourself!");
	DOCHECK(Destroyed(target), "That unit is destroyed!");
	DOCHECK(!Started(target), "That unit is not started!");
	DOCHECK(!HasC3i(target),
			"That unit does not appear to be equipped with C3i!");

	/* validate the network of our target */
	validateC3iNetwork(target);
	DOCHECK(MechC3iNetworkSize(target) >= C3I_NETWORK_SIZE,
			"That unit's C3i network is operating at maximum capacity!");

	/* Connect us up */
	mech_notify(mech, MECHALL, tprintf("You connect to %s's C3i network.",
									   GetMechToMechID(mech, target)));

	addMechToC3iNetwork(target, mech);
}

void mech_c3i_message(dbref player, MECH * mech, char *buffer)
{
	cch(MECH_USUALO);

	DOCHECK(!HasC3i(mech), "This unit is not equipped with C3i!");
	DOCHECK(C3iDestroyed(mech), "Your C3i system is destroyed!");
	DOCHECK(AnyECMDisturbed(mech),
			"Your C3i system is not currently operational!");

	validateC3iNetwork(mech);

	DOCHECK(MechC3iNetworkSize(mech) <= 0,
			"There are no other units in your C3i network!");

	skipws(buffer);
	DOCHECK(!*buffer, "What do you want to send on the C3i Network?");

	sendNetworkMessage(player, mech, buffer, 0);
}

void mech_c3i_targets(dbref player, MECH * mech, char *buffer)
{
	cch(MECH_USUALO);

	DOCHECK(!HasC3i(mech), "This unit is not equipped with C3i!");
	DOCHECK(C3iDestroyed(mech), "Your C3i system is destroyed!");
	DOCHECK(AnyECMDisturbed(mech),
			"Your C3i system is not currently operational!");

	validateC3iNetwork(mech);

	DOCHECK(MechC3iNetworkSize(mech) <= 0,
			"There are no other units in your C3i network!");

	showNetworkTargets(player, mech, 0);
}

void mech_c3i_network(dbref player, MECH * mech, char *buffer)
{
	cch(MECH_USUALO);

	DOCHECK(!HasC3i(mech), "This unit is not equipped with C3i!");
	DOCHECK(C3iDestroyed(mech), "Your C3i system is destroyed!");
	DOCHECK(AnyECMDisturbed(mech),
			"Your C3i system is not currently operational!");

	validateC3iNetwork(mech);

	DOCHECK(MechC3iNetworkSize(mech) <= 0,
			"There are no other units in your C3i network!");

	showNetworkData(player, mech, 0);
}