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>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "merc.h"
#include "tables.h"
#include "recycle.h"
#include "interp.h"

void make_note (const char *board_name, const char *sender, const char *to,
				const char *subject, const int expire_days, const char *text);

#define IS_SET_WAR(ch) (IS_SET((ch)->act, PLR_WAR) || (ch)->pcdata->still_in_war == TRUE)

#define WAR_NONE    0
#define WAR_RACE    1
#define WAR_CLASS   2
#define WAR_GENOCIDE 3
#define WAR_CLAN    4
#define MAX_WAR     5

struct war_type
{
	const char *name;
	int type;
};

const struct war_type war_table[] = {
	{"none", WAR_NONE},
	{"race", WAR_RACE},
	{"class", WAR_CLASS},
	{"genocide", WAR_GENOCIDE},
	{"clan", WAR_CLAN},
	{NULL, -1},
};

char *wartype_name (int type)
{
	int i;

	for (i = 0; war_table[i].name != NULL; i++)
		if (war_table[i].type == type)
			return capitalize (war_table[i].name);

	return "Unknown";
}

#define WAR_COST 3				// in trivia points

bool start_war (CHAR_DATA * ch, const char *argument)
{
	char arg1[MIL], arg2[MIL];
	char arg3[MIL];
	CHAR_DATA *wch, *warmaster = NULL;
	int blevel, elevel, type;

	for (warmaster = ch->in_room->people; warmaster != NULL;
		 warmaster = warmaster->next_in_room)
	{
		if (!IS_NPC (warmaster))
			continue;
		if (warmaster->spec_fun == spec_lookup ("spec_warmaster"))
			break;
	}

	if (!IS_IMMORTAL (ch)
		&& (warmaster == NULL
			|| warmaster->spec_fun != spec_lookup ("spec_warmaster")))
	{
		chprintln (ch, "You can't do that here.");
		return FALSE;
	}

	if (!IS_IMMORTAL (ch) && warmaster->fighting != NULL)
	{
		chprintln (ch, "Wait until the fighting stops.");
		return FALSE;
	}

	argument = one_argument (argument, arg1);
	argument = one_argument (argument, arg2);
	argument = one_argument (argument, arg3);

	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
	{
		int i;

		chprintln (ch, "Syntax: war start <min_level> <max_level> <type>\n\r"
				   "where <type> is either:");
		for (i = 1; war_table[i].name != NULL; i++)
			chprintf (ch, "%d - %s war\n\r", war_table[i].type,
					  war_table[i].name);
		return FALSE;
	}

	blevel = atoi (arg1);
	elevel = atoi (arg2);
	type = atoi (arg3);

	if (blevel <= 0 || blevel > MAX_LEVEL)
	{
		chprintf (ch, "Level must be between 1 and %d.\n\r", MAX_LEVEL);
		return FALSE;
	}

	if (blevel <= 0 || elevel > MAX_LEVEL)
	{
		chprintf (ch, "Level must be between 1 and %d.\n\r", MAX_LEVEL);
		return FALSE;
	}

	if (elevel < blevel)
	{
		chprintln (ch, "Max level must be greater than the min level.");
		return FALSE;
	}

	if (elevel - blevel < 5)
	{
		chprintln (ch, "Levels must have a difference of at least 5.");
		return FALSE;
	}

	if (type <= WAR_NONE || type >= MAX_WAR)
	{
		int i;

		chprintln (ch, "The type either has to be:");
		for (i = 1; war_table[i].name != NULL; i++)
			chprintf (ch, "%d (%s)\n\r", war_table[i].type,
					  war_table[i].name);
		return FALSE;
	}

	if (war_info.iswar != WAR_OFF)
	{
		chprintln (ch, "There is already a war going!");
		return FALSE;
	}

	if (!IS_IMMORTAL (ch))
	{
		char buf[MSL];

		if (ch->pcdata->trivia < WAR_COST)
		{

			sprintf (buf,
					 "It costs %d Trivia Points to start a %s war.",
					 WAR_COST, wartype_name (type));
			do_mob_tell (ch, warmaster, buf);
			return FALSE;
		}
		else
		{

			sprintf (buf,
					 "Thank you %s, %s war started, you are %d trivia points lighter.",
					 ch->name, wartype_name (type), WAR_COST);
			do_mob_tell (ch, warmaster, buf);
		}
	}

	war_info.iswar = WAR_WAITING;
	replace_string (war_info.who, ch->name);
	war_info.min_level = blevel;
	war_info.max_level = elevel;
	war_info.wartype = type;
	announce (ch, INFO_WAR,
			  "$n announces a %s war for levels %d to %d.  Type 'WAR JOIN' to kill or be killed.",
			  wartype_name (war_info.wartype), war_info.min_level,
			  war_info.max_level);
	if (ch)
		chprintf (ch,
				  "You announce a %s war for levels %d to %d.  Type 'WAR JOIN' to kill or be killed.",
				  wartype_name (war_info.wartype), war_info.min_level,
				  war_info.max_level);
	war_info.timer = 3;
	war_info.next = 0;
	for (wch = player_list; wch != NULL; wch = wch->next_player)
	{
		if (IS_SET (wch->act, PLR_WAR))
			REMOVE_BIT (wch->act, PLR_WAR);
		if (wch->pcdata->still_in_war)
			wch->pcdata->still_in_war = FALSE;
	}
	return TRUE;
}

void auto_war (void)
{
	CHAR_DATA *wch, *wch_last, *warmaster;
	int maxlvl = 0, minlvl = MAX_LEVEL, middle = LEVEL_HERO / 2;
	int clan = 0, count = 0, lbonus = 0, half = 0;
	int heros = 0;

	if (war_info.iswar != WAR_OFF)
		return;

	for (wch = player_list; wch != NULL; wch = wch->next_player)
	{
		if (!wch->desc)
			continue;

		if (!IS_NPC (wch) && !IS_IMMORTAL (wch))
		{
			count++;
			maxlvl = UMAX (maxlvl, wch->level);
			minlvl = UMIN (minlvl, wch->level);
			if (wch->level == LEVEL_HERO || wch->level == LEVEL_HERO)
				heros++;
			if (is_clan (wch))
			{
				for (wch_last = player_list; wch_last != NULL;
					 wch_last = wch_last->next_player)
				{
					if (!IS_NPC (wch_last)
						&& !IS_IMMORTAL (wch_last)
						&& is_clan (wch_last)
						&& !is_same_clan (wch, wch_last))
						clan++;
				}
			}
		}
	}
	if (count < 2)
	{
		end_war ();
		return;
	}

	lbonus = number_range (15, 30);
	minlvl = UMAX (1, minlvl - lbonus);
	maxlvl = UMIN (LEVEL_HERO, maxlvl + lbonus);
	half = ((maxlvl - minlvl) / 2);
	middle = URANGE (minlvl, maxlvl - half, maxlvl);
	minlvl = UMAX (1, number_range (minlvl, (middle * 2) / 3));
	if (heros > 2 && number_percent () < 25)
		maxlvl = LEVEL_HERO;
	else
		maxlvl = UMIN (LEVEL_HERO, number_range ((middle * 3) / 2, maxlvl));
	for (warmaster = char_list; warmaster != NULL;
		 warmaster = warmaster->next)
		if (warmaster->pIndexData
			&& warmaster->pIndexData->vnum == MOB_VNUM_WARMASTER)
			break;
	war_info.iswar = WAR_WAITING;
	replace_string (war_info.who,
					(!warmaster ? "AutoWar (tm)" : warmaster->short_descr));
	war_info.min_level = minlvl;
	war_info.max_level = maxlvl;

	if (clan >= 2)
		war_info.wartype = number_range (WAR_NONE, MAX_WAR - 1);
	else
		war_info.wartype = number_range (WAR_NONE, MAX_WAR - 2);

	if (war_info.wartype == WAR_NONE)
		war_info.wartype = WAR_GENOCIDE;

	announce (warmaster, INFO_WAR,
			  "%s %s war for levels %d to %d%s.  Type 'WAR JOIN' to kill or be killed.",
			  !warmaster ? "A" : "$n announces a",
			  wartype_name (war_info.wartype), war_info.min_level,
			  war_info.max_level, !warmaster ? " has started" : "");
	if (warmaster)
		chprintf (warmaster,
				  "You announce a %s war for levels %d"
				  " to %d.  Type 'WAR JOIN' to kill or be killed.",
				  wartype_name (war_info.wartype), war_info.min_level,
				  war_info.max_level);
	war_info.timer = 3;
	war_info.next = 0;
	for (wch = player_list; wch != NULL; wch = wch->next_player)
	{
		if (IS_SET (wch->act, PLR_WAR))
			REMOVE_BIT (wch->act, PLR_WAR);
		if (wch->pcdata->still_in_war)
			wch->pcdata->still_in_war = FALSE;
	}
}

void end_war (void)
{
	CHAR_DATA *wch;

	replace_string (war_info.who, "");
	war_info.wartype = WAR_NONE;
	war_info.min_level = 0;
	war_info.max_level = 0;
	war_info.iswar = WAR_OFF;
	war_info.inwar = 0;
	war_info.timer = 0;
	war_info.next = number_range (100, 200);
	for (wch = player_list; wch != NULL; wch = wch->next_player)
	{
		if (IS_SET_WAR (wch))
		{
			stop_fighting (wch, TRUE);
			REMOVE_BIT (wch->act, PLR_WAR);
			wch->pcdata->still_in_war = FALSE;
			if (IS_SET (wch->in_room->room_flags, ROOM_ARENA)
				|| wch->in_room->vnum == ROOM_VNUM_WAITROOM)
			{
				char_from_room (wch);
				char_to_room (wch, get_room_index (ROOM_VNUM_TEMPLE));
			}
			wch->hit = wch->max_hit;
			wch->mana = wch->max_mana;
			wch->move = wch->max_move;
			update_pos (wch);
			do_function (wch, &do_look, "auto");
		}
	}
}

const char *wartype_info (CHAR_DATA * ch)
{
	switch (war_info.wartype)
	{
	default:
		return "";
	case WAR_RACE:
		return race_table[ch->race].name;
	case WAR_CLASS:
		return class_table[ch->Class[0]].name;
	case WAR_GENOCIDE:
		return "";
	case WAR_CLAN:
		return clan_table[ch->clan].who_name;
	}
}

CH_CMD (do_war)
{
	char arg[MIL];
	ROOM_INDEX_DATA *location;
	int i = 0;

	if (IS_NPC (ch))
	{
		chprintln (ch, "Mobiles not supported yet.");
		return;
	}

	argument = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "{gSyntax:{R  war {Wstart <minlev> <maxlev> <#type>");
		chprintln (ch, "         {Rwar {Wtalk <message>");
		chprintln (ch, "         {Rwar {Wstatus");
		chprintln (ch, "         {Rwar {Winfo");
		chprintln (ch, "         {Rwar {Wjoin{x");
		if (IS_IMMORTAL (ch))
			chprintln (ch, "         {Rwar {Wend{x");
		return;
	}
	else if (!str_cmp (arg, "start"))
	{
		if (ch->pcdata->trivia < WAR_COST && !IS_IMMORTAL (ch))
		{
			chprintf (ch,
					  "It costs %d Trivia Points to start a war.\n\r",
					  WAR_COST);
			return;
		}
		if (start_war (ch, argument) && !IS_IMMORTAL (ch))
			ch->pcdata->trivia -= WAR_COST;
		return;
	}

	else if (!str_cmp (arg, "talk"))
	{
		war_talk (ch, argument);
		return;
	}
	else if (!str_cmp (arg, "next") && IS_IMMORTAL (ch))
	{
		if (war_info.iswar == WAR_RUNNING)
		{
			chprintln (ch, "Not while a war is running.");
			return;
		}

		i = is_number (argument) ? atoi (argument) : number_range (30, 100);
		war_info.next = i;
		chprintf (ch, "The next war will start in %d minutes.\n\r",
				  war_info.next);
		return;
	}

	if (war_info.iswar != WAR_RUNNING && war_info.iswar != WAR_WAITING)
	{
		chprintf (ch,
				  "There is no war going! The next war will start in %d minutes.",
				  war_info.next);
		return;
	}

	if (!str_cmp (arg, "end") && IS_IMMORTAL (ch))
	{
		end_war ();
		announce (ch, INFO_WAR,
				  "$n has ended the war. The next autowar will start in %d minutes.",
				  war_info.next);
		announce (ch, INFO_WAR | INFO_PRIVATE,
				  "You have ended the war. The next autowar will start in %d minutes.",
				  war_info.next);
		return;
	}
	else if (!str_cmp (arg, "info"))
	{
		char buf[MSL];

		stringf (buf, 0, ALIGN_CENTER, "-", "[ {WWAR INFO{g ]");
		chprintf (ch, "{g%s{x\n\r", buf);
		chprintf (ch, "{RStarted by  : {W%s\n\r",
				  IS_NULLSTR (war_info.who) ? "Unknown" : war_info.who);
		chprintf (ch, "{RFighting    : {W%d player%s.\n\r",
				  war_info.inwar, war_info.inwar == 1 ? "" : "s");
		chprintf (ch, "{RLevels      : {W%d - %d{x\n\r",
				  war_info.min_level, war_info.max_level);
		chprintf (ch, "{RStatus      : {W%s for %d minutes.{x\n\r",
				  war_info.iswar == WAR_WAITING ? "Waiting" : "Running",
				  war_info.timer);
		chprintf (ch, "{RType        : {W%s war.{x\n\r",
				  wartype_name (war_info.wartype));
		chprintf (ch, "{g%s{x\n\r", draw_line (NULL, 0));
		return;
	}
	else if (!str_cmp (arg, "status"))
	{
		CHAR_DATA *wch;
		char buf[MSL];
		bool found = FALSE;

		stringf (buf, 0, ALIGN_CENTER, "-", "[ {WWAR COMBATENTS{g ]");
		chprintf (ch, "{g%s{x\n\r", buf);
		for (wch = player_list; wch != NULL; wch = wch->next_player)
		{
			if (IS_SET (wch->act, PLR_WAR))
			{
				chprintf (ch,
						  "{W%-12s : [{R%ld%% hit{W] [{M%ld%% mana{W] [Pos: {G%s{W]{x",
						  wch == ch ? "You" : wch->name,
						  wch->hit * 100 / wch->max_hit,
						  wch->mana * 100 / wch->max_mana,
						  position_flags[wch->position].name);
				found = TRUE;
			}
		}
		if (!found)
			chprintln (ch, "No one in the war yet.");
		chprintf (ch, "{g%s{x\n\r", draw_line (NULL, 0));
		return;
	}
	else if (!str_cmp (arg, "join"))
	{

		if (ch->fighting != NULL)
		{
			chprintln (ch, "You're a little busy right now.");
			return;
		}

		if (war_info.iswar == WAR_RUNNING)
		{
			chprintln (ch, "The war has already started, your too late.");
			return;
		}

		if (ch->level < war_info.min_level || ch->level > war_info.max_level)
		{
			chprintln (ch, "Sorry, you can't join this war.");
			return;
		}

		if (IS_SET_WAR (ch))
		{
			chprintln (ch, "You are already in the war.");
			return;
		}
		if (IS_QUESTOR (ch) || ON_GQUEST (ch))
		{
			chprintln (ch, "What? And leave your quest?");
			return;
		}

		if (IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL))
		{
			chprintln (ch, "Something prevents you from leaving.");
			return;
		}

		if (war_info.wartype == WAR_CLAN && !is_clan (ch))
		{
			chprintln (ch, "You aren't in a clan, you can't join this war.");
			return;
		}

		if ((location = get_room_index (ROOM_VNUM_WAITROOM)) == NULL)
		{
			chprintln (ch, "Arena is not yet completed, sorry.");
			return;
		}
		else
		{
			act ("$n goes to get $s ass whipped in war!", ch, NULL,
				 NULL, TO_ROOM);
			char_from_room (ch);
			char_to_room (ch, location);
			ch->pcdata->still_in_war = TRUE;
			SET_BIT (ch->act, PLR_WAR);
			if (war_info.wartype == WAR_GENOCIDE)
				announce (NULL, INFO_WAR,
						  "%s (Level %d) joins the war!", ch->name,
						  ch->level);
			else
				announce (NULL, INFO_WAR,
						  "%s (Level %d, %s) joins the war!",
						  ch->name, ch->level, wartype_info (ch));
			act ("$n arrives to get $s ass whipped!", ch, NULL, NULL,
				 TO_ROOM);
			war_info.inwar++;
			do_function (ch, &do_look, "auto");
		}
		return;
	}
	do_war (ch, "");
	return;
}

bool abort_race_war (void)
{
	CHAR_DATA *ch;
	CHAR_DATA *vict;

	for (ch = player_list; ch != NULL; ch = ch->next_player)
	{
		if (IS_SET (ch->act, PLR_WAR))
		{
			for (vict = player_list; vict != NULL; vict = vict->next_player)
			{
				if (IS_SET (vict->act, PLR_WAR))
				{
					if (ch->race == vict->race)
						continue;
					else
						return FALSE;
				}
			}
		}
	}
	return TRUE;
}

bool abort_class_war (void)
{
	CHAR_DATA *ch;
	CHAR_DATA *vict;

	for (ch = player_list; ch != NULL; ch = ch->next_player)
	{
		if (IS_SET (ch->act, PLR_WAR))
		{
			for (vict = player_list; vict != NULL; vict = vict->next_player)
			{
				if (IS_SET (vict->act, PLR_WAR))
				{
					if (prime_class (ch) == prime_class (vict))
						continue;
					else
						return FALSE;
				}
			}
		}
	}
	return TRUE;
}

bool abort_clan_war (void)
{
	CHAR_DATA *ch;
	CHAR_DATA *vict;

	for (ch = player_list; ch != NULL; ch = ch->next_player)
	{
		if (IS_SET (ch->act, PLR_WAR) && is_clan (ch))
		{
			for (vict = player_list; vict != NULL; vict = vict->next_player)
			{
				if (IS_SET (vict->act, PLR_WAR) && is_clan (vict))
				{
					if (is_same_clan (ch, vict))
						continue;
					else
						return FALSE;
				}
			}
		}
	}
	return TRUE;
}

void note_war (CHAR_DATA * ch)
{
	BUFFER *output;
	char sender[MIL], subject[MIL], buf[MSL];
	CHAR_DATA *wch;

	if (war_info.iswar != WAR_RUNNING)
		return;

	output = new_buf ();
	add_buf (output, "{WWAR INFO{g\n\r--------{x");
	sprintf (buf, "{RStarted by  : {W%s",
			 IS_NULLSTR (war_info.who) ? "AutoWar (Tm)" : war_info.who);
	add_buf (output, buf);
	sprintf (buf, "{RLevels      : {W%d - %d{x", war_info.min_level,
			 war_info.max_level);
	add_buf (output, buf);
	sprintf (buf, "{RType        : {W%s war.{x",
			 wartype_name (war_info.wartype));
	add_buf (output, buf);
	add_buf (output, "{WWAR COMBATENTS{g\n\r--------------{x");
	for (wch = player_list; wch != NULL; wch = wch->next_player)
	{
		if (!IS_SET_WAR (wch))
			continue;
		if (war_info.wartype != 3)
			sprintf (buf, "{W%12s : (%s){x", wch->name, wartype_info (wch));
		else
			sprintf (buf, "{W%s{x", wch->name);
		add_buf (output, buf);
	}
	add_buf (output, "{g--------------{x");
	switch (war_info.wartype)
	{
	case WAR_RACE:
		sprintf (buf, "{WThe {R%s's{W won this war.{x",
				 race_table[ch->race].name);
		add_buf (output, buf);
		break;
	case WAR_CLASS:
		sprintf (buf, "{WThe {R%s's{W won this war.{x",
				 class_table[ch->Class[0]].name);
		add_buf (output, buf);
		break;
	case WAR_GENOCIDE:
		sprintf (buf, "{R%s{W won the Genocide war.{x", ch->name);
		add_buf (output, buf);
		break;
	case WAR_CLAN:
		sprintf (buf, "{R%s{W won this war.{x",
				 clan_table[ch->clan].who_name);
		add_buf (output, buf);
		break;
	}

	sprintf (subject, "War Info %s", ctime (&current_time));
	sprintf (sender, "%s",
			 IS_NULLSTR (war_info.who) ? "AutoWar (Tm)" : war_info.who);
	make_note ("General", sender, "All", subject, 15, buf_string (output));
	free_buf (output);
	return;
}

void war_update (void)
{
	if (war_info.iswar == WAR_OFF && war_info.next > 0)
	{
		if (--war_info.next <= 0)
			auto_war ();
	}

	else if (war_info.iswar == WAR_WAITING)
	{
		vnum_t randm = 0;

		war_info.timer--;

		if (war_info.timer > 0)
		{
			announce (NULL, INFO_WAR,
					  "%d minute%s left to join the war. (Levels %d - %d, %s War)",
					  war_info.timer, war_info.timer == 1 ? "" : "s",
					  war_info.min_level, war_info.max_level,
					  wartype_name (war_info.wartype));
		}
		else
		{
			if (war_info.inwar < 2)
			{
				end_war ();
				announce (NULL, INFO_WAR, "Not enough people for war.");
			}
			else if (war_info.wartype == WAR_RACE && abort_race_war ())
			{
				end_war ();
				announce (NULL, INFO_WAR, "Not enough races for war.");
			}
			else if (war_info.wartype == WAR_CLASS && abort_class_war ())
			{
				end_war ();
				announce (NULL, INFO_WAR, "Not enough classes for war.");
			}
			else if (war_info.wartype == WAR_CLAN && abort_clan_war ())
			{
				end_war ();
				announce (NULL, INFO_WAR, "Not enough clans for war");
			}
			else
			{
				CHAR_DATA *wch;

				announce (NULL, INFO_WAR,
						  "The battle begins! %d players are fighting!",
						  war_info.inwar);
				war_info.timer =
					number_range (3 * war_info.inwar, 5 * war_info.inwar);
				war_info.iswar = WAR_RUNNING;
				for (wch = player_list; wch != NULL; wch = wch->next_player)
				{
					if (IS_SET (wch->act, PLR_WAR))
					{
						randm = number_range (17601, 17636);
						char_from_room (wch);
						char_to_room (wch, get_room_index (randm));
						do_function (wch, &do_look, "auto");
					}
				}
			}
		}
	}

	else if (war_info.iswar == WAR_RUNNING)
	{
		if (war_info.inwar == 0)
		{
			end_war ();
			announce (NULL, INFO_WAR, "No one left in the war");
			return;
		}

		switch (war_info.timer)
		{
		case 0:
			end_war ();
			announce (NULL, INFO_WAR, "Time has run out!");
			return;
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 10:
		case 15:
			announce (NULL, INFO_WAR,
					  "%d minute%s remaining in the war.",
					  war_info.timer, war_info.timer > 1 ? "s" : "");
		default:
			war_info.timer--;
			break;
		}
		return;
	}
}

void check_war (CHAR_DATA * ch, CHAR_DATA * victim)
{
	CHAR_DATA *wch;
	int reward;
	int qreward;

	if (IS_NPC (ch) || IS_NPC (victim))
		return;

	reward = number_range (500, 1500);
	qreward = number_range (50, 150);

	REMOVE_BIT (victim->act, PLR_WAR);
	victim->pcdata->still_in_war = TRUE;
	war_info.inwar--;
	stop_fighting (victim, TRUE);
	stop_fighting (ch, TRUE);
	char_from_room (victim);
	char_to_room (victim, get_room_index (ROOM_VNUM_WAITROOM));
	if (victim->hit < 1)
		victim->hit = 1;
	if (victim->mana < 1)
		victim->mana = 1;
	if (victim->move < 1)
		victim->move = 1;
	update_pos (victim);
	do_function (victim, &do_look, "auto");
	chprintln (victim,
			   "Please wait here untill the war ends and you'll be transfered and healed.");
	chprintln (ch, "");
	chprintln (victim, "");
	announce (NULL, INFO_WAR, "%s was killed in combat by %s!{x",
			  victim->name, ch->name);

	switch (war_info.wartype)
	{
	case WAR_RACE:
		if (abort_race_war ())
		{
			announce (NULL, INFO_WAR, "The %s's have won the War!",
					  race_table[ch->race].name);
			note_war (ch);
			for (wch = player_list; wch != NULL; wch = wch->next_player)
			{
				if (!IS_SET_WAR (wch))
					continue;

				if (wch->race == ch->race)
				{
					wch->gold += reward;
					wch->pcdata->questpoints += qreward;
					chprintf (wch,
							  "You recieve %d gold and %d questpoints from the war tribunal!",
							  reward, qreward);
				}
			}
			end_war ();
			return;
		}						// end abort
		break;
	case WAR_CLASS:
		if (abort_class_war ())
		{
			announce (NULL, INFO_WAR, "The %s's have won the War!{x",
					  class_table[ch->Class[0]].name);
			note_war (ch);
			for (wch = player_list; wch != NULL; wch = wch->next_player)
			{
				if (!IS_SET_WAR (wch))
					continue;
				if (wch->Class[0] == ch->Class[0])
				{
					wch->gold += reward;
					wch->pcdata->questpoints += qreward;
					chprintf (wch,
							  "You recieve %d gold and %d questpoints from the war tribunal!",
							  reward, qreward);
				}
			}
			end_war ();
			return;
		}
		break;
	case WAR_CLAN:
		if (abort_clan_war ())
		{
			announce (NULL, INFO_WAR, "%s has won the War!{x",
					  clan_table[ch->clan].who_name);
			note_war (ch);
			for (wch = player_list; wch != NULL; wch = wch->next_player)
			{
				if (!IS_SET_WAR (wch))
					continue;
				if (is_same_clan (ch, wch))
				{
					wch->gold += reward;
					wch->pcdata->questpoints += qreward;
					chprintf (wch,
							  "You recieve %d gold and %d questpoints from the war tribunal!",
							  reward, qreward);
				}
			}
			end_war ();
			return;
		}
		break;
	case WAR_GENOCIDE:
		if (war_info.inwar == 1)
		{
			announce (ch, INFO_WAR, "$n has won the War!");
			chprintln (ch, "You have won the War!");
			note_war (ch);
			ch->gold += reward;
			ch->pcdata->questpoints += qreward;
			chprintf (ch,
					  "You recieve %d gold and %d questpoints from the war tribunal!",
					  reward, qreward);
			end_war ();
			return;
		}
		break;
	}
	return;
}

bool is_safe_war (CHAR_DATA * ch, CHAR_DATA * wch)
{
	if (war_info.iswar == WAR_OFF)
		return FALSE;

	if (!IS_IN_WAR (ch) || !IS_IN_WAR (wch))
		return FALSE;

	if (war_info.wartype == WAR_GENOCIDE)
		return FALSE;

	if (war_info.wartype == WAR_RACE && ch->race == wch->race)
		return TRUE;

	if (war_info.wartype == WAR_CLASS && ch->Class[0] == wch->Class[0])
		return TRUE;

	if (war_info.wartype == WAR_CLAN && is_same_clan (ch, wch))
		return TRUE;

	return FALSE;
}

void war_talk (CHAR_DATA * ch, const char *argument)
{
	DESCRIPTOR_DATA *d;

	if (argument[0] == '\0')
	{
		chprintln (ch,
				   "Wartalk about what?\n\rUse 'info war' to toggle this channel.");
		return;
	}

	chprintf (ch, "{Y({RWarTalk{Y) {gYou drum: %s{x\n\r", argument);

	for (d = descriptor_list; d != NULL; d = d->next)
	{
		CHAR_DATA *victim;

		if (d->connected == CON_PLAYING && (victim = CH (d)) != ch
			&& !IS_SET (victim->info_settings, INFO_WAR)
			&& !IS_SET (victim->comm, COMM_QUIET))
		{
			chprintf (victim, "{Y({RWarTalk{Y) {g%s drums: %s{x",
					  PERS (ch, victim), argument);
		}
	}
	return;
}

void extract_war (CHAR_DATA * ch)
{
	if (war_info.iswar != WAR_OFF && IS_SET (ch->act, PLR_WAR))
	{
		REMOVE_BIT (ch->act, PLR_WAR);
		war_info.inwar--;
		if (war_info.iswar == WAR_RUNNING)
		{
			if (war_info.inwar == 0 || war_info.inwar == 1)
			{
				announce (ch, INFO_WAR, "$n has left. War over.");
				end_war ();
			}
			if (abort_race_war ())
			{
				announce (ch, INFO_WAR, "$n has left. War over.");
				end_war ();
			}
			else if (abort_class_war ())
			{
				announce (ch, INFO_WAR, "$n has left. War over.");
				end_war ();
			}
			else if (abort_clan_war ())
			{
				announce (ch, INFO_WAR, "$n has left. War over.");
				end_war ();
			}
			else
			{
				announce (ch, INFO_WAR,
						  "$n has left. %d players in the war.",
						  war_info.inwar);
			}
		}
		char_from_room (ch);
		char_to_room (ch, get_room_index (ROOM_VNUM_TEMPLE));
	}
}