Skip to content
PotatoePet edited this page Feb 11, 2024 · 1 revision

The API is currently work-in-progress. Use it at your own risk as stuff might still change in a breaking way. Even tho I will try to prevent this it might be necessary at times. So keep looking for breaking changes in the API in upcoming versions.

Version Compability Checker

If your mod requires all clients to use your mod you can register your mod with AdvancedCompany so it checks on connect for the existence of those mods and only show lobbies to join with the same mods. AdvancedCompany will also show meaningful errors when joining isn't possible due to mod version mismatches.

To register your mod you have two ways:

AdvancedCompany.Lib.Mod.RegisterRequiredMod(BaseUnityPlugin)

You can supply a reference to your plugin in your Awake method like this:

void Awake()
{
    AdvancedCompany.Lib.Mod.RegisterRequiredMod(this);
}

Alternatively you can register your mod manually which might be benefical if you have multiple versions working together well (for example if your mod only uses some networking and you want the protocol version of your networking to be the same):

AdvancedCompany.Lib.Mod.RegisterRequiredMod(string, string)

First parameter is your mod name and second parameter is your mod version:

void Awake()
{
    AdvancedCompany.Lib.Mod.RegisterRequiredMod("MyMod", "1.0.0");
}

Post processing

To register your post processing effects you can use Unitys IPostProcessComponent and register your class with AdvancedCompany.

There are multiple ways to attach your post processing to the game currently. As of now AdvancedCompany creates multiple profiles for every setting (moon, state of player etc.) which requires to use a callback for you to apply your parameters correctly. It is planned to rework this in the near future to make it easier for modders.

To register your post processing component you can use AdvancedCompany.Lib.HDRP.AddPostProcessing<T>(InjectionPoint, PostProcessingFlags, string) where T : IPostProcessComponent

InjectionPoint and PostProcessingFlags are enums provided by the HDRP class:

public enum InjectionPoint
{
    AFTER_POSTPROCESS,
    AFTER_POSTPROCESS_BLURS,
    BEFORE_POSTPROCESS,
    BEFORE_TAA,
    BEFORE_TRANSPARENT
}
public enum PostProcessingFlags
{
    OUTSIDE = 1,
    INSIDE = 2,
    ORBIT = 4,
    UNDERWATER = 8,
    ALL = OUTSIDE | INSIDE | ORBIT | UNDERWATER
}

The last string parameter is the moon ID (The value of PlanetName of the moon). You can set this parameter to null to make your post processing apply to all moons.

A simple post processing effect which will be applied at all times would look like this:

var postProcessing = AdvancedCompany.Lib.HDRP.AddPostProcessing<MyPostProcessingComponent>(InjectionPoint.AFTER_POSTPROCESS, PostProcessingFlags.ALL, null);

AddPostProcessing returns a value of type PostProcessInstance.

With this object you can track the current instance of your post processing volume instantiated by Unity. To listen for changes of the active component used you can listen to the delegate OnInstanceChanged.

postProcessing.OnInstanceChanged += (old, @new) => {
    if (old is MyPostProcessingComponent oldComponent)
    {
    }
    if (@new is MyPostProcessingComponent newComponent)
    {
    }
}

You can access the currently active instance with the property CurrentInstance.

if (postProcessing.CurrentInstance != null)
    postProcessing.CurrentInstance.MyParameter.value = 1f;

Animation overrides

If multiple mods want to use simple animations its recommended to use an override animation controller. AdvancedCompany offers you the ability to override animations with simple calls and also synchronize those overrides to all clients.

In order to function properly you have to register your AnimationClips before you can use them. Load your AnimationClips from your AssetBundle and register them with AdvancedCompany.Lib.Player.AddAnimation(AnimationClip)

For all future uses you will reference your AnimationClip by its name.

If you want to set an animation override call: AdvancedCompany.Lib.Player.SetAnimationOverride(PlayerControllerB, string, string, bool)

First parameter is the player you want to set the animation override for. Second parameter is the original name of the AnimationClip you want to override. Third parameter is the name of the AnimationClip you want to replace the animation with. Fourth parameter is wether this override should be shared to all clients.

If you want to remove an animation override call: AdvancedCompany.Lib.Player.RemoveAnimationOverride(PlayerControllerB, string, bool)

First parameter is the player you want to set the animation override for. Second parameter is the original name of the AnimationClip you want to override. Third parameter is wether this override should be shared to all clients.

See this example:

var myAnimationClip = n.LoadAsset<AnimationClip>("Assets/MyAnimationClip"); // animation is named "MyAnimationClip"
AdvancedCompany.Lib.Player.AddAnimation(myAnimationClip);
AdvancedCompany.Lib.Player.SetAnimationOverride(global::StartOfRound.Instance.localPlayerController, "Idle", "MyAnimationClip", true);

Equipment

It might be necessary to make changes to or access the objects AdvancedCompany spawned for its equipment system. To do so you can call: AdvancedCompany.Lib.Equipment.GetSpawnedEquipment(GameNetcodeStuff.PlayerControllerB, Slot)

Here is a simple example:

var gameObjects = AdvancedCompany.Lib.Equipment.GetSpawnedEquipment(global::StartOfRound.Instance.localPlayerController, Slot.HEAD);
foreach (var gameObject in gameObjects)
{
    gameObject.SetActive(false);
}

Cosmetics

It might also be necessary to make changes to or access the objects AdvancedCompany spawned for the cosmetics system. To do so you can call: AdvancedCompany.Lib.Cosmetics.GetSpawnedCosmetics(GameNetcodeStuff.PlayerControllerB)

Here is a simple example:

var gameObjects = AdvancedCompany.Lib.Equipment.GetSpawnedCosmetics(global::StartOfRound.Instance.localPlayerController);
foreach (var gameObject in gameObjects)
{
    gameObject.SetActive(false);
}

You can also register your cosmetics by script with the Cosmetics API.

To do so you have 2 ways. Registering an AssetBundle or the GameObject itself. The GameObject has to have the AdvancedCompany.Cosmetics.CosmeticInstance component at its root. Alternatively AdvancedCompany is able to convert MoreCompany.Cosmetics.CosmeticInstance as well.

To register an AssetBundle use: AdvancedCompany.Lib.Cosmetics.LoadCosmeticsFromBundle(AssetBundle)

To reigster a prefab use: AdvancedCompany.Lib.Cosmetics.LoadCosmeticsFromPrefab(GameObject)

Custom flavour

AdvancedCompany supports setting the main menu logo via code as well. Logos replaced by code will always have a higher priority than a logo defined in the ModPack.cfg.

To set a logo simply call: AdvancedCompany.Lib.Flavour.SetLogo(Texture2D)

Network synchronization

Coming soon.