Multiplayer Armory: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Text replacement - "Category:ArmA 2: Operation Arrowhead" to "Category:Arma 2: Operation Arrowhead")
m (Text replacement - "[[Image:" to "[[File:")
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The '''Multiplayer Armory''' (ARMEX) enables you to try out all weapons and every single vehicle model from Arma 2 in procedurally generated missions with up to eight friends online or over LAN!
{{TOC|side}}
[[File:ARMEX_TANK.jpg|250px]]
The '''Multiplayer Armory''' (ARMEX) enables you to try out all weapons and every single vehicle model from {{arma2}} in procedurally generated missions with up to eight friends online or over LAN!
The system allows it to be used on user-made worlds. See the configuration guide below.
* {{Link|http://forums.bistudio.com/showthread.php?p{{=}}1777081|Feedback thread}}


The system allows it to be used on user-made worlds by [[Multiplayer_Armory_configuration|configuring]] an ARMEX for these worlds.


This documentation covers the [[Multiplayer Armory]] ('''MPA'''), how to set it up generally and how to configure custom content to work with it.
A lot of the [[Armory_configuration|documentation]] regarding the original ''Armory'' is still relevant.


Feedback thread: http://forums.bistudio.com/showthread.php?p=1777081
{{Feature|informative|
* Whenever a code sample shows <syntaxhighlight lang="cpp" inline>// ...</syntaxhighlight>, this means a full config will likely have more content, but this is not shown in these samples because it is not relevant to the MPA.
* The initial release of the MPA does not integrate user-made items such as vehicles, because of low-level engine limitations in the multiplayer environment.
* The MPA was built using [[Object_Oriented_scripting_shell|a scripting framework]] which simulates many of the benefits of Object Oriented architectures.
}}


[[Category:Arma 2: Operation Arrowhead]]
 
== Configuration ==
 
<syntaxhighlight lang="cpp">
class CfgMPArmory
{
// List of all (meta-)challenges in the MPA
// Can be expanded by user-made add-ons
class Challenges
{
class SomeMetaChallenge
{
id = 0; // Unique challenge identifier (Scalar)
type = 1; // 0: normal, 1: meta (Scalar)
multiplayer = 1; // Is this meta-challenge applied to more than one player? 0: no [default] / 1: yes (Scalar)
occurAtARMEX = 2; // Can this challenge be triggered at ARMEX? 0: no [default] / 1: yes / 2: yes and only there (Scalar)
startAlways = 1; // Should it start always when the conditions are met? 0: no, randomly [default] / 1: yes (Scalar)
title = "Some Meta-challenge"; // Challenge title text (localized String)
icon = "path\somemetachallenge_icon_ca.paa"; // Meta-challenges use icons in (de)briefings (String)
script = "path\somemetachallenge.sqf"; // Path to the meta-challenge script (String)
points = 50; // Points received by the team and players (Scalar)
tidExclusions[] = { 2, 6, 7, 8, 9, 10, 11, 12 }; // For which [[Armory_configuration#Type_ID.27s|TIDs]] is this challenge excluded? (Array of Scalar)
runtimeConditions[] = { "isDriver", "isFlying" }; // What runtime conditions must the item satisfy (see original Armory documentation)? (Array of String)
chalidExclusions[] = { 3, 7, 8, 21, 22 }; // For which challenge IDs is this meta-challenge excluded? (Array of Scalar)
textLog = "Description ..."; // Text shown as description in the player log (localized String)
 
// All texts required for the task (Array of localized String)
textTask[] =
{
"Task ..."
};
 
// All texts required for the debriefing (Array of localized String)
textDebriefing[] =
{
"Debriefing ..."
};
};
 
class SomeChallenge
{
id = 1;
type = 0;
title = "Some Challenge";
image = "path\somechallenge_co.paa"; // Challenges use images in (de)briefings (String)
script = "path\somechallenge.sqf"; // Special script called as function to return a special respawn position as Array (String)
scriptRespawn = "path\somechallenge_Respawn.sqf"; // Special script called as function before the challenge starts (String)
// Used to e.g. override some default parameters with special values for this challenge
scriptInit = "path\somechallenge_Init.sqf";
respawnDelay = 30; // Delay before a player respawn in seconds (Scalar) [-1 disables respawn until the challenge ends]
tidExclusions[] = { 7, 8 };
configConditions[] = { "hasWeapon" }; // What config conditions must the items used in this challenge satisfy? (Array of String)
positionMode = 3; // Where to insert? 0: away from target [default] / 1: very close to target / 2: randomly around target / 3: near the target (Scalar)
positionOnRoad = 1; // Find target position on a road? 0: no [default] / 1: yes (Scalar)
useRoadRoute = 1; // Grow a road network route? 0: no [default] / 1: yes - grown to both ends / 2: yes - grown to one end (Scalar)
minimumNodes = 3; // Route must have at least this amount of nodes (Scalar)
teamMode = 1; // Team configuration for players. 0: all in one team [default] / 1: all alone (Scalar)
itemMode = 1; // Item mode. 0: all using own item [default] / 1: all using the same random item (Scalar)
points[] = { 150 }; // Amount of points per end state (Array of Scalar)
taskStates[] = { 1, 0 }; // Task state for each end state (Array of Scalar)
textLog = "Description ...";
textTask[] = { "Task ..." };
textDebriefing[] = { "Debriefing ..." };
 
// All markers to be created for this challenge
class Markers
{
class SomeMarker1
{
icon = 1; // Icon instead of an ellipse? 0: no / 1: yes (Scalar)
type = "mil_start"; // CfgMarkers type entry (String)
color = "ColorBlue"; // CfgMarkerColors color entry (String)
// Text shown with the marker (localized String)
Value "#title" means the challenge's title is used
text = "Some Marker";
Marker position (String)
// References an Array stored in a variable with this name in the challenge
// Value "#routeStart" means the challenge route start is used
// Value "#routeEnd" means the challenge route end is used
// Value "#routeNode" means this marker is created for every node in the challenge route
position = "positionInsertion";
};
class SomeMarker2
{
size = 100; // Uniform X and Y scale in meters (Scalar)
color = "ColorRed";
position = "positionInsertion";
};
};
};
};
 
// Defining generic MPA hints as well as hints specific to certain database tables
// [target table (-1: generic hint, 0: item set, 1: item type) (Scalar), primary key ID in the table (Scalar), hint (localized String)]
hints[] =
{
{ -1, -1, "Hint ..." }
};
};
</syntaxhighlight>
 
 
=== Worlds ===
 
We have introduced a new class ''ARMEX'' in class ''Armory'' of any world that is to be used with the MPA.
In it we define where the items are placed and how the special areas are set up. The easiest way to understand these definitions is to look at the ''Takistan'' configs.
 
{{Feature|informative|Entries ''safePositionAnchor'' and ''safePositionRadius'' described for the original Armory are important as well.}}
 
<syntaxhighlight lang="cpp">
class CfgWorlds
{
// ...
class SomeWorld
{
class Armory
{
class ARMEX
{
position[] = { 10, 10 }; // Centre point of the ARMEX on this world (Array of Scalar)
// Radius in meters of a circle with the above centre point (Scalar)
// This circle should encompass the entire ARMEX area
radius = 250;
 
// Defining all item-specific data per type
// Not defining items of a certain type means they will not be included at ARMEX
class Items
{
// Find the list of all item class names below
class Tracked
{
// List of XY-coordinates where the actual items can be positioned (Array of Array of Scalar)
// The amount of defined positions determines how many items of this type will be randomly included
positions[] =
{
{ 10, 10 },
{ 20, 20 }
};
 
// List of XY-coordinates where the information signs for these items can be positioned (Array of Array of Scalar)
// This list corresponds to the list of positions above (order and amount)
positionsInfo[] =
{
{ 11, 11 },
{ 21, 21 }
};
 
// List of azimuths in degrees the items will be oriented with (Array of Scalar)
// This list corresponds to the list of positions above (order and amount)
directions[] =
{
90,
90
};
 
// List of azimuths in degrees the item information signs will be oriented with (Array of Scalar)
// This list corresponds to the list of positions above (order and amount)
directionsInfo[] =
{
180,
180
};
 
// ...
};
 
// Special areas of ARMEX, such as the item displays, Mobility Ranges, Firing Ranges, etc.
class Areas
{
class SomeArea
{
displayName = "$STR_EP1_MPA_AREA_SOMEAREA"; // Name of the area (localized String)
position[] = { 10, 10 }; // XY-coordinates for this area (Array of Scalar)
positionInfo[] = { 11, 11 }; // XY-coordinates for an information kiosk [optional] (Array of Scalar)
direction = 0; // Azimuth in degrees for this area (Scalar)
directionInfo = 90; // Azimuth in degrees for the information kiosk [optional] (Scalar)
markerType = "n_armor"; // CfgMarkers type used to indicate this area (String)
markerColor = "ColorBlue"; // CfgMarkerColors used [ColorBlack is default] (String)
directionTexture = "direction_sign_area_somearea_ca"; // Texture used for direction signs pointing to this area (String)
compositionScript = "path\mpa_somearea1.sqf"; // Path to the DynO set script (String)
compositionPosition[] = { 10, 10 }; // Anchor position for the set (Array of Scalar)
};
};
 
// List of optional extra DynO sets, used to add ambient scenery
class AmbientObjects
{
// List of paths to DynO scripts (Array of String)
compositionScripts[] =
{
"path\mpa_ambient1.sqf"
};
 
// List of XY-coordinates as the anchor positions for the above sets (Array of Array)
// Mapped using azimuth 0
compositionAnchors[] =
{
{ 20, 20 }
};
};
};
 
// One or several pre-defined back-up routes used in challenges which require a route
// These are only used in case a random route could not be found
backUpRoutes[] =
{
{
{ 10, 10 },
{ 20, 20 },
{ 30, 30 },
{ 40, 40 }
}
};
};
};
};
</syntaxhighlight>
 
=== Supported Types ===
 
{{Columns|3|
* Tracked
* Wheeled
* Static
* Helicopters
* Airplanes
* Rifles
* Machineguns
* Sidearms
* Launchers
* Explosives
}}
 
 
=== Factions ===
 
It is possible to define hints randomly shown while using items from a particular faction.
 
<syntaxhighlight lang="cpp">
class CfgFactionClasses
{
// ...
class SomeFaction
{
// ...
// List of hints specific to this faction (Array of localized String)
hints[] =
{
"Some hint!"
};
};
};
</syntaxhighlight>
 
 
{{GameCategory|arma2oa}}

Latest revision as of 23:10, 20 November 2023

ARMEX TANK.jpg The Multiplayer Armory (ARMEX) enables you to try out all weapons and every single vehicle model from Arma 2 in procedurally generated missions with up to eight friends online or over LAN! The system allows it to be used on user-made worlds. See the configuration guide below.


This documentation covers the Multiplayer Armory (MPA), how to set it up generally and how to configure custom content to work with it. A lot of the documentation regarding the original Armory is still relevant.

  • Whenever a code sample shows // ..., this means a full config will likely have more content, but this is not shown in these samples because it is not relevant to the MPA.
  • The initial release of the MPA does not integrate user-made items such as vehicles, because of low-level engine limitations in the multiplayer environment.
  • The MPA was built using a scripting framework which simulates many of the benefits of Object Oriented architectures.


Configuration

class CfgMPArmory
{
	// List of all (meta-)challenges in the MPA
	// Can be expanded by user-made add-ons
	class Challenges
	{
		class SomeMetaChallenge
		{
			id = 0;				// Unique challenge identifier (Scalar)
			type = 1;			// 0: normal, 1: meta (Scalar)
			multiplayer = 1;	// Is this meta-challenge applied to more than one player? 0: no [default] / 1: yes (Scalar)
			occurAtARMEX = 2;	// Can this challenge be triggered at ARMEX? 0: no [default] / 1: yes / 2: yes and only there (Scalar)
			startAlways = 1;	// Should it start always when the conditions are met? 0: no, randomly [default] / 1: yes (Scalar)
			title = "Some Meta-challenge";						// Challenge title text (localized String)
			icon = "path\somemetachallenge_icon_ca.paa";		// Meta-challenges use icons in (de)briefings (String)
			script = "path\somemetachallenge.sqf";				// Path to the meta-challenge script (String)
			points = 50;										// Points received by the team and players (Scalar)
			tidExclusions[] = { 2, 6, 7, 8, 9, 10, 11, 12 };	// For which [[Armory_configuration#Type_ID.27s|TIDs]] is this challenge excluded? (Array of Scalar)
			runtimeConditions[] = { "isDriver", "isFlying" };	// What runtime conditions must the item satisfy (see original Armory documentation)? (Array of String)
			chalidExclusions[] = { 3, 7, 8, 21, 22 };			// For which challenge IDs is this meta-challenge excluded? (Array of Scalar)
			textLog = "Description ...";						// Text shown as description in the player log (localized String)

			// All texts required for the task (Array of localized String)
			textTask[] =
			{
				"Task ..."
			};

			// All texts required for the debriefing (Array of localized String)
			textDebriefing[] =
			{
				"Debriefing ..."
			};
		};

		class SomeChallenge
		{
			id = 1;
			type = 0;
			title = "Some Challenge";
			image = "path\somechallenge_co.paa";				// Challenges use images in (de)briefings (String)
			script = "path\somechallenge.sqf";					// Special script called as function to return a special respawn position as Array (String)
			scriptRespawn = "path\somechallenge_Respawn.sqf";	// Special script called as function before the challenge starts (String)
																// Used to e.g. override some default parameters with special values for this challenge
			scriptInit = "path\somechallenge_Init.sqf";
			respawnDelay = 30;						// Delay before a player respawn in seconds (Scalar) [-1 disables respawn until the challenge ends]
			tidExclusions[] = { 7, 8 };
			configConditions[] = { "hasWeapon" };	// What config conditions must the items used in this challenge satisfy? (Array of String)
			positionMode = 3;						// Where to insert? 0: away from target [default] / 1: very close to target / 2: randomly around target / 3: near the target (Scalar)
			positionOnRoad = 1;						// Find target position on a road? 0: no [default] / 1: yes (Scalar)
			useRoadRoute = 1;						// Grow a road network route? 0: no [default] / 1: yes - grown to both ends / 2: yes - grown to one end (Scalar)
			minimumNodes = 3;						// Route must have at least this amount of nodes (Scalar)
			teamMode = 1;							// Team configuration for players. 0: all in one team [default] / 1: all alone (Scalar)
			itemMode = 1;							// Item mode. 0: all using own item [default] / 1: all using the same random item (Scalar)
			points[] = { 150 };						// Amount of points per end state (Array of Scalar)
			taskStates[] = { 1, 0 };				// Task state for each end state (Array of Scalar)
			textLog = "Description ...";
			textTask[] = { "Task ..." };
			textDebriefing[] = { "Debriefing ..." };

			// All markers to be created for this challenge
			class Markers
			{
				class SomeMarker1
				{
					icon = 1;				// Icon instead of an ellipse? 0: no / 1: yes (Scalar)
					type = "mil_start";		// CfgMarkers type entry (String)
					color = "ColorBlue";	// CfgMarkerColors color entry (String)
					// Text shown with the marker (localized String)
					Value "#title" means the challenge's title is used
					text = "Some Marker";
					Marker position (String)
					// References an Array stored in a variable with this name in the challenge
					// Value "#routeStart" means the challenge route start is used
					// Value "#routeEnd" means the challenge route end is used
					// Value "#routeNode" means this marker is created for every node in the challenge route
					position = "positionInsertion";
				};
				class SomeMarker2
				{
					size = 100; // Uniform X and Y scale in meters (Scalar)
					color = "ColorRed";
					position = "positionInsertion";
				};
			};
		};
	};

	// Defining generic MPA hints as well as hints specific to certain database tables
	// [target table (-1: generic hint, 0: item set, 1: item type) (Scalar), primary key ID in the table (Scalar), hint (localized String)]
	hints[] =
	{
		{ -1, -1, "Hint ..." }
	};
};


Worlds

We have introduced a new class ARMEX in class Armory of any world that is to be used with the MPA. In it we define where the items are placed and how the special areas are set up. The easiest way to understand these definitions is to look at the Takistan configs.

Entries safePositionAnchor and safePositionRadius described for the original Armory are important as well.
class CfgWorlds
{
	// ...
	class SomeWorld
	{
		class Armory
		{
			class ARMEX
			{
				position[] = { 10, 10 }; // Centre point of the ARMEX on this world (Array of Scalar)
				// Radius in meters of a circle with the above centre point (Scalar)
				// This circle should encompass the entire ARMEX area
				radius = 250;

				// Defining all item-specific data per type
				// Not defining items of a certain type means they will not be included at ARMEX
				class Items
				{
					// Find the list of all item class names below
					class Tracked
					{
					// List of XY-coordinates where the actual items can be positioned (Array of Array of Scalar)
					// The amount of defined positions determines how many items of this type will be randomly included
					positions[] =
					{
						{ 10, 10 },
						{ 20, 20 }
					};

					// List of XY-coordinates where the information signs for these items can be positioned (Array of Array of Scalar)
					// This list corresponds to the list of positions above (order and amount)
					positionsInfo[] =
					{
						{ 11, 11 },
						{ 21, 21 }
					};

					// List of azimuths in degrees the items will be oriented with (Array of Scalar)
					// This list corresponds to the list of positions above (order and amount)
					directions[] =
					{
						90,
						90
					};

					// List of azimuths in degrees the item information signs will be oriented with (Array of Scalar)
					// This list corresponds to the list of positions above (order and amount)
					directionsInfo[] =
					{
						180,
						180
					};

					// ...
				};

				// Special areas of ARMEX, such as the item displays, Mobility Ranges, Firing Ranges, etc.
				class Areas
				{
					class SomeArea
					{
						displayName = "$STR_EP1_MPA_AREA_SOMEAREA";	// Name of the area (localized String)
						position[] = { 10, 10 };					// XY-coordinates for this area (Array of Scalar)
						positionInfo[] = { 11, 11 };				// XY-coordinates for an information kiosk [optional] (Array of Scalar)
						direction = 0;								// Azimuth in degrees for this area (Scalar)
						directionInfo = 90;							// Azimuth in degrees for the information kiosk [optional] (Scalar)
						markerType = "n_armor";						// CfgMarkers type used to indicate this area (String)
						markerColor = "ColorBlue";					// CfgMarkerColors used [ColorBlack is default] (String)
						directionTexture = "direction_sign_area_somearea_ca";	// Texture used for direction signs pointing to this area (String)
						compositionScript = "path\mpa_somearea1.sqf";			// Path to the DynO set script (String)
						compositionPosition[] = { 10, 10 };			// Anchor position for the set (Array of Scalar)
					};
				};

				// List of optional extra DynO sets, used to add ambient scenery
				class AmbientObjects
				{
					// List of paths to DynO scripts (Array of String)
					compositionScripts[] =
					{
						"path\mpa_ambient1.sqf"
					};

					// List of XY-coordinates as the anchor positions for the above sets (Array of Array)
					// Mapped using azimuth 0
					compositionAnchors[] =
					{
						{ 20, 20 }
					};
				};
			};

			// One or several pre-defined back-up routes used in challenges which require a route
			// These are only used in case a random route could not be found
			backUpRoutes[] =
			{
				{
					{ 10, 10 },
					{ 20, 20 },
					{ 30, 30 },
					{ 40, 40 }
				}
			};
		};
	};
};

Supported Types

  • Tracked
  • Wheeled
  • Static
  • Helicopters
  • Airplanes
  • Rifles
  • Machineguns
  • Sidearms
  • Launchers
  • Explosives


Factions

It is possible to define hints randomly shown while using items from a particular faction.

class CfgFactionClasses
{
	// ...
	class SomeFaction
	{
		// ...
		// List of hints specific to this faction (Array of localized String)
		hints[] =
		{
			"Some hint!"
		};
	};
};