Cedit2.0/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/***************************************************************************
*	ROM 2.4 is copyright 1993-1996 Russ Taylor		           *
*	ROM has been brought to you by the ROM consortium		   *
*	    Russ Taylor (rtaylor@efn.org)				   *
*	    Gabrielle Taylor						   *
*	    Brian Moore (zump@rom.org)					   *
*	By using this code, you have agreed to follow the terms of the	   *
*	ROM license, in the file Rom24/doc/rom.license			   *
***************************************************************************/

/***************************************************************************
*       This file is for clan related commands.  Included here is:         *
*                 The JOIN command.                                        *
*                 The immortal CLEADER command.                            *
*                 The clan leader ACCEPT command.                          *
*                 The clan leader LONER command.                           *
*       Clans can be found in the clan table in tables.c                   *
*                             -Blizzard (blizzard_imp@hotmail.com)         *
***************************************************************************/

/***************************************************************************
*    Highly Modified clan system modded by Bojack of Dragonball Arena.	   *
*	Added to this file is:					   	   *
*		top_clan						   *
*		bit names						   *
*		new_clan						   *
*		free_clan						   *
*		loading clans						   *
*		is_clan							   *
*		is_same_clan						   *
*		clan_lookup						   *
*		player_rank						   *
*		player_clan						   *
*	Nothing else was modified, I purposely made it around the	   *
*	clan system written by Blizzard.				   *
***************************************************************************/

#if defined(macintosh)
#include <types.h>
#include <time.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"

#include "db.h" // For top_clan and added into do_memory 

int top_clan;
CLAN_DATA *clan_first;
CLAN_DATA *clan_last;

//Local Routines
void fread_clan (FILE *fp);
void load_clans (void);

char *clan_bit_name( int clan_flags )
{
    static char buf[512];
  
    buf[0] = '\0';
    if ( clan_flags & CLAN_INDEPENDENT	) strcat( buf, " independent");
    if ( clan_flags & CLAN_CHANGED	) strcat( buf, " changed");
    if ( clan_flags & CLAN_DELETED	) strcat( buf, " deleted");
    if ( clan_flags & CLAN_IMMORTAL	) strcat( buf, " immortal");
  
    return ( buf[0] != '\0' ) ? buf+1 : "none";
}

CLAN_DATA *new_clan(void)
{
    CLAN_DATA *pClan;

    if (!((pClan) = (CLAN_DATA *) calloc ( (1), sizeof(CLAN_DATA) )) )
    {
	logstr( LOG_BUG, "New_clan: Memory allocating for clans failed", 0);
	abort();
	return NULL;
    }

    if (clan_first == NULL)
	clan_first = pClan;

    if (clan_last != NULL)
	clan_last->next = pClan;

    pClan->next = NULL;

    //For clan deletion only
    if (clan_first == pClan)
	pClan->prev = NULL;
    else
	pClan->prev = clan_last;
    clan_last = pClan;
    pClan->name = str_dup ("New clan");
    return pClan;
}

void free_clan (CLAN_DATA *pClan)
{
    int i;

    //Change ordering in memory first
    if (pClan->prev == NULL)
    {
	clan_first = pClan->next;
	if (clan_first != NULL)
	    clan_first->prev = NULL;
    }
    else {
	pClan->prev->next = pClan->next;
    }

    if (pClan->next == NULL)
    {
	clan_last = pClan->prev;
	if (clan_last != NULL)
	    clan_last->next = NULL;
    }
    else {
	pClan->next->prev = pClan->prev;
    }

    //Null'ing all strings then free'ing memory
    pClan->name = NULL;
    pClan->who_name = NULL;
    pClan->leader = NULL;
    for (i = 1; i < MAX_RANK; i++)
	pClan->c_rank[i].rankname = NULL;

    if (pClan->flags != 0)
	pClan->flags = 0;

    if (pClan != NULL)
        free ( (void*)pClan);

    pClan = NULL;

    //Save clans
    save_clans (NULL);

    return;
}

void fread_clan (FILE *fp)
{
    char buf[MSL];
    CLAN_DATA *pClan;
    char *string;
    bool fMatch;
    int i;

    if ( ((pClan) = (CLAN_DATA *) calloc ( (1), sizeof(CLAN_DATA) )) )
    {
	for (;;)
	{
	    string = feof(fp) ? "End" : fread_word (fp);
	    fMatch = FALSE;

	    switch (UPPER(string[0]))
	    {
            	case 'C':
		    if (!str_cmp (string, "Clan") )
		    {
		        pClan->name = fread_string (fp);
	                fMatch = TRUE;
		    }
		    break;

	        case 'E':
		    if (!str_cmp (string, "End") )
		    {
		        if (clan_first == NULL)
			{
			    clan_first = pClan;
			    clan_last = pClan;
			}
			else
			    clan_last->next = pClan;

		        pClan->next = NULL;

			//For clan deletion only
			if (clan_first == pClan)
			    pClan->prev = NULL;
			else
			    pClan->prev = clan_last;

			clan_last = pClan;

		        top_clan++;
			fMatch = TRUE;
		        return;
		    }
		    break;			    

		case 'F':
		    if (!str_cmp (string, "Flags") )
		    {
		        pClan->flags = fread_flag( fp );
              	        fMatch = TRUE;
		    }
                    break;

		case 'L':
		    if (!str_cmp (string, "Leader") )
		    {
		        pClan->leader = fread_string(fp);
	                fMatch = TRUE;
		    }
	            break;
	          
	        case 'R':
	      	    if (!str_cmp(string, "Rank") || !str_cmp(string, "CRank") )
                    {
			i = fread_number(fp);
                        pClan->c_rank[i].rankname = fread_string(fp);
                        fMatch = TRUE;
                    }

	            break;

	        case 'W':
		    if (!str_cmp (string, "Who") )
		    {
		        pClan->who_name = fread_string(fp);
	      	        fMatch = TRUE;
		    }
	      	    break;
	    } /* end of switch */

	    if ( !fMatch )
	    {
	    	sprintf( buf, "Fread_clans: no string match '%s'", string );
	    	logstr( LOG_BUG, buf, 0 );
	    }
	} /* end loop */
    } /* end if */

    if (!pClan)
    {
	logstr( LOG_BUG, "Memory allocating for clans failed", 0);
	abort();
	return;
    }
}

void load_clans (void)
{
    char buf[256];
    FILE *fp;

    sprintf (buf, "%s", CLAN_FILE);
    if (!(fp = fopen( buf, "r" )) )
    {
	logstr( LOG_BUG, "Load_clans: file not found.", 0 );
	exit(1);
    }

    else
    {
	clan_first = NULL;
	clan_last = NULL;

	for (;;)
	{
	    char *word;

	    word = feof( fp ) ? "$" : fread_word( fp );

	    if (!str_cmp( word, "#CLAN" ) )
		fread_clan( fp );

	    else if (!str_cmp(word, "$") )
		break;

	    else
	    {
		char error[MSL];

		sprintf( error, "Load_clans: bad string found '%s'", word );
		logstr( LOG_BUG, error, 0 );
		break;
	    }
	}
    }
    fclose( fp );
    return;
}

bool is_clan(CHAR_DATA * ch)
{
    if (ch->clan != NULL)
    return TRUE;

    return FALSE;
} 

bool is_same_clan(CHAR_DATA * ch, CHAR_DATA * victim)
{
    if ( ch->clan != NULL && IS_SET(ch->clan->flags, CLAN_INDEPENDENT) )
        return FALSE;
    if ( victim->clan != NULL && IS_SET(victim->clan->flags, CLAN_INDEPENDENT) )
        return FALSE;
    if (ch->clan != NULL && victim->clan != NULL)
    {
        if (ch->clan != victim->clan)
            return FALSE;
    }
    return (ch->clan == victim->clan);
}

CLAN_DATA *clan_lookup (char *name)
{
    CLAN_DATA *clan;

    for (clan = clan_first; clan != NULL; clan = clan->next)
    {
	if (!str_prefix(name, clan->name))
	    return clan;
    }

    return NULL;
}

char *player_rank(CHAR_DATA * ch)
{
    if (ch->clan == NULL)
	return '\0';
    return ch->clan->c_rank[ch->c_rank].rankname;
}

char *player_clan(CHAR_DATA * ch)
{
    if (ch->clan == NULL)
	return '\0';
    return ch->clan->name;
}


/* Commands */
void do_cleader (CHAR_DATA *ch, char *argument) 
{
    CLAN_DATA *clan;
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;

    one_argument( argument, arg );

    if (arg[0] == '\0') 
    {
        sendch( "Syntax: CLEADER <name>\n\r", ch );
        return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL ) 
    {
        sendch( "They aren't here.\n\r", ch );
        return;
    }

    if (victim->level > ch->level) 
    {
        sendch( "You failed.\n\r", ch );
        return;
    }

    if (IS_SET(victim->act, PLR_LEADER)) 
    {
        REMOVE_BIT(victim->act, PLR_LEADER);
        sendch( "The gods have revoked your leadership priviliges.\n\r", victim );
        sendch( "Leadership removed.\n\r", ch );
        victim->c_rank = 1;
	if (!str_cmp (victim->clan->leader, victim->name) )
	{
	    free_string (victim->clan->leader);
	    victim->clan->leader = str_dup("Unknown");
	}
    }
    else 
    {
        if (!is_clan(victim)) 
	{
            sendch ("That person must be clanned first.\n\r", ch);
            return;
        }

	clan = victim->clan;
        free_string (victim->clan->leader);
        SET_BIT(victim->act, PLR_LEADER);
        victim->clan->leader = str_dup(victim->name);
        sendch( "The gods have made you a clan leader.\n\r", victim );
        sendch( "Leadership set.\n\r", ch );
        victim->c_rank = 7;
    }
    save_clans(NULL);
    return;
}

void do_promote(CHAR_DATA *ch, char *argument) 
{
    char arg[MAX_INPUT_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    int value;

    one_argument( argument, arg );

    if(ch->clan == NULL) 
    {
        sendch( "Huh?\n\r", ch);   
        return;
    }

    if(!IS_SET(ch->act, PLR_LEADER) )
    {
	sendch("You cannot promote anyone!\n\r", ch);
	return;
    }

    if (arg[0] == '\0' || !is_number(arg1)) 
    {
	sendch( "Who do you want to promote?\n\r", ch);
	sendch( "Type promote <name> <rank #>\n\r", ch);
	return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL ) 
    {
	sendch( "They aren't here!\n\r", ch);
	return;
    }

    if (victim == ch) 
    {
	sendch( "You cannot promote yourself!\n\r", ch);
	return;
    }
    if (victim->clan != ch->clan) 
    {
	sendch( "You cannot promote them.\n\r", ch);
	return;
    }

    if (victim->c_rank > 6) 
    {
	sendch( "You cannot promote them any higher!\n\r", ch);
	return;
    }

    value = atoi(arg1);
    if (value < 1 || value > 6) 
    {
	sendch( "Value must be 1 - 6.\n\r", ch);
	return;
    }

    if (value < victim->c_rank) 
    {
	sendch ("Use 'demote <who> <rank #>' to demote someone.\n\r", ch);
	return;
    }
    else
	victim->c_rank = value;
        sendch( "You have promoted them!\n\r", ch);
        sendch( "You have been promoted!\n\r", victim);
    return;
}

void do_demote(CHAR_DATA *ch, char *argument) 
{
    char arg[MAX_INPUT_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    int value;

    one_argument( argument, arg );

    if(ch->clan == NULL) 
    {
        sendch( "Huh?\n\r", ch);
        return;
    }

    if(!IS_SET(ch->act, PLR_LEADER) )
    {
        sendch( "You cannot demote anyone!\n\r", ch);
        return;
    }

    if (arg[0] == '\0' || !is_number(arg1)) 
    {
        sendch( "Who do you want to demote?\n\r", ch);
        sendch( "Type demote <name> <rank #>\n\r", ch);
        return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL ) 
    {
        sendch( "They aren't here!\n\r", ch);
        return;
    }

    if (IS_SET(victim->act, PLR_LEADER))
    {
        sendch("You cannot demote a leader!\n\r", ch);
        return;
    }

    if (victim == ch) 
    {
        sendch( "You cannot demote yourself!\n\r", ch);
        return;
    }

    if (victim->clan != ch->clan) 
    {
        sendch( "You cannot demote them.\n\r", ch);
        return;
    }

    if (victim->c_rank < 1) 
    {
        sendch( "You cannot demote them any lower!\n\r", ch);
        return;
    }

    value = atoi(arg1);
    if (value < 1 || value > 6)
    {
        sendch( "Value must be 1 - 6.\n\r", ch);
        return;
    }

    if (value > victim->c_rank)
    {
        sendch ("Use 'promote <who> <rank #>' to promote someone.\n\r", ch);
        return;
    }
    else
        victim->c_rank = value;
        sendch( "You have demoted them!\n\r", ch);
        sendch( "You have been demoted!\n\r", victim);
    return;
}

void do_petition (CHAR_DATA *ch, char *argument)
{
    char arg[MAX_INPUT_LENGTH];

    one_argument( argument, arg);

    if (arg[0] == '\0')
    {
	sendch ("Syntax: petition <on/off>\n\r", ch);
	return;
    }

    if (!str_cmp(arg, "off") )
    {
	sendch( "You will not allow yourself to be clanned.\n\r", ch);
        ch->petition = 0;
        return;
    }

    if (!str_cmp (arg, "on") )
    {
	sendch( "You will now allow yourself to be clanned.\n\r", ch);
	ch->petition = 1;
	return;
    }
    else
	sendch ("Syntax: petition <on/off>\n\r", ch);
    return;
}

void do_join (CHAR_DATA *ch, char *argument) 
{
    CLAN_DATA *clan;
    char arg[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];

    if (IS_SET(ch->act, PLR_LEADER)) 
    {
        sendch("You can't join another clan while you are currently a leader!\n\r"
               "Step down from leadership first.\n\r", ch);
        return;
    }

    one_argument( argument, arg );

    if (arg[0] == '\0') 
    {
	sendch ("Syntax: join <clan name>\n\r", ch);
        return;
    }

    clan = clan_lookup(arg);
    if (clan == NULL) 
    {
        sendch("There is no clan by that name.\n\r", ch);
        return;
    }

    if (!str_cmp(arg, "loner")) 
    {
        sendch("You are now a loner.\n\r", ch);
        ch->petition = 0;
	ch->clan = (clan_lookup("loner"));
	ch->c_rank = 1;
        return;
    }

    if (is_clan(ch) ) 
    {
        sendch ("You are already in a clan!\n\r", ch);
        return;
    }
 
    else 
    {
	CHAR_DATA *pch;

	sprintf (buf, "{YYou have applied to %s{x.\n\r", clan->name);
    	sendch(buf, ch);
    	ch->petition = 1;
//	ch->pendingapp = str_dup (clan->name);

	if ((pch = get_char_world(ch, clan->leader)) == NULL) 
	    return;
	else 
	{
	    sprintf (buf, "{Y%s has petitioned to join your clan.{x\n\r", ch->name);
            sendch (buf, pch);
	}
    }
    return;
}

/*
//Added Feb 11, 2009 -Bo- NEEDS FIXING!
void do_appspending (CHAR_DATA *ch, char *argument)
{
//    CHAR_DATA *pch;
    DESCRIPTOR_DATA *d;
    char arg[MIL];
    char buf[MSL];
    int count = 0;

    if (IS_NPC(ch) )
	return;

    if (!IS_SET(ch->act, PLR_LEADER) )
    {
	sendch ("You are not a clan leader.\n\r", ch);
	return;
    }

    one_argument (argument, arg);

    if (arg[0] == '\0')
    {
	sendch ("Syntax: Type 'pending applications'\n\r", ch);
	return;
    }

    if (!str_cmp (arg, "applications" ) || !str_cmp(arg, "apps") )
    {
	sendch ("Applications pending---------------\n\r", ch);
        for (d = descriptor_list; d != NULL; d = d->next)
        {
            CHAR_DATA *wch;
            if ( !(d->connected != CON_PLAYING || d->connected != CON_NOTE_TO 
		|| d->connected != CON_NOTE_SUBJECT || d->connected != CON_NOTE_EXPIRE 
		|| d->connected != CON_NOTE_TEXT || d->connected != CON_NOTE_FINISH)
		|| !can_see( ch, d->character ) )
            continue;

            wch = (d->original != NULL) ? d->original : d->character;

            if (!can_see(ch, wch))
                continue;

	    if (wch->pendingapp != NULL || wch->pendingapp[0] != '\0')
	        continue;

	    if (!str_cmp (wch->pendingapp, ch->clan->name) )
	    {
		count++;
		sprintf (buf, "%s\n\r", wch->name);
		sendch (buf, ch); 
	    }
	}

	if (count == 0)
	    sendch ("\n\rNone.\n\r", ch);
    }
    return;
}
*/
void do_accept (CHAR_DATA *ch, char *argument) 
{
    char arg[MAX_INPUT_LENGTH];
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;

    if (!IS_SET(ch->act, PLR_LEADER))
    {
        sendch("You are not a clan leader.\n\r", ch);
        return;
    }

    one_argument( argument, arg );

    if (arg[0] == '\0') 
    {
	sendch("Syntax: accept <player>.\n\r", ch);
        return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL)
    {
        sendch("They are not playing.\n\r", ch);
        return;
    }

    if (victim->petition == 0) 
    {
        sendch("They do not wish to join a clan.\n\r", ch);
        return;
    }

    victim->clan = ch->clan;
    victim->petition = 0;
    victim->c_rank = 1;
    sendch("You have accepted them into your clan.\n\r", ch);
    sprintf(buf, "You have joined %s.\n\r", victim->clan->name);
    sendch(buf, victim);
//    if (victim->pendingapp != NULL || victim->pendingapp != '\0')
//	victim->pendingapp = &str_empty[0];
    return;
}

void do_clanremove (CHAR_DATA *ch, char *argument) 
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;

    if (!IS_SET(ch->act, PLR_LEADER)) 
    {
        sendch("You are not a clan leader.\n\r", ch);
        return;
    }

    one_argument( argument, arg );

    if (arg[0] == '\0') 
    {
        sendch( "Remove who?\n\r", ch );
        return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL) 
    {
        sendch("They are not playing.\n\r", ch);
        return;
    }

    if (!is_clan(victim) )
    {
        sendch("They're not in a clan.\n\r", ch);
        return;
    }

    if (victim->clan != ch->clan)
    {
        sendch("They're not in your clan.\n\r", ch);
        return;
    }

    victim->clan = NULL;
    victim->petition = 0;
    victim->c_rank = 0;
    sendch("You have removed them from your clan.\n\r", ch);
    sendch("You have been removed from your clan.\n\r", victim);
    return;
}

void do_loner( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;

    if (!IS_SET(ch->act, PLR_LEADER)) 
    {
        sendch("You are not a clan leader.\n\r", ch);
        return;
    }

    one_argument( argument, arg );

    if (arg[0] == '\0') 
    {
        sendch( "Loner who?\n\r", ch );
        return;
    }

    if ((victim = get_char_world(ch, arg)) == NULL)
    {
        sendch("They are not playing.\n\r", ch);
        return;
    }

    if (!is_clan(victim) )
    {
        sendch("They're not in a clan.\n\r", ch);
        return;
    }

    if (victim->clan != ch->clan)
    {
        sendch("They're not in your clan.\n\r", ch);
        return;
    }

    if ((clan_lookup("loner")) == NULL)
    {
	sendch ("The 'Loner' clan doesn't exist.\n\r", ch);
	sendch ("Contact an Imm about this.\n\r", ch);
    }

    victim->clan = clan_lookup("loner");
    victim->petition = 0;
    victim->c_rank = 1;
    sendch ("You have made them a loner.\n\r", ch);
    sendch ("You have been made a loner.\n\r", victim);
    return;
}