
  Unreal Tournament Game - Plus
  copyright (c) Rodney Powers
  January 11, 2008

-------------------------------------------------------------------------------

	1. Description
	2. Game Plus
		2.1. About
		2.2. Features
		2.3. Development
			2.3.1. Playing Custom Music
			2.3.2. UTPScoreboardPanel
				2.3.2.1. Captions
				2.3.2.2. Caption Lists
			2.3.3. Scoreboard Extensions
				2.3.3.1. Overview
				2.3.3.1. Creating an Extension
				2.3.3.3. Example
	3. Invasion (Version 0.9.5)
		3.1. About
		3.2. Features
		3.3. Configuration
		  3.3.1. Global Settings
		  3.3.2. Wave Manager Configuration
		  3.3.3. Wave Set Configuration
		  3.3.4. Wave Configuration
			3.3.4.1. MonsterWave
			3.3.4.2. IntermissionWave
			3.3.4.3. MonsterBonusWave
		  3.3.5. Monster Roster Configuration
		3.4. User Commands
			3.4.1. Hud
			3.4.2. Radar
		3.5. User Ini Settings
		3.6. Development
			3.6.1. Invasion Game Mode
			3.6.2. Wave Manager
			3.6.3. Creating a Custom Wave
			3.6.4. Invasion Mutators
			3.6.5. Scoreboard Expansions
			3.6.6. Hud Elements
	4. Mutators
		4.1 Always Dualies
		4.2 Connection Logger
		4.3 Instagib Areana
		4.4 Map Specific Settings
		4.5 Open Vehicles
		4.6 Weapons Arena
		4.7 Show Player IDs
	5. Installation
	6. Credits
	7. Change Log

-------------------------------------------------------------------------------

1. Description:

UTP is a collection of things I wanted to add to the game. Currently this only
involves a revamped set of base classes for games modes that support extended
functionality and Invasion which is built off of those classes as well as a
few mutators that were made to add more flexibility to Invasion.

Why the name UTGamePlus? The original game classes are in UTGame and my code
is a bit of a plus pack for it so UTGamePlus.

-------------------------------------------------------------------------------

2. Game Plus:

2.1. About:

	This section is meant for developers who are curious about what I'm doing
	in UTGamePlus as far as what it adds. If you don't care, just skip this
	section.

	In general a lot of this was to start work on supporting multiple teams so
	that I can implement new types of game modes in the future. The first
	game mode was Invaision which is discussed in section 3. There are a few
	other small enhancements I've added, mostly geared torwards the support of
	multiple teams and Invasion right now.

2.2. Features

	* Provides support for N number of teams.
	* Provides support for changing the names and colors of the teams.
	* Provides UTPScoreInfoPanel, UTPDrawPlayerListPanel and UTPScoreboardPanel
	  that work with multiple teams.
	* Adds support for playing custom music using
	  UTPPlayerController.PlayCustomMusic.
	* Adds radar support. Set bGiveRadar to true on UTPPlayerController to have
	  a radar spawn for a player. Use RadarClass to specify the type of radar.
	* Added ScriptedGame base game mode class. This is scriptable in the form
	  of the game consisting of a series of waves. Each wave becomes and active
	  GameInfo classes modifying game rules and the players play through each
	  wave until there are no more. Victory is achieved by getting through them
	  all. This is definitely Invasion based, but this could also be extended
	  into an Assault type framework as well, with the waves being objectives.
    * UTPScoreboardPanel is a highly customizable scoreboard panel that will
      let you create almost any type of scoreboard without having to write the
      script. It uses a list of Captions for the scoreboard and per player to
      generate the scoreboard. Support for switching list styles based
      on the # of players is planned. Just give it a try.

	That's all for now. This is a placeholder for anything else I plan to add.

2.3. Development

	This section contains information related to using the UTP base classes and
	what additional abilities you can access.

2.3.1. Playing Custom Music

	Huds based off of UTPHud gain access to the UTPMusicManager which provides
	the ability to at any time play a custom peice of music.

	In order to play the music, just call PlayCustomMusic with the desired
	SoundCue you wish to play. If you've packaged this and distributed the
	package on your server, you harass your players with any song you'd like.

2.3.2. UTPScoreboardPanel

	This is my own custom scoreboard panel that provides a lot of flexibility
	when designing in the UI and when using in a game. The nicest part is that
	you can alter the text and images on the fly in unreal ed. This way you
	can fine tune the positioning of elements visually instead of messing with
	code, compiling, viewing, repeating.

2.3.2.1. Captions

	The core of the panel is the use of Captions. These are placeable objects
	with a variety of attributes for formatting their display. The attributes
	are:

	Name
		A name for the caption that can be used to find it in unrealscript.

	Visible
		Flag indicating if this should be displayed or not.

	VisibilityTest
		A special string that will run through parsers, reducing variables
		down to either a 1 or nothing. If after the parsing the string is
		not empty, the caption is displayed.

		For example, if this were: %isOut%%isBot%

		Then if the player was out and a bot the result would be: 11
		Then if the player was out and not a bot the result would be: 1
		Then if the player was not out and a bot the result would be: 1
		Then if the player was not out and not a bot the result would be: <empty>

		The first three outcomes would result in the caption being
		displayed.

	NegateVisibilityTest
		If this is set, the result of VisibilityTest is negated. In this way
		you can do a selection on everyone who is not out by setting your
		VisibilityTest to %isOut% and setting this field to true.

	ParseCaption
		Flag indicating if the caption should be parsed for variables. If you
		don't have any in the caption, turn this off.

	Caption
		The caption to display. This can contain variables that will be parsed
		into relevant text.

		For example, if the caption is: "Ping: %PlayerPing%"

		This would appear as (if the ping was 128): "Ping: 128"

	Position
		The position to render the caption. This is in relative screen
		coordinates. That means (0, 0) is (0.0, 0.0) and (ScreenWidth,
		ScreenHeight) is (1.0, 1.0).

	Dimensions
		The dimensions of the caption box. This is in relative screen
		coordinates. That means (0, 0) is (0.0, 0.0) and (ScreenWidth,
		ScreenHeight) is (1.0, 1.0).

	FontSize
		The size of the font to use. This can be Tiny, Small, Medium, or Large.

	Justification
		The text justification of the caption. This can be Left, Center,
		or Right.

	VerticalAlignment
		The vertical positioning of the text within the caption box. This can
		be Top, Middle, or Bottom.

	ColorOp
		A color operation to apply to the caption text. The options are UseColor,
		which will just use the color specified, or BlendTeamColor, which will
		multiply the color by the team color of the panel.

		The operation is also used when blending the background images.

	Color
		Color used to display the caption. Note that the color is also blended
		with any background images.

	HighlightCurrentPlayer
		If set, the text color will automatically switch to the player highlight
		color if the caption is being drawn for the current player.

	ShowBounds
		Debug flag that will draw a box representing the bounds of the caption.

	TextureIndex
		An index into the ScoreboardPanel's Textures array. The texture will
		be used as the background of the caption and blended using the color
		operations.

		If you do not want a background, set this to -1.

2.3.2.2. Caption Lists

	There are a few different set of caption lists in the scoreboard, each
	serving a different purpose.

	The first list is just Captions. This list represents global text on the
	scoreboard. This would be things like the team name, team score, or any
	generic text.

	The remaining list are stored in PlayerCaptionStyles. These list are
	referenced by PlayerListSettings and used to render a set of player
	names. This way you can have a style for the top 3 players, maybe something
	more elaborate, and then a lesser style for the remaining.

	The major difference between the Captions list and PlayerCaptionStyles is
	that Captions will not be parsed for player related variables.

	The other difference is that the Position value of Captions in
	PlayerCaptionStyles is automatically offset by the PlayerListSettings
	position, and then by the index of the player being displayed.

2.3.2. Scoreboard Expansions

2.3.3.1. Overview

	The scoreboard can be expanded in order to add new fields. This ability was
	specifically added for the future thought of an RPG mutator so that RPG
	information could be display on the scoreboard. It has been generalized
	so that any mutator can add their own information if they desire to.
	Perhaps you'd like to list the player's current weapon, kills, or deaths.
	
	In short, extensions are added by creating your own class that extends
	UTGamePlus.UTPScoreboardExtension and then making the call
	AddScoreboardExtension on UTPGameReplicationInfo. Note this is UTP, not UT.

	This will register your extension so that every client receives it and
	displays it.

2.3.3.2. Creating an Extension

	Scoreboard extensions derive from the UTPScoreboardExtension. Once you have
	your class set up there are five methods you need to potentially worry
	about.

	Apply(UTPScoreboardPanel scoreboard)
		This is the method where you can alter the elements being display in
		the scoreboard. This is by either editing the Captions list or one of
		the various PlayerCaptionStyles. Possibly more than one.

		You'll want to understand captions as these are the core of the
		scoreboard panel and its ability to be customized. See section
		2.3.2. UTPScoreboardPanel for information on them.

	ParseGlobalScoreboardText(out String text)
		This is called when a scoreboard is parsing a global caption's text.
		It provides a chance for you to replace any text with any value you'd
		like. Typically this would be a %variable% substitution where you
		could insert something like the team name using %TeamName%.

	ParseGlobalScoreboardVisibility(out String test)
		Parses a visibility test. This should reduce %variables% down to
		a blank string or a 1.

	ParsePlayerScoreboardText(out String text, PlayerReplicationInfo PRI, int rank)
		Parse text on a player by player basis, giving you access to the
		player's replication info for use in the substitution.

	ParsePlayerScoreboardVisibility(out String test, PlayerReplicationInfo PRI, int rank)
		Parses a visibility test. This should reduce %variables% down to
		a blank string or a 1.

2.3.3.3. Example

	So a short example of an extension would be to replace the score with
	kills. If the player does not have any kills then I just won't display the
	item. I'm going to write semipsuedo	code here and assume most of you get
	what I mean.

	Apply(UTPScoreboardPanel scoreboard) {
		// Loop through all the styles and replace all instances of score
		// with kills.
		for (i = 0; i < scoreboard.PlayerCaptionStyles.Length; ++i) {
			scoreIndex = scoreboard.PlayerCaptionStyles[i].CaptionList.Find('name', "Score");

			if (scoreIndex >= 0) {
				scoreboard.PlayerCaptionStyles[i].CaptionList[scoreIndex].Name = "Kills";
				scoreboard.PlayerCaptionStyles[i].CaptionList[scoreIndex].Caption = "%PlayerKills%";

				// Just for an example, only show the kills when they have some.
				scoreboard.PlayerCaptionStyles[i].CaptionList[scoreIndex].VisibilityTest = "%hasKills%";
			}
		}
	}

	ParsePlayerScoreboardText(out String text, PlayerReplicationInfo PRI, int rank)
		text = repl("%PlayerKills%", PRI.Kills);
	}

	ParsePlayerScoreboardVisibility(out String test, PlayerReplicationInfo PRI, int rank) {
		test = repl("%hasKills%", (PRI.Kills > 0) ? "1" : "");
	}

-------------------------------------------------------------------------------

3. Invasion:

3.1 About:

	Many of you already know about Invasion and Epic's decision to remove it
	from Unreal Tournament 3. This is just my own implementation of Invasion
	to fill that void.

	It's identical to the original with a few of my own improvements. You
	spawn starting with N configurable lives per wave and must kill all of the
	invading monsters each wave in order to advanced to the next one. Simple
	enough.

3.2 Features:

	Aside from the standard Invasion game play, here is the list of
	improvements:

	* All game menus and HUDs have been updated and work.
	* Support for Customized wave managers
		The default one provides a framework for wave sets described below,
		but you can optionally write your own. The wave manager simply needs
		to return a new wave on a call to GetNextWave. When it returns None
		the Invasion is over.
	* Supports Invasions of any number of waves.
	* Supports Invasion Sets.
		Sets are a set of wave configurations and each map chooses a random
		set. In this way you can have multiple that are randomly chosen each
		map allowing for much greater variety in gameplay.
		
		Sets can be configured to work on only certain maps or to exclude
		certain maps. Support for work/exclude maps designed for game types is
		underway.
	* Invasion will work on all map types. DM, CTF, VCTF, WAR.
		* Note: On maps with objectives, the objectives will just be disabled
		  and hidden from view.
		* Vehicles will be unlocked on all maps that have vehicles.
	* Support for configuring the monsters / Invasion team to use team spawns
	  on a per game or per wave level.
	* Support for Customized waves.
		Waves are not just monster waves. They are spawned InvasionWave
		instances of which you can create your own and specify them.
		
		Currently there are only two wave types for Invasion:
			* UTGamePlus.MonsterWave: Your standard monsters invading
			  wave.
			* UTGamePlus.IntermissionWave: A wave that provides a timeout
			  so players can gather powerups. You can specify the time
			  and a background song to play. (Just create a package with
			  the music and reference it from the IntermissionWave)
	* Monster Waves
		* Support a timelimited wave or monster kill limited wave.
		* Each wave can have their own name displayed in the scoreboard.
		* Can configure the bot damage ratio, scaling it down to make it
		  easier for players.
		* Can specify the maximum number of bots in play to be a fixed number
		  or relative to the number of Invasion team players.
		* Can override any monster wave setting using a wave properties list.
		  So you can create one wave, and override a few settings without
		  having to copy the entire configuration.
	* Configurable monsters
		* Monsters can be configured with the property list in the ini,
		  allowing you to customize a single monster in different ways. This
		  may be things like specifying health, size, AI parameters, skins,
		  weapons, and what ever else the bot maker allowed to be configured
		  on the fly.
	* Enhanced Radar
		* Supports Zooming.
		* Rotate / Fixed Rotation.
		* Viewing a larger version of the map.
		* Always displays team locations.
		* Supports multiple MapRevealers. (Which generate the pings that show
		  enemy locations. Currently this isn't used but I hope to add Radar
		  station deployments and Radar attachments for vehicles.)

3.3. Configuration

	This section will help you understand all of the ini settings you can mess
	with in order to configure Invasion.

3.3.1. Global Settings
	These settings go under the [UTGamePlus.Invasion] section in UTInvasion.ini

	FallbackMonsterClass (string):
		A string naming a monster class to fall back to when a monster
		cannot be spawned due to an error.

	MaxLives (int):
		The number of lives each player receives per wave. After they die
		this many times, they're out until the next wave. At the end of
		each monster wave they will be respawned and the lives will be
		reset to this value.

	WaveManagerClassName (string):
		The name of the class to spawn that will generate the waves for
		the game. The default value is "UTGamePlus.InvasionWaveManager"
		but you're welcome to write your own.

	MonsterTeamColor (color):
		The team color for the monsters. Typically yellow. The default
		value is (B=0,G=255,R=255,A=255).

	InvasionTeamColor (color):
		The color for the players. The default is (B=0,G=255,R=0,A=255).
		This value affects all aspects of the HUD.

3.3.2. Wave Manager Configuration

	The default Invasion wave manager "UTGamePlus.InvasionWaveManager" is
	configured in the [UTGamePlus.InvasionWaveManager] section of
	UTInvasion.ini

	The wave manage only has a list of WaveSets. An example waveset is:
	
	WaveSets=(Name="TenWaveInvasion",Chance=10,ValidMaps="",InvalidMaps="")

	You can specify any number of wavesets here and the wave manager will
	use the chance value to randomly select one.

	Each wave set has the following properties:

	Name (string):
		This name is used to find the configuration information of the
		wave set in the ini file.

	Chance (int):
		The change that this wave will be choosen. A higher value means
		it will more likely be choosen relative to other wavesets.

	ValidMaps (string comma list):
		A list of maps that the wave set is valid for. For example,
		a value of "DM-DECK" would only allow the waveset to be played
		on DM-DECK.

	InvalidMaps (string comma list):
		A list of maps that the wave set cannot be played on. Using
		the previous example of "DM-DECK" this would mean that this
		waveset could be played on any map except DM-DECK.

	ValidMapTypes (string comma list):
		A list of map prefixes that the wave set is valid for. For example,
		if this were "DM,DG" then the wave set could only be played on
		Deathmatch and Duel Game maps.

	InvalidMapTypes (string comma list):
		A list of map prefixes that te wave set cannot be played on. For
		example, if this were "CTF,VCTF" then the wave set could not be
		played on a Capture the Flag or Vehicle Capture the Flag map.

	Properties (property list):
		List of properties to override for the wave set. See the wave set
		properties for a list of values that can be specified.

3.3.3. Wave Set Configuration

	A wave set is a list of waves that will be played. There can be any nubmer
	of waves in a wave set and they are specified as follows:

	Waves=(ClassName="UTGamePlus.MonsterWave",Properties="WaveConfiguration=TestBotWave?Title=The Beginning?MonsterRoster=BotMonsterRoster1")

	The properties of a Waves entry are:

	ClassName (string):
		The name of the class to spawn that is that wave. Currently
		the following classes exists.

		* UTGamePlus.MonsterWave
		* UTGamePlus.IntermissionWave

	Properties (property list):
		Properties are a property list that will be passed to the wave
		once it is spawned so that it can configure itself. More will be
		discussed of the actual properties you can play with later.

		Property list are simply a key value list using '=' to separate
		key value pairs and '?' to separate different key value pairs.

	Additionally, the following options can be specified for a wave set:

	UseTeamSpawns (boolean):
		If true, the monsters and players will use the team spawns when
		spawning.

	SwapTeamSpawns (boolean):
		If true and use team spawns is enabled, the team spawns will be
		swapped for the monsters and players.

	GiveMonstersUnclaimedObjectives (boolean):
		For objective games, this option will give ownership of all
		unclaimed objectives to the monsters. This allows them to spawn
		there by default.

3.3.4. Wave Configuration

	There are three types of waves you can configure. MonsterWave,
	IntermissionWave, MonsterBonusWave.

3.3.4.1. MonsterWave

	A monster wave is your simple Invasion type wave where monsters spawn and
	the player(s) need to kill them all or survive for a specified length of
	time in order to advance to the next wave.

	When you add a MonsterWave to a WaveSet, in the properties section you
	can specify the following properties:

	WaveConfiguration (string):
		This the name of an ini MonsterWaveConfiguration section to use
		as a base for all the settings. It allows you to specify any
		of these properties in it and then the property string will
		override specific values.

	Title (string):
		A name for the wave that will be displayed on the player scoreboards.

	MonsterRoster (string):
		The name of a monster roster ini section to use for selecting
		the monsters to spawn. See the monster roster configuration
		section for more information.

	TimeLimit (int):
		The length of the round in seconds. If this is 0 the round will
		have no time limit.

	OverTimeLimit (int):
		The amount of time to wait after a wave has ended before monsters
		will start to automatically kill themselves.

	MonsterCount (int):
		The maximum number of monsters to spawn. 0 will disable the limit
		and instead expect a time limit.

	MaxActiveMonsters (float):
		The maximum number of monsters to spawn into play at any given
		time. The way this value is interpretted is dependant on
		MaxRelativeToPlayers.

	MaxRelativeToPlayers (boolean):
		If true, MaxActiveMonsters is multiplied by the number of
		players on the Invasion team in order to determine the max.
		This way you can specify a ratio of 3 monsters to 1 player
		by setting MaxRelativeToPlayers to true and MaxActiveMonsters
		to 3.

	SpawnRate (float):
		The time to wait between spawning monsters.

	Difficulty (float):
		The monster difficulty. This value ranges from 0 to 7.

	MonsterDamageScale (float):
		A scale to apply to all damage dealt by monsters. For example, 0.5
		would make monsters only do 50% damage to players.

	UseTeamSpawns (boolean):
		For maps that have team spawns or objective location team spawns,
		this will cause the wave to respawn players in team areas only.
		This really only matters if players have more than 1 life.

	Lives (int):
		How many lives should each player receive at the beginning of the
		wave. If this is not specified or 0, the default for the game will
		be used.

	Those are all the properties. Now just to go back and provide more
	information on WaveConfiguration. If you specify WaveConfiguration
	to be for example "TestBotWave", then in the ini you can have the
	following:
	
	[TestBotWave MonsterWaveConfiguration]
	Title=Bot Test Wave
	MonsterRoster=BotMonsterRoster
	TimeLimit=300
	OverTimeLimit=60
	MonsterCount=10
	MaxRelativeToPlayers=True
	MaxActiveMonsters=2.5
	SpawnRate=0.8
	Difficulty=4.0
	MonsterDamageScale=0.5
	UseTeamSpawns=True
	Lives=3

	The monster wave would load all the settings from this ini section
	and then apply any properties you specified in the wave set entry
	over the default values retrieved from this ini block.

	This way you can do things like use the same configuration but
	specify a different MonsterRoster or Difficulty.

3.3.4.2. IntermissionWave

	This really was a dummy concept for testing different types of
	waves. My original test had this wave in there for 50 seconds playing
	"Offspring - Intermission" which was amusing. You can use it if you
	like to gives players a pause.

	The properties for IntermissionWave are:

	Duration (int):
		The time in seconds the wave lasts.

	Music (string):
		The string name of an SoundCue in an Unreal Package that will
		be played when the wave starts.

3.3.4.3. MonsterBonusWave

	This is another test of a custom wave. This wave is exactly like a monster
	wave except that if all the players die, the game does not end. This wave
	allows players to earn some extra points without having to worry about
	loosing.

	Additionally there are two special effects of this wave.

	* If a player dies in this wave, when they respawn after the wave is over
	  they will be given all their weapons back that they had when they died.

	* If a player lives, they are rewarded with full health, armor, and ammo
	  for all their weapons.

	You can make this wave as hard as you like without having to worry about
	ending the game for your players or taking away their weapons.

3.3.5. Monster Roster Configuration

	A monster roster is a set of monsters that can spawn during a wave that
	uses that roster. It is simply a collection of Monster entries that
	look like this:
	
	Monsters=(MonsterClass="UTGamePlus.BotMonster",Chance=10,Properties="Name=Beamer?Weapon=UTGame.UTWeap_LinkGun?Scale=0.5?Health=50")

	The properties of a monster are:

	MonsterClass (string):
		The class name to spawn for that monster.

	Chance (int):
		The chance that that monster will be selected to spawn.

	Properties (string property list):
		An extended set of properties that the monster class can use
		to configure itself.

	Different monster classes will support different extended properties.
	The base monster class will provide you with the following:

	Name (string):
		Name of the monster. Call it whatever you want.

	Health (int):
		The starting health for the monster.

	Scale (float):
		A size scale to apply to the monster.

	For the BotMonster class, the following are provided in addition
	to the monster class set of properties:

	Weapon (string):
		The name of a weapon to give the bot. This will be the only weapon
		the bot uses and he will have infinite ammo.

	Alertness (float):
		The AI alertness of the bot.

	Accuracy (float):
		The AI accuracy of the bot.

	Aggressiveness (float):
		The AI aggressiveness of the bot.

	StrafingAbility (float):
		The AI strafing ability of the bot.
	
	CombatStyle (float):
		The AI combat style of the bot.

	Tactics (float):
		The AI tactics of the bot.

	ReactionTime (float):
		The AI reaction time of the bot.

	Jumpiness (float):
		The AI jumpiness of the bot.

	DodgeToGoalPct (float):
		The AI dodge to goal percent of the bot.
	
	HearingThreshold (float):
		The AI hearing threshold of the bot.

	CanUseVehicles (boolean):
		Specifies if the bot is allowed to get into vehicles. This defaults to
		false. (It sucks to get blown up by a tank being driven by a dwarf.)

	CanPickupInventory (boolean):
		Determines whether or not the bot(s) can pick up and use inventory
		items. If this is true, the bot will be able to get and use other
		weapons. The default value is false.

3.4. User Commands

3.4.1 Hud

	The following command is available for the hud.

	hud [action] (HudElement)

	Action can be list, show, or hide. Hud element refers to the name of one
	of the hud elements.

	The first thing you'd do whenever you see new hud elements is to

	hud list

	This will print out what hud elements are on the screen. From this
	you can then use

	hud hide MonstersLeft
	hud hide Wave

	or similar to hide the specified element. Once hidden the element remains
	hidden and the setting is saved. To turn an element back on you must
	use

	hud show MonstersLeft
	hud show Wave

	A note about the HudElement field. This only needs to be the start of
	the name of the hud element, just enough to uniquely identify it. So
	if the hud element is MonstersLeftHudElement, I can use any of m, mo,
	mon, monst, and so on.

3.4.2 Radar

	The user has the following commands for affecting the Radar. These are
	accessed by hitting <tab> and entering the command.

	ToggleLargeMap:
		Zooms the map to the large size so the entire map can be seen.

	ToggleMapRotation:
		Switches between fixed and rotating map.

	ZoomIn:
		Zooms the map in by a factor of 2.

	ZoomOut:
		Zooms the map out by a factor of 2.

3.5. User Ini Settings

	The following settings are customizable by the user by created a
	UTGamePlus.ini file in their config folder and then adding the section
	
	[UTGamePlus.Radar]

	Center:
		Center of the map on the screen. Default is (X=0.9,Y=0.25).

	Size:
		Size of the map relative to the screen width. Default is 0.25.

	IconScale:
		Scale factor for map icons. Default is 1.0.

	LargeMapCenter:
		Center of the enlarged map. Default is (X=0.5, Y=0.5) 

	LargeMapSize:
		Size of the enlarged map. Default is 0.75. 

	LargeMapIconScale:
		Scale factor for map icons on the large map. Default is 15.0.

	Opacity:
		Opacity of the map. Default is 0.75.

	RotateMap:
		Toggles fixed vs rotating map. Default is true. 

	PlayRadarSound:
		True to play the ping noise. Default is true.

	Example Ini:

	[UTGamePlus.Radar]
	Center=(X=0.9,Y=0.25)
	Size=0.25
	IconScale=1.0
	LargeMapCenter=(X=0.5,Y=0.5)
	LargeMapSize=0.75
	LargeMapIconScale=15.0
	Opacity=0.75
	RotateMap=true
	PlayRadarSound=true

3.6. Development

	This section is for developers who want to further customize Invasion.

3.6.1. Invasion Game Mode

	The Invasion game mode for the most part just overrides many common game
	methods. It does however add the following which may be useful:

	AnyPlayersAlive
		Returns true if there are any players alive still.

	SpawnMonster(class<Monster> MonsterClass, NavigationPoint StartSpot)
		Spawn a monster of the specified class at the specified start location.

3.6.2. Wave Manager

	A wave manager is a class used to select the waves for the Invasion game.
	The built in wave manager uses a set of wave sets and randomly selects
	a valid one based on a chance value and the restrictions places on where
	the wave set can be played. You however can implement your own and set
	Invasion to use it in the Invasion game settings ini config section.

	Wave managers have two important functions:

	GetNextWave
		Returns the next wave to be played.

	InsertWave(InsertPosition pos, Wave newWave)
		This function takes the insertion position which can be either 
		IP_Immediate or IP_EndOfGame. Immediate insertions should be returned
		the next time GetNextWave is called. EndOfGame insertions should be
		returned after the wave manager has returned all of its waves to
		play. NewWave is simply the wave to insert.

		This method returns true if the wave was queued, false if it was
		not. Not all wave managers will support insertion so checking for
		false is useful.

3.6.3. Creating a Custom Wave

	The framework I created for Invasion is open for you to create your own
	custom waves.

	To start you need to extend InvasionWave. Now, each eave is a GameRules
	class and when a Wave starts it is automatically added to the set of
	game rules for the game. When the wave ends, the wave is removed from the
	game rules list.

	The additional methods on top of the game rules that InvasionWaves provide
	are:

	InitializeGameReplicationInfo
		Called when a wave starts, this allows the wave to alter some of the
		game information.

	InitializeWaveReplicationInfo
		This allows the wave to initialize its own wave replication info that
		will be tied into the GRI.

	StartWave
		Called when the wave is being started by the game engine.

	EndWave
		Called when the wave is over. This is the result of either
		CheckGameOver returning true, CheckWaveOver returning true, or a
		call to WaveComplete.

	RestartWave
		Called to restart the current wave.

	ClientStartWave
		This is a static function that is called on all of the clients when
		a wave starts.

	ClientEndWave
		This is a static function that is called on all of the clients when
		a wave ends.

	UpdateHudElements
		Used to update the hud elements for the current wave. This will remove
		elements that are no longer needed and add ones that the current wave
		requires.

	GetHudElements
		Used to retrieve a list of the hud elements a wave uses.

	AddHudElement
		Adds a hud element. This can be used to catch a hud element so that
		it can be further configured.

	RemoveHudElement
		Removes a hud element.

	GetWaveTime
		Returns the time the wave has been going.

	CheckGameOver
		Returns true if the game has ended. If this returns true then no other
		waves will be played.

	CheckWaveOver
		Check to see if the wave is over. If this returns true, WaveComplete
		will be called resulting in this wave being ended allowing the next
		wave to start.

	WaveComplete
		Triggers the game engine to end this wave and move onto the next one.

	AllowPlayerRestart(Controller Player)
		Returns true if the player is allowed to respawn.

	RestartPlayer(Controller C)
		Called when the controller C has been restarted.

	RefreshPlayer(Controller C)
		Called when the controller C was refreshed. This means that the
		owner of this controller did not need to be restarted, that is
		they did not die. This is a place where you can restock players
		who lived.

	Configure(PropertyList properties)
		Configures the wave using the settings from a property list.

	CountsTowardsWaveSpree
		If true, this wave will count towards the wave spree statistic.
		For non-combative waves you might want to just return false.

	GetWaveDifficulty
		Returns a wave difficulty from 0 to 7.

	GetWaveId
		Returns a string that identifies the wave. Typically this is a
		string like "Wave 1" but it could also be "Wave 1-2" or
		"BONUS WAVE!!!!".

	GetRoundGoal
		Returns a line that describes the goal of the wave.

3.6.4. Invasion Mutators

	Invasion mutators allow you to hook the Invasion game using the mutator
	framework. In this way you can add mutators that alter monters, affect
	players between rounds, trigger events between waves, insert new waves,
	and so on.

	The following additional methods are available to InvasionMutators:

	OnMatchStarted
		Called when the game begins.

	OnMatchEnded
		Called when the game ends.

	OnWaveStarted(Wave newWave)
		Called when a wave has started.

	OnWaveEnded(Wave oldWave)
		Called when a wave has ended.

	OnPlayerRestarted(Pawn Other)
		Called when a player wave restarted between waves.

	OnPlayerRefreshed(Pawn Other)
		Called when a player needed to be refreshed between waves.

	OnOvertime
		Called when the game enters overtime.

	ModifyMonster(Monster Other)
		Called when a monster is spawned.

3.6.6. Hud Elements

	Hud elements are just a specialized Actor for rendering new components to
	the hud. They support basic show and hide commands and the standard
	PostRenderFor.

-------------------------------------------------------------------------------

4. Mutators

	The mutators included in this package just came about from people
	requesting features for Invasion and instead of making them specific to
	Invasion, instead I implemented them as a set of mutators you can use with
	Invasion, or any other game mode for that matter.
	
	At some point I may pull these out into their own package, but for now they
	live as part of the UTGamePlus package.

4.1. Always Dualies

	Just like the title says, this mutator will spawn players with two
	enforcers, eliminating the need to pick up one from a corpse. There is
	no configuration available, just add and enjoy two enforcers.

4.2. Connection Logger

	Very basic connection logger that will write out logs for each map of
	player connects and disconnects along with the player ip, name, and
	if available the unique ID of that player.

	The logs are placed in the <UTGAME>\Logs folders.

4.3. Instagib Areana

	This is a variation of the Weapons Arena mutator. Instagib Arena will
	remove all weapon spawns and all ammo picksup. Each player will spawn and
	recieve only an Super Shock Rifle.

4.4. Map Specific Settings

	Map specific settings allows you to set up a heirarch of settings based on
	game modes and maps. In this way you can specify a set of settings to
	apply to only Deathmatch games but maybe not Invasion or vice-versus. You
	can also specify settings that will apply only to specific maps.

	This mutator works by searching the UTMapSettings.ini file for the
	following configuration sections in order:

	[<MapPrefix> MapSpecificSettings]
	[<MapName> MapSpecificSettings]
	[<GameName>.<MapPrefix> MapSpecificSettings]
	[<GameName>.<MapName> MapSpecificSettings]
	[<GameAbbreviation>.<MapPrefix> MapSpecificSettings]
	[<GameAbbreviation>.<MapName> MapSpecificSettings]

	So for example, if the game is Invasion and the map we're on it WAR-Torlan,
	the following sections would be searched for:

	[WAR MapSpecificSettings]
	[WAR-Torlan MapSpecificSettings]
	[Invasion.WAR MapSpecificSettings]
	[Invasion.WAR-Torlan MapSpecificSettings]
	[INV.WAR MapSpecificSettings]
	[INV.WAR-Torlan MapSpecificSettings]

	Now, in each of these sections you can place one of many configurable
	options that are common to the game modes. I won't describe the common
	settings listed, also more will be added in the future but for now here
	are the available options:

		* MaxLives (Integer)
		* GoalScore (Integer)
		* TimeLimit (Integer)
		* LateEntryLives (Integer)
		* BotRatio (Float)
		* GameDifficulty (Float)
		* EndTimeDelay (Float)
		* WarmupTime (Float)
		* bPlayersMustBeReady (Boolean)
		* bWaitForNetPlayers (Boolean)
		* bWarmupRound (Boolean)
		* bForceMidGameMenuAtStart (Boolean)
		* bForceRespawn (Boolean)

		* bAllowHoverboards
			If set true, the game will be made to support hoverboards.

		* bAllowTranslocators
			If set true, players will spawn with translocators.

		* Mutators
			When set to append, this mutator list will be added.

	The way these options are specified in one of the ini sections is as
	follows:
	
	Setting=(Value=<value>,Op=<Operation>)

		* Setting is the name of the value you want to set at that level.
		* Value is the actual value for that setting.
		* Operation is one of the following:
			OS_Ignore: Do not use this value.
			OS_Override: Override this value with the value specified.
			OS_Apped: Append this value. (This is only used by Mutators)

	So some example entries in an ini section might be:

	MaxLives=(Value=30,Op=OS_Override)
	Mutators=(Value="UTPMutator.DualiesAlways",Op=OS_Append)

	An example UTMapSettings.ini is:

	[Invasion.WAR MapSpecificSettings]
	bAllowHoverboards=(Value=true,Op=OS_Override)
	
	[Invasion.VCTF MapSpecificSettings]
	bAllowHoverboards=(Value=true,Op=OS_Override)
	
	[Invasion.DM MapSpecificSettings]
	bAllowTranslocators=(Value=true,Op=OS_Override)
	
	[Invasion.DG MapSpecificSettings]
	bAllowTranslocators=(Value=true,Op=OS_Override)
	
	[Invasion.CTF MapSpecificSettings]
	bAllowTranslocators=(Value=true,Op=OS_Override)

	This above ini enables hoverboards in Invasion games played on Warfare and
	Vehicle CTF maps, but for DeathMatch, Dual Game, and CTF maps players will
	get translocators instead.

4.5. Open Vehicles

	This mutator will simply unlock all the vehicles on a map allowing any team
	to use them.

4.6. Weapons Arena

	Weapons Arena allows you to specify the starting weapons each player has
	when they spawn and then specify what weapons are allowed in the field.

	To specify the list of starting weapons, create StartingWeapon entries
	under [UTGamePlus.UTPMutator_WeaponsArena] as follows:

	StartingWeapons=(WeaponClass="UTGame.UTWeap_ImpactHammer")

	You can have as many of these as you like.

	For the field, you need to specify a list of pickup weapons and a pickup
	aciton. The pickup weapons list what weapons are allowed to be picked up
	on the map and the pickup action specifies what to do with weapons on the
	map that are not allowed.

	Pickup weapon entries are just like StartingWeapon entries only they use
	PickupWeapons. An example is:

	PickupWeapons=(WeaponClass="UTGame.UTWeap_Linkgun")

	The PickupAction is an enum that can be one of the following values:
		* WPA_Remove: Remove all weapons that are not allowed.
		* WPA_SwapToRelevant: Replaces the weapon with one of the valid ones.
		* WPA_RemoveNonRelevant: Remove only the weapons that are not allowed.

	Example:

	PickupAction=WPA_SwapToRelevant

	And lastly you can specify InfiniteAmmo which will turn infinite ammo on
	for all players when set to true. In this way you can spawn people with
	any weapon and let them just fight it out without needing to ever find
	ammo.

	InfiniteAmmo=True

	An example full configuration section is:

	[UTGamePlus.UTPMutator_WeaponsArena]
	StartingWeapons=(WeaponClass="UTGame.UTWeap_ImpactHammer")
	PickupWeapons=(WeaponClass="UTGame.UTWeap_Linkgun")
	PickupWeapons=(WeaponClass="UTGame.UTWeap_ShockRifle")
	PickupAction=WPA_SwapToRelevant
	InfiniteAmmo=false

	With this, all players start with the impact hammer and they can pick up
	a link gun or shock rifle on the map. All other weapons on the map are
	replaced with either a link gun or a shock rifle.

4.7 Show Player IDs

	This mutator is really a demo of the ability to alter the scoreboards by
	using a mutator. This one simply adds the hash of the unique player IDs
	to the scoreboard below the player's name.
	
	You can use this as a base to write your own so you can add other
	information to the score board like kills and deaths.

-------------------------------------------------------------------------------

5. Installation:

	* To insall, copy the enclosed UTGame folder into the following location:
	
	Vista:
	
	C:\Users\<Your username>\Documents\My Games\Unreal Tournament 3\

	XP:
	
	C:\Documents and Settings\<Your username>\ My Documents\My Games\Unreal Tournament 3\

-------------------------------------------------------------------------------

6. Credits:

	This was mainly a solo project, but there are definitely people/groups
	worth noting for their contributions to the modding resources available.
	
	* Epic Games: For making the Unreal Tournament series of games and
	  releasing the tools necessary for modding them. Also for creating the
	  original Invasion which this is based off of.

	* Unrealwiki: Invaluable resource for figuring out why things don't work
	  the way you'd expected them too. Big thanks to all of the contributors
	  who keep that updated.

	* Antonio Cordero Balczar: For creating WOTgreal which has made writing
	  mods so much easier.

	* All the other modders: Because the best way to learn how to do something
	  is reading how someone else did it.

	* Goku, FlaK_MoNKeY, Mystrina, and everyone else from the Invasion 24/7
	  RPG server who helped with suggestions and testing.

	* Catalyst for giving me the code I need to be able to eventually get the
	  team colors set up correctly.

	* Tor6 for helping me test this on my test server and making offering some
	  good suggestions. (Don't ping unless monster in range, show map
	  directions on the radar.)	  

-------------------------------------------------------------------------------

7. Change Log:

I didn't start tracking this until I was well into the development of Invasion,
but here is the change log since I started tracking:

0.9.6 [January 11, 2008]
	* Fixed the bug where players got stuck in spectator.
	* Fixed a bug where the game would end twice.
	* Added the ability to show all targets on the radar by using the config
	  varaible ShowAllTargetsOnRadars. Note: This currently only works in
	  stand alone games. To make this work in network requires replicating a
	  lot more information about all pawns. It can be done but that will
	  be in another release.
	* Added the ability to turn off BotMonster's ability to shock combo.
	* Added new spectator config option, SpectateMode. This can be one of
	  SM_Anyone (any player on any team), SM_Locked (can't view anyone),
	  SM_TeamOnly (only players on your team).
	* Finished implementing the framework for adding scoreboard extensions.
	  There is documentation in this readme on how to use them as well as
	  an example mutator in the package, UTPMutator_ShowPlayerIds, that you
	  can view the code for to see an example.
	* Colorized the hud messages appropriately. This refers to say messages
	  and team messages.
	* Updated the enforcer, sniper's rifle, and instagib rifles to use the
	  correct team colors.
	* Changed the architecture of GameReplicationInfo. Added
	  WaveReplicationInfo so that waves can have their own information.
	* Added a new framework for waves to be able to add hud elements when
	  they are active.
		* This also comes with a new player console command they can use
		  to toggle hud elements they don't like. See the player commands
		  for more information.
	* For all waves, now display the wave number in the hud.
	* For monsters waves, now display the Monsters in the hud.

0.9.5 [January 5, 2008]
	* Removed all the "has left the game", "has entered the game" messages
	  for monsters.
	* Reverted a change I believe was responsible for players getting stuck in
	  spectator.

0.9.4 [January 4, 2008]
	* Added the ability to filter wavesets by map type. You can use the
	  ValidMapTypes and InvalidMapTypes fields to specify DM, CTF, VCTF, WAR, or
	  DG.
	* Fixed all the known bugs in the radar.
		* Various drawing issues.
		* Not pinging while in vehicles.
		* Replication issues.
		* Orientation issues.
		* Fixed map rotation not updating rotation for player when in a
		  vehicle.
	* Added compass directions to the radar.
	* Added the ability to override wave set settings in the wave manager
	  configuration.
	* Added SwapTeamsSpawns to wave set configurations. Simply swaps where
	  the monsters and the players spawn.
	* Added GiveMonstersUnclaimedObjectives to wave set configurations
	  allowing you to give the monsters the spawn locations at all unclaimed
	  objectives. In this way you can make them spawn all over a Warfare map
	  instead of just at red spawns.
	* Added UTPMutator_WeaponArena and UTPMutator_InstagibArena. The first
	  was just a base for the second so you get that one for free.
		* UTPMutator_WeaponArena
			* You can specify any number of weapons and specify what weapons
			  the player starts with with StartingWeapons and what weapons
			  they can pickup in the game with PickupWeapons.
			* You can specify for pickups to be Removed (WPA_Remove),
			  swapped to a relevant weapon (WPA_SwapToRelevant), or remove
			  only those that are not relevant (WPA_RemoveNonRelevant).
			* Additionally, you can specify if the players should have
			  unlimited ammo.
		* UPTMutator_InstagibArena
			* Just a weapon arena where everyone gets an instagib rifle.
			* Works with Invasion!
	* Added UTPMutator_MapSpecificSettings. This mutator allows you to
	  customize setting at various levels. By GameType, MapType, MapName,
	  GameType.MapType, GameType.MapName. This heirarchy allows you to
	  finely control what settings are applied to a specific game/map.
	  You can also use this to specify mutators that run in specific modes
	  or on specific maps.
	  
	  My motivation for this was so that I could enable hoverboards and
	  translocators on a map type specific basis. I just generalized the
	  concept to include more settings and I'll add more settings in the
	  future.
	* Added UTPMutator_ConnectionLogger. Simply logs who connects to your
	  server with some basic information about that user.

0.9.3
	* Fixed some divide by zero errors in the radar.
	* Fixed an ocassional access none from the radar because of VehicleDriven.
	* Changed the radar to only ping when an enemy is within range.
	* Fixed a bug where more monsters than should be spawned were spawned.
	* Fixed monster controllers being spawned on the clients. This screwed up a lot
	  of things as well as flooded the client logs. An aside to this is that monsters
	  now have the red team glow to them.
	* Added debugging code to help track down why monsters are attacking each other.
	* Added InvasionMutator and ScriptedGameMutator. These add the follow
	  hooks:
		* OnMatchStarted
		* OnMatchEnded
		* OnWaveStarted
		* OnWaveEnded
		* OnPlayerRestarted
		* OnPlayerRefreshed
		* ModifyMonster
		* OnOvertime
	* Added some new stats tracking for Invasion statistics. Currently not used
	  but I have plans for them in the future. The new stats are:
		* Scores per wave.
		* Longest run of combative waves without dying.
	* Added MonsterBonusWave.
		* This wave is just like a monster wave, only that if all the players
		  die the game does not end, it just moves on.
		* You can configure this just like a normal monster wave, possible
		  make it extremely difficult instead for a challenge.
		* Players who are alive at the end will be maxed out on health, armor,
		  and ammo.
		* Players who died will not have lost any of their weapons when they
		  died, but will not be rewarded.
	* Added the ability to set the lives players start with on a per wave basis.
	  Each wave the number of lives will be set to the specified value in the
	  wave properties. If no value is specified it will default to the game
	  setting MaxLives. (This is useful with Bonus waves to set them down to
	  1 life.)
	* Added death messages back in for Monsters.
	* Changed it so monsters will no longer taunt.

0.9.2
	* New radar.
	* New radar will display the map if the map has a mini map. 
	* New radar supports multiple radar pings. (In the future I hope to add
	  deployable radar post / alter the radar sweeps.) 
	* Radar supports map rotation or fixed map. 
	* Radar supports zoom in and out. 
	* Radar can be enlarged for an overall view of the map. 
	* New map console commands: 
		* ToggleLargeMap: switches between large map and small map. 
		* ToggleMapRotation: switches between a fixed map and a rotating map. 
		* ZoomIn: Zooms the map in by a power of 2. 
		* ZoomOut: Zooms the map out by a power of 2.
	* UTGamePlus.ini settings under [UTGamePlus.Radar]: 
		* Center: Center of the map on the screen. Ex: Center=(X=0.9,Y=0.2) 
		* Size: Size of the map relative to the screen width. Ex: Size=0.2 
		* IconScale: Scale factor for map icons. 
		* LargeMapCenter: Center of the enlarged map. Default is (X=0.5, Y=0.5) 
		* LargeMapSize: Size of the enlarged map. Default is 0.7. 
		* LargeMapIconScale: Scale factor for map icons on the large map. 
		* Opacity: Opacity of the map. 
		* RotateMap: Toggles fixed vs rotating map. Default is true. 
		* PlayRadarSound: True to play the ping noise.
	* Fixed time limits in game not working correctly. (Was off because of wave
	  count down.) 
	* Added Overtime announcement message.

0.9.1
	* Fixed support of maps designed for other game modes. This now means 100%
	  support with the ability to support spawning in team areas only,
	  including onslaught maps.

0.9 [December 28, 2007]
	* Radar colors fixed for monsters. 
	* Ping fixed in hud. 
	* Hopefully fixed the %TeamScore% text appearing between maps. 
	* Fixed a major bug that caused Invasion to crash on changing maps. 
	* No more first blood/killing spree/multi kill messages. 
	* Monsters are now set to freelance always. I have plans to improve this
	  when we have more monsters. 
	* Allied bots will also freelance instead of trying to defend objectives in
	  non-dm maps. 
	* Invasion works on all map types (DM, WAR, CTF, VCTF) 
	* Bots can be configured to use or not use vehicles. 
	* Vehicles are all unlocked. 
	* War objectives are all disabled so they don't cause bot/play issues. 
	* Revamped the configuration of monsters and waves. I'll need to go into
	  more information about this but essential for every monster you can
	  override settings individually. I need to make a base prop so you can
	  create common sets and reference them and most important explain all
	  of this so you can understand exactly what I did. :P It's powerful
	  though for configurations.
