Encounter Rulesets
Mission Control allows other modders to add their own contract type rulesets to be used. When added to the mod, the mod will randomly select a ruleset for a contract type from the given choices.
Encounter Rulesets are what control the manipulation of a mission/contract. To manipulate encounters you create lots of Logic
objects and submit them to the EncounterLogic
system. Mission Control then intelligently runs these logic blocks at the correct point as the game runs.
Example Ruleset
Below is an example of the AssassinateEncounterRules
used in Mission Control. We'll run through each bit of code to explain what is happening.
using BattleTech;using MissionControl.Logic;namespace MissionControl.Rules {public class AssassinateEncounterRules : EncounterRules {public AssassinateEncounterRules() : base() { }public override void Build() {Main.Logger.Log("[AssassinateEncounterRules] Setting up rule object references");BuildRandomSpawns();BuildAdditionalLances("AssassinateSpawn", SpawnLogic.LookDirection.AWAY_FROM_TARGET,"SpawnerPlayerLance", SpawnLogic.LookDirection.AWAY_FROM_TARGET, 25f, 100f);}public void BuildRandomSpawns() {if (!MissionControl.Instance.IsRandomSpawnsAllowed()) return;Main.Logger.Log("[AssassinateEncounterRules] Building spawns rules");EncounterLogic.Add(new SpawnLanceAtEdgeOfBoundary(this, "SpawnerPlayerLance", "AssassinateSpawn"));EncounterLogic.Add(new SpawnLanceAnywhere(this, "AssassinateSpawn", "SpawnerPlayerLance", 400, true));EncounterLogic.Add(new LookAtTarget(this, "SpawnerPlayerLance", "AssassinateSpawn", true));}public override void LinkObjectReferences(string mapName) {ObjectLookup["AssassinateSpawn"] = EncounterLayerData.gameObject.FindRecursive("Lance_Enemy_AssassinationTarget");}}}
Example Walkthrough
Set up the right special superclass
public class AssassinateEncounterRules : EncounterRules {
To create a ruleset you must create a class and extend the EncounterRules
superclass. This provides lots of inbuilt functionality useful for encounters and allows Mission Control to use it.
Create a build step
public override void Build() {Main.Logger.Log("[AssassinateEncounterRules] Setting up rule object references");BuildSpawns();BuildAdditionalLances("AssassinateSpawn", SpawnLogic.LookDirection.AWAY_FROM_TARGET,"SpawnerPlayerLance", SpawnLogic.LookDirection.AWAY_FROM_TARGET, 25f, 100f);}
This is a special method which is required. It is called by Mission Control at the appropriate time to create the initial configuration. From here you can chain into your own methods for organisational purposes. I've used it to chain on Ai, Spawns and the special hook for Additional Lances
support for this contract type.
The EncounterRules
superclass gives you access to an easy way of enabling Additional Lances
for your encounter. Here is the method hook explained in more detail.
BuildAdditionalLances(TargetKeyToSpawnEnemyLancesAround, DirectionToLookAtInRelationToEnemyTarget, TargetKeyToSpawnAllyLancesAround,DirectionToLookAtInRelationToAllyTarget, MinDistanceForAlliesToSpawnFromAllyTarget, MaxistanceForAlliesToSpawnFromAllyTarget);
The target keys are bound at the bottom of the class with the LinkObjectReferences
method. This will be explained in a moment.
Specify Custom Logic
You can specify custom logic to be applied in a contract type. You can do this as follows:
public void BuildCustomLogic() { // any method name, then call it from the Build() methodEncounterLogic.Add(new MyCustomLogic());}
This method is for organisational purposes only. You can set up your custom logic in a method similar to this.
Two things are happening here. Firstly, you would have previously created a custom logic block which contains your logic. Secondly, you add this logic block relating to your custom logic to the EncounterLogic
property that is provided by the superclass EncounterRules
your class has access to. The EncounterLogic
list contains logic blocks of different type and that execute at different points in the game depending on their type. The main types are:
- RESOURCE_REQUEST
- CONTRACT_OVERRIDE_MANIPULATION
- ENCOUNTER_MANIPULATION
- SCENE_MANIPULATION
and these types are executed in that order depending on when the game requires them to be executed.
Build Spawns
public void BuildSpawns() {Main.Logger.Log("[AssassinateEncounterRules] Building spawns rules");EncounterLogic.Add(new SpawnLanceAtEdgeOfBoundary(this, "SpawnerPlayerLance", "AssassinateSpawn"));EncounterLogic.Add(new SpawnLanceAnywhere(this, "AssassinateSpawn", "SpawnerPlayerLance", 400, true));EncounterLogic.Add(new LookAtTarget(this, "SpawnerPlayerLance", "AssassinateSpawn", true));}
This method is for organisational purposes only. You can set up your spawn logic in a method similar to this.
Mission Control provides four spawn logic blocks to be used to move targets around the map. They are:
- SpawnLanceAnywhere
- SpawnLanceAroundTarget
- SpawnLanceMembersAroundTarget
- SpawnLanceAtEdgeBoundary
and there are two orientation logic blocks of:
- LookAtTarget
- LookAwayFromTarget
For each of these you provide different arguments but they all are very similar. You provide the target you wish to move around, the target you wish to be the orientation target (e.g to look at after being moved and to pathfind check to) and sometimes provide the look type (TOWARDS ORIENTATION TARGET, AWAY FROM ORIENTATION TARGET), minimum and maximum spawn distance constraints.
Link Object References
public override void LinkObjectReferences(string mapName) {ObjectLookup.Add("AssassinateSpawn", EncounterLayerData.gameObject.FindRecursive("Lance_Enemy_AssassinationTarget"));}
This is a very important method. Almost every logic block requires the use of keys to identify which item to move around the game map. This is how those keys are linked up to the game objects in the game scene / map. In this example, we assign the object found under the EncounterLayerData
object in the Unity game scene which has the name Lance_Enemy_AssassinationTarget
, which is a spawner object for the encounter, to the key AssassinateSpawn
.
You may notice there is no SpawnerPlayerLance
entry. This is because SpawnerPlayerLance
is a special key that is auto-linked for you already. It will always be available for you to use.
To discover the name and unity game scene location of the object to link I highly recommend you use the mod BTDebug with the latest releases found in the Releases area. It has a runtime inspector that allows you to view what objects are in the game scene / map so you can correctly link up what you need.
Send Your Custom Ruleset To Mission Control
You're able to provide your custom ruleset to Mission Control and it will use it. Mission Control randomly selects from all the available rulesets for a particular contract type.
To do this you must first create your own ruleset by linking your mod to MissionControl.dll
then creating it as explained above. Then, in your mod code execute code similar to the below example:
MissionControl.Instance.AddEncounter("Assassinate", typeof(MyCustomAssassinateRuleset)); // Add a custom assassinate ruleset
If for whatever reason you wish to only have your custom rulesets running you can clear all loaded rulesets with the following code:
MissionControl.Instance.ClearEncounters(); // Clears all encounters for all contract types
and
MissionControl.Instance.ClearEncounters("Assassinate"); // Clears all encounters for only the 'Assassinate' contract type
Summary
It's worth reviewing the code of this mod to see what already happens for the default encounter rulesets, especially looking at the EncounterRules.cs
class to see what the mod already provides for you to use (e.g. it contains properties that link to the encounter object in the Unity game scene you can use).