/
rogue25b1/
rogue25b1/space/planets/
rogue25b1/space/prototypes/
rogue25b1/space/ships/
/*
 * Clan stuff by Mendanbar
 * Rogue v24b5 - Saturday, July 28, 2001
 */

#include "merc.h"
#include "clans.h"


UInt32	top_of_clant;
struct	clan_type	*clan_table;

char *clan_ranks[] = {
    "Applicant",
    "Member",
    "Commander",
    "Leader",
    "\n"
};

/* Clan Functions */

ACMD(do_clanlist) {
    UInt32 clan, count = 0;
    char buf[MAX_STRING_LENGTH];

    strcpy(buf, "   #  Leader      Members  Clan Name\n\r");
    strcat(buf, "-----------------------------------------------------------\n\r");

    for (clan = 1; clan < top_of_clant; clan++) {
	sprintf(buf+strlen(buf), " %3d. %-15s %3d. %s\n\r",
		CLAN_VNUM(clan), CLAN_OWNER(clan),
		CLAN_MEMBERS(clan), CLAN_NAME(clan));
	count++;
    }
    if (count == 0)
	strcat(buf, "There are no clans at this time.\n\r");
    page_to_char(buf, ch);
    return;
}

ACMD(do_clanwho) {
    RNum clan;
    CHAR_DATA *wch;
    UInt32 players = 0;
    DESCRIPTOR_DATA *d;
    char buf[MAX_STRING_LENGTH];

    one_argument(argument, buf);

    clan = real_clan(IS_STAFF(ch) ? atoi(buf) : GET_CLAN(ch));

    if ((clan == -1) || ((GET_CLAN_RANK(ch) < CLAN_MEMBER) && !IS_STAFF(ch))) {
	if (IS_STAFF(ch))
		ch->Send("That clan does not exist.\n\r");
	else
		ch->Send("You aren't even in a clan!\n\r");
	return;
    }

    strcpy(buf,	"Clan Members currently online\n\r"
		"-----------------------------\n\r");

    for (d = descriptor_list; d != NULL; d = d->next) {
	if (!(wch = Original(d)))				continue;
	if ((STATE(d) != CON_PLAYING) || !can_see(ch, wch))	continue;
	if (GET_CLAN(wch) != clan)				continue;

	sprintf(buf+strlen(buf), "[%-9s] %s%s`n\n\r",
		clan_ranks[GET_CLAN_RANK(wch)],
		wch->name, wch->pcdata->title);
	players++;
    }
    if (players == 0)
	strcat(buf, "\n\rNo clan members are currently visible to you.\n\r");
    else
	sprintf(buf+strlen(buf), "\n\rThere %s %d visible clan member%s.\r\n", (players == 1 ? "is" : "are"), players, (players == 1 ? "" : "s"));
    page_to_char(buf, ch);
    return;
}

ACMD(do_apply) {
    RNum clan;
    VNum vnum;
    char arg[MAX_INPUT_LENGTH];

    one_argument(argument, arg);

    if (IS_NPC(ch) || IS_STAFF(ch))
	ch->Send("You can't join a clan you dolt!\n\r");
    else if ((real_clan(GET_CLAN(ch)) != -1) && (GET_CLAN_RANK(ch) > CLAN_APPLY))
	ch->Send("You are already a member of a clan.\n\r");
    else if (!*arg || (clan = real_clan(vnum = atoi(arg))) < 0)
	ch->Send("Apply to WHAT clan?\n\r");
    else {
	GET_CLAN(ch)		= clan;
	GET_CLAN_RANK(ch)	= CLAN_APPLY;
	ch->Send("You have applied to '%s'\n\r", CLAN_NAME(GET_CLAN(ch)));
    }
    return;
}

ACMD(do_resign) {
    RNum clan;

    if (IS_NPC(ch))
	ch->Send("Very funny.\n\r");
    else if ((clan = real_clan(GET_CLAN(ch))) == -1)
	ch->Send("You aren't even in a clan!\n\r");
    else {
	if (GET_CLAN_RANK(ch) > CLAN_APPLY) {
	    ch->Send("You resign from '%s'.\n\r", CLAN_NAME(clan));
	    CLAN_MEMBERS(clan) = UMAX(0, CLAN_MEMBERS(clan)-1);
	} else
	    ch->Send("You remove your application to '%s'.\n\r", CLAN_NAME(clan));
	GET_CLAN(ch)		= 0;
	GET_CLAN_RANK(ch)	= 0;
    }
    return;
}

ACMD(do_enlist) {
    RNum clan;
    CHAR_DATA *app;
    char arg[MAX_INPUT_LENGTH];

    one_argument(argument, arg);

    if (((clan = real_clan(GET_CLAN(ch))) == -1) || (GET_CLAN_RANK(ch) < CLAN_MEMBER))
	ch->Send("You aren't even in a clan!\n\r");
    else if (GET_CLAN_RANK(ch) < CLAN_COMMANDER)
	ch->Send("You are of insufficient clan rank to do that.\n\r");
    else if (!*arg)
	ch->Send("Enlist who?\n\r");
    else if (!(app = get_pc_world(ch, arg)))
	ch->Send("No-one by that name here.\n\r");
    else if (GET_CLAN(app) != GET_CLAN(ch))
	ch->Send("They aren't applying to this clan!\n\r");
    else if (GET_CLAN_RANK(app) > CLAN_APPLY)
	ch->Send("They are already in your clan!\n\r");
    else if (CLAN_MEMBERS(clan) >= MAX_CLAN_MEMBERS)
	ch->Send("You have reached your member limit!\n\r");
    else {
	ch->Send("You have enlisted %s into %s!\n\r", RealName(app), CLAN_NAME(clan));
	app->Send("You have been accepted into %s!\n\r", CLAN_NAME(clan));
	CLAN_MEMBERS(clan)	+= 1;
	GET_CLAN_RANK(app)	= CLAN_MEMBER;
    }
    return;
}

ACMD(do_clanpromote) {
    RNum clan;
    CHAR_DATA *vict;
    char arg[MAX_INPUT_LENGTH];

    one_argument(argument, arg);

    if (((clan = real_clan(GET_CLAN(ch))) == -1) || (GET_CLAN_RANK(ch) < CLAN_MEMBER))
	ch->Send("You aren't even in a clan!\n\r");
    else if (GET_CLAN_RANK(ch) < CLAN_LEADER)
	ch->Send("You are of insufficient clan rank to do that.\n\r");
    else if (!*arg)
	ch->Send("Promote who?\n\r");
    else if (!(vict = get_pc_world(ch, arg)))
	ch->Send("No-one by that name here.\n\r");
    else if (GET_CLAN(vict) != GET_CLAN(ch))
	ch->Send("They aren't even in this clan!\n\r");
    else if (ch == vict)
	ch->Send("To yourself? Dumbass.\n\r");
    else if (GET_CLAN_RANK(vict) != CLAN_MEMBER)
	ch->Send("You can only promote clan members of rank MEMBER.\n\r");
    else {
	GET_CLAN_RANK(vict)	= CLAN_COMMANDER;
	save_char_obj(vict);
	vict->Send("You have been promoted to clan Commander!\n\r");
	ch->Send("You have promoted %s to a clan Commander!\n\r", RealName(vict));
    }
    return;
}

ACMD(do_clandemote) {
    RNum clan;
    CHAR_DATA *vict;
    char arg[MAX_INPUT_LENGTH];

    one_argument(argument, arg);

    if (((clan = real_clan(GET_CLAN(ch))) == -1) || (GET_CLAN_RANK(ch) < CLAN_MEMBER))
	ch->Send("You aren't even in a clan!\n\r");
    else if (GET_CLAN_RANK(ch) < CLAN_LEADER)
	ch->Send("You are of insufficient clan rank to do that.\n\r");
    else if (!*arg)
	ch->Send("Demote who?\n\r");
    else if (!(vict = get_pc_world(ch, arg)))
	ch->Send("No-one by that name here.\n\r");
    else if (GET_CLAN(vict) != GET_CLAN(ch))
	ch->Send("They aren't even in this clan!\n\r");
    else if (ch == vict)
	ch->Send("To yourself? Dumbass.\n\r");
    else if (GET_CLAN_RANK(vict) != CLAN_COMMANDER)
	ch->Send("You can only demote clan members of rank COMMANDER.\n\r");
    else {
	GET_CLAN_RANK(vict) = CLAN_MEMBER;
	save_char_obj(vict);
	vict->Send("You have been demoted to clan Member!\n\r");
	ch->Send("You have demoted %s to a clan Member!\n\r", RealName(vict));
    }
    return;
}

ACMD(do_boot) {
    RNum clan;
    CHAR_DATA *member;
    char arg[MAX_INPUT_LENGTH];

    if ((clan = real_clan(GET_CLAN(ch))) == -1)
	ch->Send("You aren't even in a clan!\n\r");
    else if (GET_CLAN_RANK(ch) < CLAN_COMMANDER)
	ch->Send("You are of insufficient clan rank to do that.\n\r");
    else if (!*arg)
	ch->Send("Boot who?\r\n");
    else if ((member = get_pc_world(ch, arg))) {
	if (GET_CLAN(ch) != GET_CLAN(member))
	    act("$N isn't in your clan!", ch, 0, member, TO_CHAR);
	else if (GET_CLAN_RANK(ch) <= GET_CLAN_RANK(member))
	    act("$N is not below you in rank!", ch, 0, member, TO_CHAR);
	else {
	    ch->Send("You have booted %s from %s!\n\r", RealName(member), CLAN_NAME(clan));
	    member->Send("You have been booted from %s by %s!\n\r", CLAN_NAME(clan), RealName(ch));
	    GET_CLAN(member)		= 0;
	    GET_CLAN_RANK(member)	= 0;
	    CLAN_MEMBERS(clan)		= UMAX(0, CLAN_MEMBERS(clan)-1);
	}
    } else
	ch->Send("No-one by that name here.\n\r");
    return;
}

ACMD(do_forceenlist) {
    RNum clan;
    CHAR_DATA *vict;
    char arg[MAX_INPUT_LENGTH];

    one_argument(argument, arg);

    if (!*arg)
	ch->Send("Force-Enlist who?\n\r");
    else if (!(vict = get_pc_world(ch, arg)))
	ch->Send("No-one by that name here.\n\r");
    else if ((clan = real_clan(GET_CLAN(vict))) < 1)
	ch->Send("They aren't applying to a clan.\n\r");
    else if (GET_CLAN_RANK(vict) > CLAN_APPLY)
	ch->Send("They are already a member of a clan.\n\r");
    else {
	ch->Send("You have force-enlisted %s into %s!\n\r", RealName(vict), CLAN_NAME(clan));
	vict->Send("You have been accepted into %s!\n\r", CLAN_NAME(clan));
	CLAN_MEMBERS(clan) += 1;
	if (!strncmp(vict->name, CLAN_OWNER(clan), strlen(vict->name)))
	    GET_CLAN_RANK(vict) = CLAN_LEADER;
	else
	    GET_CLAN_RANK(vict) = CLAN_MEMBER;
    }
    return;
}

void save_clan_table(void) {
    FILE *fp;
    RNum clan;

    if (!(fp = fopen(CLAN_FILE, "w"))) {
	mudlogf(BRF, LVL_STAFF, TRUE, "SYSERR: Cannot write clan to disk!");
	return;
    }

    fprintf(fp, "%d\n", top_of_clant);

    for (clan = 0; clan < top_of_clant; clan++) {
	fprintf(fp,	"%d\n"		// Vnum
			"%s~\n"		// Clan Name
			"%s~\n"		// Owner
			"%d %d %d\n\n",	// Recall & Morgue, Members
		clan,
		CLAN_NAME(clan) ? CLAN_NAME(clan) : "Undefined",
		CLAN_OWNER(clan) ? CLAN_OWNER(clan) : "<NONE>",
		CLAN_RECALL(clan), CLAN_MORGUE(clan), CLAN_MEMBERS(clan));
    }
    fclose(fp);
}

void load_clan(FILE *fp, CLAN_DATA *clan) {
    clan->vnum		= fread_number(fp);
    clan->name		= fread_string(fp);
    clan->owner		= fread_string(fp);
    clan->room[0]	= fread_number(fp);
    clan->room[1]	= fread_number(fp);
    clan->members	= fread_number(fp);
}

void load_clan_table(void) {
    VNum i;
    FILE *fp;

    if (!(fp = fopen(CLAN_FILE, "r"))) {
	mudlogf(BRF, LVL_STAFF, TRUE, "SYSERR: Couldn't open %s for reading.", CLAN_FILE);
	exit(1);
    }

    fscanf(fp, "%d\n", &top_of_clant);
    clan_table = (CLAN_DATA *)malloc(sizeof(CLAN_DATA) * (top_of_clant+1));

    for (i = 0; i < top_of_clant; i++)
	load_clan(fp, &clan_table[i]);

    clan_table[top_of_clant].name = str_dup("");
    fclose(fp);
    return;
}

RNum real_clan(VNum vnum) {
    VNum clan;
    for (clan = 1; clan < top_of_clant; clan++)
	if (clan == vnum)
		return clan;
    return -1;
}

CLAN_DATA *get_clan_data(VNum vnum) {
    VNum clan;
    for (clan = 1; clan < top_of_clant; clan++)
	if (clan == vnum)
		return &clan_table[clan];
    return NULL;
}