-
Notifications
You must be signed in to change notification settings - Fork 12
Developers World
The UncomplicatedCustomRoles APIs are easy to use, and with v4.0.0
they become even easier!
This is not to say that ease takes away from quality, in fact you will be able to customize your custom Custom Roles even more!
Our APIs are really logical to use and manage Custom Roles on multiple levels, so they are easy and intuitive. There are mainly two levels:
- When the Custom Role is registered and uploaded by UCR.
- When the Custom Role is applied to a player
UncomplicatedCustomRoles treats all roles that are registered as instances of a class that implements the ICustomRole
interface: this then allows API users to be able to create custom classes that implement the interface!
When a role is loaded its instance is single: it is saved in a Dictionary<TKey, TValue>
and thus can be retrieved-and modified-at any time: however, this modification is not applied instantaneously to players who have already obtained the role before the modification.
Tip
As how C# works, you can edit a role from the source dictionary, and statistics that are updated in real time (such as Hume Shield regeneration) will be automatically updated without the need to give the player the custom role again.
Instead, UCR handles a role differently when it is assigned to a player.
This is where the SummonedCustomRole
class comes in, which represents just such a swept player with a certain Custom Role.
This class also handles many aspects of the role, such as mechanics, Custom Modules, and event handling.
This class also saves the player's original information (such as any public tags, custom nicknames, and the like) so that these values are reassigned when the Custom Role is removed (either by the plugin then forcedly or by plugin events).
Each instance of SummonedCustomRole
(which thus fully represents a player with a Custom Role) is saved in a list in the static variable SummonedCustomRole.List
.
For faster management of players (and their related Custom Roles), UCR implements an extension that allows you to perform some quick actions by having the Player.
Function name | Args | Return | Description | Note |
---|---|---|---|---|
HasCustomRole |
bool |
Check if a Player is currently a ICustomRole
|
||
SetCustomRoleSync |
ICustomRole role |
void |
Set a ICustomRole to a Player without a coroutine |
Can cause small lag |
SetCustomRole |
ICustomRole role |
void |
Set a ICustomRole to a Player
|
|
SetCustomRoleAttributes |
ICustomRole role |
void |
Set a ICustomRole to a player, skipping the spawn-related thing(s) |
You shouldn't use it |
TryGetSummonedInstance |
out SummonedCustomRole role |
bool |
Try to gets the SummonedCustomRole instance for the given player: if false then the player is not a Custom Role |
|
GetSummonedInstance |
bool |
Gets the SummonedCustomRole instance for the given player: if null then the player is not a Custom Role |
||
TryRemoveCustomRole |
bool doResetRole = false |
bool |
Tries to remove the current Custom Role from a player. |
So for example if you want to spawn a Player:
player.SetCustomRole(myBeautifulCustomRole);
If you want to try to remove the Custom Role:
// You can do both from the extension or from the SummonedCustomRole
// SummonedCustomRole
if (player.TryGetSummonedInstance(out SummonedCustomRole role))
role.Destroy();
// Extension
player.TryRemoveCustomRole();
If you want to check if a player has a Custom Role
// You can use two methods
// If you don't need the Custom Role info
if (player.HasCustomRole())
Log.Info("Yeah");
// If you need Custom Role info
if (player.TryGetSummonedInstance(out SummonedCustomRole role))
// Your code...
Through your own plugin you can create your own Custom Roles and import them within UCR.
However, we must first distinguish the types of Custom Roles that you can manage with UCR.
-
ICustomRole
: the basic interface of a Custom Role: you will have to implement all members of the interface yourself -
CustomRole
: the UCR class that already implements theICustomRole
interface: every member isvirtual
so you can override them. -
EventCustomRole
: the UCR class that already implements theCustomRole
and also allow to handle every event by overriding them.
- Fully customizable implementation
- Fast and easy implementation
- Event implementation
Perfect for those who, in addition to already knowing C# well, want to customize the role in every way.
Example:
namespace UCRExample
{
internal class MyCustomRole : ICustomRole
{
public int Id { get; set; }
public string Name { get; set; }
public bool OverrideRoleName { get; set; }
public string Nickname { get; set; }
public string CustomInfo { get; set; }
public string BadgeName { get; set; }
public string BadgeColor { get; set; }
public RoleTypeId Role { get; set; }
public Team? Team { get; set; }
public RoleTypeId RoleAppearance { get; set; }
public List<Team> IsFriendOf { get; set; }
public HealthBehaviour Health { get; set; }
public AhpBehaviour Ahp { get; set; }
public List<Effect> Effects { get; set; }
public StaminaBehaviour Stamina { get; set; }
public int MaxScp330Candies { get; set; }
public bool CanEscape { get; set; }
public Dictionary<string, string> RoleAfterEscape { get; set; }
public Vector3 Scale { get; set; }
public string SpawnBroadcast { get; set; }
public ushort SpawnBroadcastDuration { get; set; }
public string SpawnHint { get; set; }
public float SpawnHintDuration { get; set; }
public Dictionary<ItemCategory, sbyte> CustomInventoryLimits { get; set; }
public List<ItemType> Inventory { get; set; }
public List<uint> CustomItemsInventory { get; set; }
public Dictionary<AmmoType, ushort> Ammo { get; set; }
public float DamageMultiplier { get; set; }
public SpawnBehaviour SpawnSettings { get; set; }
public CustomFlags? CustomFlags { get; set; }
public bool IgnoreSpawnSystem { get; set; }
}
}
Note
I have not set any values as they are unnecessary for the purpose of the wiki. However, it remains mandatory to definiri as there is no default fallback!
- Fully customizable implementation
- Fast and easy implementation
- Event implementation
Perfect if you want to create a Custom Role by changing only a few default values and leaving unnecessary ones as such.
Example:
namespace UCRExample
{
internal class AnotherCustomRole : CustomRole
{
public override int Id { get; set; } = 69;
public override string Name { get; set; } = "AnotherRole";
}
}
As you can see we have modified only the values that we wanted to edit, without the need to import the whole parameters as if not overrided here the default ones will be used!
- Fully customizable implementation
- Fast and easy implementation
- Event implementation
This can be seen more as an extension of
CustomRole
in that it implements it and also implements a built-in event system: in fact, with this class you can handle events directly from here and without even having to register them!
Important
The class event will obviously be invoked when the player with the custom role activates it. Example:
namespace UCRExample
{
internal class MyEventCustomRole : EventCustomRole, ICoroutineRole
{
public override int Id { get; set; } = 99;
public override void OnDroppedItem(DroppedItemEventArgs ev)
{
ev.Player.ShowHint("You just dropped an item!", 2.5f);
}
}
}
As you can see we are handling the DroppedItem
event by overriding the basic virtual method with our function!
It is possible to register a Custom Role in two different ways, depending on your needs:
- Via an Attribute to be assigned to the Custom Role class.
- Via a call to the
CustomRole.Register(ICustomRole)
static function.
Warning
Registering a Custom Role with both methods “just to be sure” although it may sound very clever is quite stupid: the role will be de facto loaded twice.
To automatically register a Custom Role without having to do anything outside of its class just use the PluginCustomRole
attribute to apply to the class.
Example:
namespace UCRExample
{
[PluginCustomRole]
internal class AnotherCustomRole : CustomRole
{
public override int Id { get; set; } = 69;
public override string Name { get; set; } = "AnotherRole";
}
}
In this way when every plugin will finish the loading this role will be registered inside UCR.
If, on the other hand, you prefer to load the role in the traditional way - or the plugin must be able to decide whether to load it or not - you can use the classic static function to register the CustomRole.
Example:
namespace UCRExample
{
internal class AnotherCustomRole : CustomRole
{
public override int Id { get; set; } = 69;
public override string Name { get; set; } = "AnotherRole";
}
}
// You can remove the first part if you do use UncomplicatedCustomRoles.API.Features - you should already know that btw
UncomplicatedCustomRoles.API.Features.CustomRole.Register(new AnotherCustomRole());
Through UCR, it is possible to already set up a role with a Coroutine
within it, that is, an action that repeats from when a Player becomes that role until it is removed from him.
In order to use this very cool feature you need to implement the ICoroutineRole
interface within your Custom Role.
Example:
namespace UCRExample
{
[PluginCustomRole]
internal class MyCoroutineCustomRole : CustomRole, ICoroutineRole
{
public override int Id { get; set; } = 56;
public CoroutineHandle CoroutineHandler { get; set; }
public float TickRate { get; set; } = 5f;
public long Frame { get; set; } = -1;
public void Tick(SummonedCustomRole roleInstance)
{
roleInstance.Player.ShowHint("UWU", 1f);
}
}
}
In this example, when the player receives this custom role it will display a hint containing “UWU” for 1 second: this is every 5 seconds.
-
float TickRate
: Every how many seconds should theTick()
function invoked -
float Frame
: Every iteration (Invoke ofTick()
)1
is added to this variable ( soFrame++
) -
CoroutineHandle CoroutineHandler
: the handler of the coroutine: in this way you can manage it by yourself!
Tip
ICoroutineRole
can be also used with EventCustomRole
!
Version v4.0.0 also brought Custom Modules.
These we can see as hard-coded “skills” in the plugin.
The official Custom Modules have a CustomFlag assigned to them by the system so that the plugin can infer which Custom Modules to load for a certain role.
Custom Modules can also be seen as “disks” that are inserted and removed at will from an instance or more of the SummonedCustomRoles
class: these disks contain additional functionality.
And just think, you too can create and insert these disks!
All Custom Modules must implement the abstract class CustomModule
in order to function.
That class has two constructors: one with no arguments and the other with a single argument: SummonedCustomRole
.
Depending on your requirements:
- Choose the empty constructor (you can also not define it) if the functionality you create does not require an instance of the
SummonedCustomRole
class with which it is associated - Choose the constructor with the class
SummonedCustomRole
if the functionality you create does not require an instance of the class with which it is associated Example:
namespace UCRExample
{
internal class AutoDoorBypassModule : CustomModule
{ }
}
namespace UCRExample
{
internal class PetModule : CustomModule
{
public PetModule(SummonedCustomRole role) : base(role)
{ }
}
}
Adding the Custom Module to the SummonedCustomRole instance you want is critical to enabling its functionality.
For this you can interface to the UncomplicatedCustomRoles.AddModule<T>()
of the class.
role.AddModule<PetModule>();
There are also functions dedicated to managing the Custom Module(s) present.
// Check if the instance has the PetModule
if (role.HasModule<PetModule>())
// Present!
// Try to get the instance of the module PetModule
if (role.Get(out PetModule module))
module.Execute();
// Get a list of modules with the same base
role.GetModules<ReallyNumerousModule>().Length; // omg 13!
// Get a single Custom Module
role.GetModule<PetModule>();
// Remove the module
role.RemoveModule<PetModule>();
UncomplicatedCustomRoles is a free plugin developed by FoxWorn3365 and DrAgenda.
Please consider Donatig 1$ if you found this plugin helpful