Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit 4bd815d

Browse files
Exiled 9.0.0-beta.1 (#2771)
2 parents 857cdd7 + 3a93db1 commit 4bd815d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+381
-280
lines changed

EXILED.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<PropertyGroup>
1717
<!-- This is the global version and is used for all projects that don't have a version -->
18-
<Version Condition="$(Version) == ''">9.0.0-alpha.19</Version>
18+
<Version Condition="$(Version) == ''">9.0.0-beta.1</Version>
1919
<!-- Enables public beta warning via the PUBLIC_BETA constant -->
2020
<PublicBeta>false</PublicBeta>
2121

Exiled.API/Features/Core/EActor.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ protected EActor()
4545
{
4646
IsEditable = true;
4747
fixedTickRate = DEFAULT_FIXED_TICK_RATE;
48-
PostInitialize();
49-
Timing.CallDelayed(fixedTickRate, OnBeginPlay);
50-
Timing.CallDelayed(fixedTickRate * 2, () => serverTick = Timing.RunCoroutine(ServerTick()));
5148
}
5249

5350
/// <summary>
@@ -454,14 +451,24 @@ public bool TryGetComponent(Type type, out EActor component)
454451

455452
/// <inheritdoc/>
456453
public bool HasComponent<T>(bool depthInheritance = false) => depthInheritance
457-
? ComponentsInChildren.Any(comp => typeof(T).IsAssignableFrom(comp.GetType()))
454+
? ComponentsInChildren.Any(comp => comp is T)
458455
: ComponentsInChildren.Any(comp => typeof(T) == comp.GetType());
459456

460457
/// <inheritdoc/>
461458
public bool HasComponent(Type type, bool depthInheritance = false) => depthInheritance
462-
? ComponentsInChildren.Any(comp => type.IsAssignableFrom(comp.GetType()))
459+
? ComponentsInChildren.Any(type.IsInstanceOfType)
463460
: ComponentsInChildren.Any(comp => type == comp.GetType());
464461

462+
/// <summary>
463+
/// Called when the <see cref="EActor"/> is initialized.
464+
/// </summary>
465+
public void ComponentInitialize()
466+
{
467+
PostInitialize();
468+
Timing.CallDelayed(fixedTickRate, OnBeginPlay);
469+
Timing.CallDelayed(fixedTickRate * 2, () => serverTick = Timing.RunCoroutine(ServerTick()));
470+
}
471+
465472
/// <summary>
466473
/// Fired after the <see cref="EActor"/> instance is created.
467474
/// </summary>
@@ -474,7 +481,6 @@ protected virtual void PostInitialize()
474481
/// </summary>
475482
protected virtual void OnBeginPlay()
476483
{
477-
SubscribeEvents();
478484
}
479485

480486
/// <summary>
@@ -485,7 +491,6 @@ protected virtual void Tick()
485491
if (DestroyNextTick)
486492
{
487493
Destroy();
488-
return;
489494
}
490495
}
491496

Exiled.API/Features/Core/EObject.cs

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ protected EObject(GameObject gameObject = null)
6262
/// <summary>
6363
/// Gets or sets the name of the <see cref="EObject"/> instance.
6464
/// </summary>
65-
public string Name { get; set; }
65+
public string Name { get; set; } = string.Empty;
6666

6767
/// <summary>
6868
/// Gets or sets the tag of the <see cref="EObject"/> instance.
6969
/// </summary>
70-
public string Tag { get; set; }
70+
public string Tag { get; set; } = string.Empty;
7171

7272
/// <summary>
7373
/// Gets or sets a value indicating whether the <see cref="EObject"/> values can be edited.
@@ -357,7 +357,13 @@ public static Type GetObjectTypeFromRegisteredTypes(Type type, string name)
357357
public static EObject CreateDefaultSubobject(Type type, params object[] parameters)
358358
{
359359
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
360-
EObject @object = Activator.CreateInstance(type, flags, null, parameters, null) as EObject;
360+
EObject @object = Activator.CreateInstance(type, flags, null, null, null) as EObject;
361+
362+
if (@object is not null && Player.DEFAULT_ROLE_BEHAVIOUR is not null && type.BaseType == Player.DEFAULT_ROLE_BEHAVIOUR)
363+
{
364+
@object.Base = parameters[0] as GameObject;
365+
@object.Cast<EActor>().ComponentInitialize();
366+
}
361367

362368
// Do not use implicit bool conversion as @object may be null
363369
if (@object != null)
@@ -371,6 +377,65 @@ public static EObject CreateDefaultSubobject(Type type, params object[] paramete
371377
throw new NullReferenceException($"Couldn't create an EObject instance of type {type.Name}.");
372378
}
373379

380+
/// <summary>
381+
/// Initializes an instance of the specified generic type <typeparamref name="T"/>.
382+
/// If no constructors are found, the base type is initialized.
383+
/// </summary>
384+
/// <typeparam name="T">The type that inherits from <see cref="EObject"/>.</typeparam>
385+
/// <returns>An instance of the specified type <typeparamref name="T"/>.</returns>
386+
public static T InitializeBaseType<T>()
387+
where T : EObject
388+
{
389+
return InitializeBaseType(typeof(T)).Cast<T>();
390+
}
391+
392+
/// <summary>
393+
/// Initializes an instance of the specified type.
394+
/// If no constructors are found, the base type is initialized.
395+
/// </summary>
396+
/// <param name="type">The type to be initialized.</param>
397+
/// <param name="parameters">Constructor parameters for the type.</param>
398+
/// <returns>An instance of the specified <see cref="EObject"/> type.</returns>
399+
/// <exception cref="InvalidOperationException">
400+
/// Thrown if the provided <paramref name="type"/> is not a subclass of <see cref="EObject"/>.
401+
/// </exception>
402+
public static EObject InitializeBaseType(Type type, params object[] parameters)
403+
{
404+
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
405+
if (type.BaseType != typeof(EObject) && !type.IsSubclassOf(typeof(EObject)) && type != typeof(EObject))
406+
throw new InvalidOperationException("The requested type is not a subclass of EObject.");
407+
408+
// Get the base type of T
409+
Type baseType = type.BaseType;
410+
411+
if (baseType == null)
412+
{
413+
throw new InvalidOperationException("The requested type does not have a base type.");
414+
}
415+
416+
// Get the constructors of the base type
417+
ConstructorInfo[] constructors = baseType.GetConstructors(flags);
418+
419+
if (constructors.Length == 0)
420+
{
421+
throw new InvalidOperationException("The base type does not have public constructors.");
422+
}
423+
424+
// Here we assume you want to use the default constructor if available
425+
ConstructorInfo constructor = Array.Find(constructors, c => c.GetParameters().Length == 0);
426+
427+
if (constructor == null)
428+
{
429+
throw new InvalidOperationException("The base type does not have a parameterless constructor.");
430+
}
431+
432+
// Create an instance of the base type
433+
object baseInstance = constructor.Invoke(null);
434+
435+
// Return the instance as the requested type
436+
return baseInstance as EObject;
437+
}
438+
374439
/// <summary>
375440
/// Creates a new instance of the <see cref="EObject"/> class.
376441
/// </summary>
@@ -853,4 +918,4 @@ protected virtual void OnDestroyed()
853918
{
854919
}
855920
}
856-
}
921+
}

Exiled.API/Features/Core/Generic/EBehaviour.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public abstract class EBehaviour<T> : EActor
2929
/// Initializes a new instance of the <see cref="EBehaviour{T}"/> class.
3030
/// </summary>
3131
protected EBehaviour()
32-
: base()
3332
{
3433
}
3534

@@ -78,13 +77,20 @@ protected override void PostInitialize()
7877
base.PostInitialize();
7978

8079
FindOwner();
80+
8181
if (!Owner && DisposeOnNullOwner)
8282
{
8383
Destroy();
8484
return;
8585
}
8686
}
8787

88+
/// <inheritdoc />
89+
protected override void OnBeginPlay()
90+
{
91+
base.OnBeginPlay();
92+
}
93+
8894
/// <inheritdoc/>
8995
protected override void Tick()
9096
{

Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic
1515
using Exiled.API.Features.Core.Generic.Pools;
1616
using Exiled.API.Interfaces;
1717
using LiteNetLib.Utils;
18+
using YamlDotNet.Serialization;
1819

1920
/// <summary>
2021
/// A class which allows <see langword="unmanaged"/> data implicit conversions and ensures unique values.
@@ -60,16 +61,19 @@ public UniqueUnmanagedEnumClass()
6061
/// <summary>
6162
/// Gets all <typeparamref name="TObject"/> object instances.
6263
/// </summary>
64+
[YamlIgnore]
6365
public static IEnumerable<TObject> Values => values.Values;
6466

6567
/// <summary>
6668
/// Gets the value of the enum item.
6769
/// </summary>
70+
[YamlIgnore]
6871
public TSource Value { get; }
6972

7073
/// <summary>
7174
/// Gets the name determined from reflection.
7275
/// </summary>
76+
[YamlMember(Alias = "name")]
7377
public string Name
7478
{
7579
get

Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic
1515
using Exiled.API.Features.Core.Generic.Pools;
1616
using Exiled.API.Interfaces;
1717
using LiteNetLib.Utils;
18+
using YamlDotNet.Serialization;
1819

1920
/// <summary>
2021
/// A class which allows <see langword="unmanaged"/> data implicit conversions.
@@ -51,11 +52,13 @@ protected UnmanagedEnumClass(TSource value)
5152
/// <summary>
5253
/// Gets the value of the enum item.
5354
/// </summary>
55+
[YamlIgnore]
5456
public TSource Value { get; }
5557

5658
/// <summary>
5759
/// Gets the name determined from reflection.
5860
/// </summary>
61+
[YamlMember(Alias = "name")]
5962
public string Name
6063
{
6164
get

Exiled.API/Features/Player.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ public class Player : GameEntity
127127
public const string INFO_CATEGORY = "Player_Info";
128128

129129
#pragma warning disable SA1401
130+
/// <summary>
131+
/// The default role behaviour class.
132+
/// </summary>
133+
public static Type DEFAULT_ROLE_BEHAVIOUR = null;
134+
130135
/// <summary>
131136
/// The default player class.
132137
/// </summary>
@@ -664,10 +669,10 @@ public PlayerPermissions RemoteAdminPermissions
664669
/// This role is automatically cached until it changes, and it is recommended to use this property directly rather than storing the property yourself.
665670
/// </para>
666671
/// <para>
667-
/// Roles and RoleTypeIds can be compared directly. <c>Player.Role == RoleTypeId.Scp079</c> is valid and will return <see langword="true"/> if the player is SCP-079. To set the player's role, see <see cref="Role.Set(RoleTypeId, SpawnReason, RoleSpawnFlags)"/>.
672+
/// Roles and RoleTypeIds can be compared directly. <c>Player.Role == RoleTypeId.Scp079</c> is valid and will return <see langword="true"/> if the player is SCP-079. To set the player's role, see <see cref="Role.Set(RoleTypeId, RoleChangeReason, RoleSpawnFlags)"/>.
668673
/// </para>
669674
/// </summary>
670-
/// <seealso cref="Role.Set(RoleTypeId, SpawnReason, RoleSpawnFlags)"/>
675+
/// <seealso cref="Role.Set(RoleTypeId, RoleChangeReason, RoleSpawnFlags)"/>
671676
[EProperty(readOnly: true, category: ROLES_CATEGORY)]
672677
public Role Role
673678
{
@@ -3988,8 +3993,9 @@ public void PlayGunSound(Vector3 position, ItemType itemType, byte volume, byte
39883993
/// <param name="unitId">The UnitNameId to use for the player's new role, if the player's new role uses unit names. (is NTF).</param>
39893994
public void ChangeAppearance(RoleTypeId type, IEnumerable<Player> playersToAffect, bool skipJump = false, byte unitId = 0)
39903995
{
3991-
if (ReferenceHub.gameObject == null || !RoleExtensions.TryGetRoleBase(type, out PlayerRoleBase roleBase))
3996+
if (ReferenceHub.gameObject == null || !type.TryGetRoleBase(out PlayerRoleBase roleBase))
39923997
return;
3998+
39933999
bool isRisky = type.GetRoleBase().Team is Team.Dead || IsDead;
39944000

39954001
NetworkWriterPooled writer = NetworkWriterPool.Get();
@@ -4001,6 +4007,7 @@ public void ChangeAppearance(RoleTypeId type, IEnumerable<Player> playersToAffec
40014007
{
40024008
if (Role.Base is not PHumanRole)
40034009
isRisky = true;
4010+
40044011
writer.WriteByte(unitId);
40054012
}
40064013

@@ -4011,8 +4018,7 @@ public void ChangeAppearance(RoleTypeId type, IEnumerable<Player> playersToAffec
40114018
else
40124019
fpc = playerfpc;
40134020

4014-
ushort value = 0;
4015-
fpc?.FpcModule.MouseLook.GetSyncValues(0, out value, out ushort _);
4021+
fpc.FpcModule.MouseLook.GetSyncValues(0, out ushort value, out ushort _);
40164022
writer.WriteRelativePosition(RelativePosition);
40174023
writer.WriteUShort(value);
40184024
}

Exiled.API/Features/Roles/Role.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ public static RoleTypeId Random(bool includeNonPlayableRoles = false, IEnumerabl
261261
/// Sets the player's <see cref="RoleTypeId"/>.
262262
/// </summary>
263263
/// <param name="newRole">The new <see cref="RoleTypeId"/> to be set.</param>
264-
/// <param name="reason">The <see cref="Enums.SpawnReason"/> defining why the player's role was changed.</param>
265-
public virtual void Set(RoleTypeId newRole, SpawnReason reason = null) => Set(newRole, reason ?? Enums.SpawnReason.ForceClass, RoleSpawnFlags.All);
264+
/// <param name="reason">The <see cref="RoleChangeReason"/> defining why the player's role was changed.</param>
265+
public virtual void Set(RoleTypeId newRole, RoleChangeReason reason = RoleChangeReason.RemoteAdmin) => Set(newRole, reason, RoleSpawnFlags.All);
266266

267267
/// <summary>S
268268
/// Sets the player's <see cref="RoleTypeId"/>.
@@ -275,9 +275,9 @@ public static RoleTypeId Random(bool includeNonPlayableRoles = false, IEnumerabl
275275
/// Sets the player's <see cref="RoleTypeId"/>.
276276
/// </summary>
277277
/// <param name="newRole">The new <see cref="RoleTypeId"/> to be set.</param>
278-
/// <param name="reason">The <see cref="Enums.SpawnReason"/> defining why the player's role was changed.</param>
278+
/// <param name="reason">The <see cref="RoleChangeReason"/> defining why the player's role was changed.</param>
279279
/// <param name="spawnFlags">The <see cref="RoleSpawnFlags"/> defining player spawn logic.</param>
280-
public virtual void Set(RoleTypeId newRole, SpawnReason reason, RoleSpawnFlags spawnFlags) =>
280+
public virtual void Set(RoleTypeId newRole, RoleChangeReason reason, RoleSpawnFlags spawnFlags) =>
281281
Owner.RoleManager.ServerSetRole(newRole, reason, spawnFlags);
282282

283283
/// <summary>

Exiled.CustomModules/API/Commands/CustomRoles/Give.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out s
5858
return false;
5959
}
6060

61-
if (!CustomRole.TryGet(arguments.At(0), out CustomRole role) || role is null)
61+
if (!CustomRole.TryGet(uint.Parse(arguments.At(0)), out CustomRole role) || role is null)
6262
{
6363
response = $"Custom role {arguments.At(0)} not found!";
6464
return false;
6565
}
6666

67-
if (arguments.Count == 1)
67+
if (arguments.Count == 2)
6868
{
6969
Pawn player = Player.Get(arguments.At(1)).Cast<Pawn>();
7070

Exiled.CustomModules/API/Features/CustomAbilities/ISelectableAbility.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77

88
namespace Exiled.CustomModules.API.Features.CustomAbilities
99
{
10-
using Exiled.API.Features.Core;
11-
using Exiled.API.Features.Core.Interfaces;
12-
using Exiled.CustomModules.API.Features.PlayerAbilities;
13-
1410
/// <summary>
1511
/// Represents a marker interface for custom ability that can be selected.
1612
/// </summary>

0 commit comments

Comments
 (0)