1stMUD/corefiles/
1stMUD/gods/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements 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          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           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                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/

#include <sys/types.h>
#if !defined(WIN32)
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "interp.h"
#include "lookup.h"
#include "tables.h"

bool is_leader(CHAR_DATA * ch)
{
	return ch->rank == (MAX_RANK - 1);
}

CH_CMD(do_promote)
{
	char arg1[MIL];
	CHAR_DATA *victim;
	int rank;

	if (IS_NPC(ch))
		return;

	argument = one_argument(argument, arg1);

	if ((!is_clan(ch) || !is_leader(ch)) && !IS_IMMORTAL(ch))
	{
		chprintln(ch, "You must be a clan Leader to promote someone.");
		return;
	}

	if (IS_NULLSTR(arg1))
	{
		chprintln(ch, "Syntax: promote <char> <rank #>");
		return;
	}

	if ((victim = get_char_world(ch, arg1)) == NULL || IS_NPC(victim))
	{
		chprintln(ch, "They aren't playing.");
		return;
	}

	if (!is_clan(victim) || is_leader(victim)
		|| (!is_same_clan(ch, victim) && !IS_IMMORTAL(ch)))
	{
		chprintln(ch, "You can't promote them.");
		return;
	}

	if (!is_number(argument) || (atoi(argument) > MAX_RANK)
		|| (atoi(argument) < 1))
	{
		chprintlnf(ch, "Rank must be between 1 and %d.", MAX_RANK);
		return;
	}

	if ((rank = (atoi(argument) - 1)) == MAX_RANK - 1)
	{
		if ((number_classes(victim) < 3) && (victim->level < LEVEL_HERO / 4))
		{
			chprintlnf
				(ch,
				 "Only second or third tier players may be clan leaders before level %d.",
				 LEVEL_HERO / 4);
			return;
		}
	}

	if (victim->rank > rank)
	{
		chprintlnf(ch, "They have been demoted to %s.",
				   clan_table[victim->clan].rank[rank].rankname);
		chprintlnf(victim, "You have been demoted to %s, by %s.",
				   clan_table[victim->clan].rank[rank].rankname, ch->name);
		victim->rank = rank;
	}
	else
	{
		chprintlnf(ch, "They are now a %s of clan %s.",
				   clan_table[victim->clan].rank[rank].rankname,
				   capitalize(clan_table[victim->clan].name));
		chprintlnf(victim, "You are now a %s of clan %s.",
				   clan_table[victim->clan].rank[rank].rankname,
				   capitalize(clan_table[victim->clan].name));
		victim->rank = rank;
	}
}

CH_CMD(do_clist)
{
	int i;

	chprintln(ch, "Clans available:");
	chprintln(ch, draw_line(NULL, 0));
	for (i = 0; i < maxClan; i++)
	{
		chprintln(ch, clan_table[i].who_name);
	}
	chprintln(ch, draw_line(NULL, 0));
	chprintln(ch, "For more info use 'cinfo <clan>'.");
}

CH_CMD(do_cinfo)
{
	int i, r;

	if (argument[0] == '\0')
	{
		chprintln(ch, "Syntax: cinfo <clan name>");
		return;
	}

	if ((i = clan_lookup(argument)) == -1)
	{
		chprintln(ch, "That is not a valid clan.");
		return;
	}

	chprintlnf(ch, "Name    : %s", clan_table[i].name);
	chprintlnf(ch, "WhoName : %s", clan_table[i].who_name);
	chprintlnf(ch, "Indep   : %s",
			   clan_table[i].independent ? "TRUE" : "FALSE");
	if (IS_IMMORTAL(ch))
		chprintlnf(ch, "Hall    : %ld", clan_table[i].hall);

	for (r = 0; r < MAX_RANK; r++)
	{
		chprintlnf(ch, "Rank %d : %s [%s]", r + 1,
				   clan_table[i].rank[r].rankname,
				   clan_table[i].rank[r].shortname);
	}
}

CH_CMD(do_clanrecall)
{
	CHAR_DATA *victim;
	ROOM_INDEX_DATA *location;

	if (!is_clan(ch) || clan_table[ch->clan].independent)
	{
		chprintln(ch, "You're not in a clan.");
		return;
	}
	if (IS_NPC(ch) && !IS_SET(ch->act, ACT_PET))
	{
		chprintln(ch, "Only player can recall.");
		return;
	}
	if (IS_SET(ch->in_room->room_flags, ROOM_ARENA))
	{
		chprintln(ch, "You can't recall while in the arena!");
		return;
	}

	act("$n prays for transportation!", ch, 0, 0, TO_ROOM);

	if ((location = get_room_index(clan_table[ch->clan].hall)) == NULL)
	{
		chprintln(ch, "Your clan doesnt seem to have a clan hall.");
		return;
	}

	if (ch->in_room == location)
		return;

	if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) ||
		IS_AFFECTED(ch, AFF_CURSE))
	{
		act("$g has forsaken you.", ch, NULL, NULL, TO_CHAR);
		return;
	}

	if ((victim = ch->fighting) != NULL)
	{
		int lose, skill;

		skill = get_skill(ch, gsn_recall);

		if (number_percent() < 80 * skill / 100)
		{
			check_improve(ch, gsn_recall, FALSE, 6);
			WAIT_STATE(ch, 4);
			chprintln(ch, "You failed!");
			return;
		}

		lose = (ch->desc != NULL) ? 25 : 50;
		gain_exp(ch, 0 - lose);
		check_improve(ch, gsn_recall, TRUE, 4);
		chprintlnf(ch, "You recall from combat!  You lose %d exps.", lose);
		stop_fighting(ch, TRUE);
	}

	ch->move /= 2;
	act("$n disappears.", ch, NULL, NULL, TO_ROOM);
	char_from_room(ch);
	char_to_room(ch, location);
	act("$n appears in the room.", ch, NULL, NULL, TO_ROOM);
	do_function(ch, &do_look, "auto");

	if (ch->pet != NULL)
	{
		act("$n disappears.", ch->pet, NULL, NULL, TO_ROOM);
		char_from_room(ch->pet);
		char_to_room(ch->pet, ch->in_room);
		act("$n appears in the room.", ch->pet, NULL, NULL, TO_ROOM);
	}

	return;
}

CH_CMD(do_clanadmin)
{
	CHAR_DATA *victim;
	char arg1[MIL];
	int clan;

	if (IS_NPC(ch))
		return;

	if ((!is_clan(ch) || clan_table[ch->clan].independent || !is_leader(ch))
		&& !IS_IMMORTAL(ch))
	{
		chprintln(ch, "You must be a valid clan leader to use this command.");
		return;
	}

	argument = one_argument(argument, arg1);

	if (IS_NULLSTR(arg1))
	{
		chprintln
			(ch,
			 "      : clanadmin where                                - show location of all members online.");
		chprintln(ch,
				  "      : clanadmin promote <char> <rank#>               - promote/demote a character.");
		chprintln(ch,
				  "      : clanadmin invite <char>                        - invite a character to your clan.");
		chprintln(ch,
				  "      : clanadmin outcast <char>                       - kick a person out of your clan.");
		if (IS_IMMORTAL(ch))
			chprintln
				(ch,
				 "Imm Syntax: clanadmin <clan> <command>    - do a clanadmin command for a specific clan.");
		return;
	}
	if (IS_IMMORTAL(ch))
	{
		char arg2[MIL];

		if ((clan = clan_lookup(arg1)) == -1)
		{
			chprintln(ch, "Invalid clan.");
			return;
		}
		argument = one_argument(argument, arg2);
		strncpy(arg1, arg2, MIL);

	}
	else
	{
		clan = ch->clan;
	}

	if (!str_cmp(arg1, "where"))
	{
		bool found = FALSE;

		chprintln(ch, "Name          Position  Area");
		chprintln(ch, "----          --------  ----");
		for (victim = player_first; victim != NULL;
			 victim = victim->next_player)
		{
			if (!IS_NPC(victim) && can_see(ch, victim)
				&& !IS_SWITCHED(victim) && is_clan(victim)
				&& victim->clan == clan)
			{
				chprintlnf(ch, "%-12s %-8s %s", victim->name,
						   position_table[victim->position].name,
						   victim->in_room ? victim->in_room->
						   area->name : "Unknown");
				found = TRUE;
			}
		}
		if (!found)
			chprintln(ch, "No members found online.");
		return;
	}
	else if (!str_prefix(arg1, "promote"))
	{
		do_function(ch, &do_promote, argument);
		return;
	}
	else if (!str_prefix(arg1, "invite"))
	{
		if ((victim = get_char_world(ch, argument)) == NULL)
		{
			chprintln(ch, "They aren't playing.");
			return;
		}
		if (IS_NPC(victim))
		{
			chprintln(ch, "NPC's cannot join clans.");
			return;
		}

		if (victim == ch)
		{
			chprintln(ch, "You're stuck...only a god can help you now!");
			return;
		}
		if (is_clan(victim) && !clan_table[victim->clan].independent)
		{
			chprintln(ch, "They are in a clan already.");
			return;
		}
		if (victim->invited != -1)
		{
			chprintln(ch, "They have already been invited to join a clan.");
			return;
		}
		chprintlnf(ch, "%s has been invited to join your clan.", victim->name);
		chprintlnf(victim, "{RYou have been invited to join {x%s{x",
				   clan_table[clan].who_name);
		chprintln(victim, "{YUse {Gjoin accept{Y to join this clan,{x");
		chprintln(victim, "{Yor {Gjoin deny{Y to turn down the invitation.{x");
		victim->invited = clan;
		return;
	}
	else if (!str_prefix(arg1, "outcast"))
	{
		if ((victim = get_char_world(ch, argument)) == NULL)
		{
			chprintln(ch, "There is no such player.");
			return;
		}
		if (IS_NPC(victim))
		{
			chprintln(ch, "NPC's cannot join clans.");
			return;
		}

		if (victim == ch)
		{
			chprintln(ch, "You're stuck...only a god can help you now!");
			return;
		}
		if (!is_clan(victim) || victim->clan != clan)
		{
			chprintln(ch, "They aren't in your clan.");
			return;
		}
		if (is_leader(victim) && !IS_IMMORTAL(ch))
		{
			chprintln(ch, "You can't kick out another leader.");
			return;
		}
		chprintln(ch, "They are now clanless.");
		chprintln(victim, "Your clan leader has kicked you out!");
		victim->clan = -1;
		victim->rank = 0;
		char_from_room(victim);
		char_to_room(victim, get_room_index(ROOM_VNUM_TEMPLE));
		do_function(victim, &do_look, "auto");
		return;
	}
	else
		do_function(ch, &do_clanadmin, "");
}

CH_CMD(do_join)
{
	char arg1[MIL];
	CHAR_DATA *victim;

	argument = one_argument(argument, arg1);

	if (IS_NPC(ch))
	{
		return;
	}

	if (is_clan(ch) && !clan_table[ch->clan].independent)
	{
		chprintln(ch, "You are already in a clan.");
		return;
	}

	if (ch->invited == -1)
	{
		chprintln(ch, "You have not been invited to join a clan.");
		return;
	}

	if (!str_cmp(arg1, "accept"))
	{
		for (victim = player_first; victim != NULL;
			 victim = victim->next_player)
			if (is_clan(victim) && victim->clan == ch->invited)
				chprintlnf(victim, "%s accepts the invitation to join %s.",
						   PERS(ch, victim), clan_table[victim->clan].name);

		ch->clan = ch->invited;
		ch->rank = 0;
		chprintlnf(ch, "{RYou are now a %s of {x%s{x",
				   clan_table[ch->clan].rank[ch->rank].rankname,
				   clan_table[ch->clan].who_name);
		ch->invited = -1;
		return;
	}
	else if (!str_cmp(arg1, "deny"))
	{
		chprintln(ch, "You turn down the invitation.");
		for (victim = player_first; victim != NULL;
			 victim = victim->next_player)
			if (is_clan(victim) && victim->clan == ch->invited
				&& victim->rank >= MAX_RANK - 2)
				chprintlnf(victim, "%s denies the invitation to join %s.",
						   PERS(ch, victim), clan_table[victim->clan].name);

		ch->invited = -1;
		return;
	}
	else
	{
		chprintln(ch, "Syntax: join <accept|deny>");
		return;
	}
}