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

Commit

Permalink
Merge branch 'dev' into moveobjects
Browse files Browse the repository at this point in the history
  • Loading branch information
xNexusACS authored Aug 20, 2024
2 parents 8727aa3 + 2a46783 commit 7b17ebf
Show file tree
Hide file tree
Showing 59 changed files with 667 additions and 495 deletions.
2 changes: 1 addition & 1 deletion EXILED.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

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

Expand Down
2 changes: 1 addition & 1 deletion Exiled.API/Extensions/MathExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static class MathExtensions
/// <param name="minInclusive">The minimum value to include in the range.</param>
/// <param name="maxInclusive">The maximum value to include in the range.</param>
/// <returns><see langword="true"/> if the probability occurred, otherwise <see langword="false"/>.</returns>
public static bool EvaluateProbability(this int probability, int minInclusive = 0, int maxInclusive = 100) => Random.Range(minInclusive, ++maxInclusive) <= probability;
public static bool EvaluateProbability(this int probability, int minInclusive = 0, int maxInclusive = 101) => probability == 100 || Random.Range(minInclusive, maxInclusive) <= probability;

/// <summary>
/// Evaluates a probability.
Expand Down
19 changes: 12 additions & 7 deletions Exiled.API/Features/Core/EActor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ protected EActor()
{
IsEditable = true;
fixedTickRate = DEFAULT_FIXED_TICK_RATE;
PostInitialize();
Timing.CallDelayed(fixedTickRate, OnBeginPlay);
Timing.CallDelayed(fixedTickRate * 2, () => serverTick = Timing.RunCoroutine(ServerTick()));
}

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

/// <inheritdoc/>
public bool HasComponent<T>(bool depthInheritance = false) => depthInheritance
? ComponentsInChildren.Any(comp => typeof(T).IsAssignableFrom(comp.GetType()))
? ComponentsInChildren.Any(comp => comp is T)
: ComponentsInChildren.Any(comp => typeof(T) == comp.GetType());

/// <inheritdoc/>
public bool HasComponent(Type type, bool depthInheritance = false) => depthInheritance
? ComponentsInChildren.Any(comp => type.IsAssignableFrom(comp.GetType()))
? ComponentsInChildren.Any(type.IsInstanceOfType)
: ComponentsInChildren.Any(comp => type == comp.GetType());

/// <summary>
/// Called when the <see cref="EActor"/> is initialized.
/// </summary>
public void ComponentInitialize()
{
PostInitialize();
Timing.CallDelayed(fixedTickRate, OnBeginPlay);
Timing.CallDelayed(fixedTickRate * 2, () => serverTick = Timing.RunCoroutine(ServerTick()));
}

/// <summary>
/// Fired after the <see cref="EActor"/> instance is created.
/// </summary>
Expand All @@ -474,7 +481,6 @@ protected virtual void PostInitialize()
/// </summary>
protected virtual void OnBeginPlay()
{
SubscribeEvents();
}

/// <summary>
Expand All @@ -485,7 +491,6 @@ protected virtual void Tick()
if (DestroyNextTick)
{
Destroy();
return;
}
}

Expand Down
73 changes: 69 additions & 4 deletions Exiled.API/Features/Core/EObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ protected EObject(GameObject gameObject = null)
/// <summary>
/// Gets or sets the name of the <see cref="EObject"/> instance.
/// </summary>
public string Name { get; set; }
public string Name { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the tag of the <see cref="EObject"/> instance.
/// </summary>
public string Tag { get; set; }
public string Tag { get; set; } = string.Empty;

/// <summary>
/// Gets or sets a value indicating whether the <see cref="EObject"/> values can be edited.
Expand Down Expand Up @@ -357,7 +357,13 @@ public static Type GetObjectTypeFromRegisteredTypes(Type type, string name)
public static EObject CreateDefaultSubobject(Type type, params object[] parameters)
{
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
EObject @object = Activator.CreateInstance(type, flags, null, parameters, null) as EObject;
EObject @object = Activator.CreateInstance(type, flags, null, null, null) as EObject;

if (@object is not null && Player.DEFAULT_ROLE_BEHAVIOUR is not null && type.BaseType == Player.DEFAULT_ROLE_BEHAVIOUR)
{
@object.Base = parameters[0] as GameObject;
@object.Cast<EActor>().ComponentInitialize();
}

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

/// <summary>
/// Initializes an instance of the specified generic type <typeparamref name="T"/>.
/// If no constructors are found, the base type is initialized.
/// </summary>
/// <typeparam name="T">The type that inherits from <see cref="EObject"/>.</typeparam>
/// <returns>An instance of the specified type <typeparamref name="T"/>.</returns>
public static T InitializeBaseType<T>()
where T : EObject
{
return InitializeBaseType(typeof(T)).Cast<T>();
}

/// <summary>
/// Initializes an instance of the specified type.
/// If no constructors are found, the base type is initialized.
/// </summary>
/// <param name="type">The type to be initialized.</param>
/// <param name="parameters">Constructor parameters for the type.</param>
/// <returns>An instance of the specified <see cref="EObject"/> type.</returns>
/// <exception cref="InvalidOperationException">
/// Thrown if the provided <paramref name="type"/> is not a subclass of <see cref="EObject"/>.
/// </exception>
public static EObject InitializeBaseType(Type type, params object[] parameters)
{
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
if (type.BaseType != typeof(EObject) && !type.IsSubclassOf(typeof(EObject)) && type != typeof(EObject))
throw new InvalidOperationException("The requested type is not a subclass of EObject.");

// Get the base type of T
Type baseType = type.BaseType;

if (baseType == null)
{
throw new InvalidOperationException("The requested type does not have a base type.");
}

// Get the constructors of the base type
ConstructorInfo[] constructors = baseType.GetConstructors(flags);

if (constructors.Length == 0)
{
throw new InvalidOperationException("The base type does not have public constructors.");
}

// Here we assume you want to use the default constructor if available
ConstructorInfo constructor = Array.Find(constructors, c => c.GetParameters().Length == 0);

if (constructor == null)
{
throw new InvalidOperationException("The base type does not have a parameterless constructor.");
}

// Create an instance of the base type
object baseInstance = constructor.Invoke(null);

// Return the instance as the requested type
return baseInstance as EObject;
}

/// <summary>
/// Creates a new instance of the <see cref="EObject"/> class.
/// </summary>
Expand Down Expand Up @@ -853,4 +918,4 @@ protected virtual void OnDestroyed()
{
}
}
}
}
8 changes: 7 additions & 1 deletion Exiled.API/Features/Core/Generic/EBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public abstract class EBehaviour<T> : EActor
/// Initializes a new instance of the <see cref="EBehaviour{T}"/> class.
/// </summary>
protected EBehaviour()
: base()
{
}

Expand Down Expand Up @@ -78,13 +77,20 @@ protected override void PostInitialize()
base.PostInitialize();

FindOwner();

if (!Owner && DisposeOnNullOwner)
{
Destroy();
return;
}
}

/// <inheritdoc />
protected override void OnBeginPlay()
{
base.OnBeginPlay();
}

/// <inheritdoc/>
protected override void Tick()
{
Expand Down
4 changes: 4 additions & 0 deletions Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic
using Exiled.API.Features.Core.Generic.Pools;
using Exiled.API.Interfaces;
using LiteNetLib.Utils;
using YamlDotNet.Serialization;

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

/// <summary>
/// Gets the value of the enum item.
/// </summary>
[YamlIgnore]
public TSource Value { get; }

/// <summary>
/// Gets the name determined from reflection.
/// </summary>
[YamlMember(Alias = "name")]
public string Name
{
get
Expand Down
3 changes: 3 additions & 0 deletions Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic
using Exiled.API.Features.Core.Generic.Pools;
using Exiled.API.Interfaces;
using LiteNetLib.Utils;
using YamlDotNet.Serialization;

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

/// <summary>
/// Gets the name determined from reflection.
/// </summary>
[YamlMember(Alias = "name")]
public string Name
{
get
Expand Down
4 changes: 3 additions & 1 deletion Exiled.API/Features/Core/StaticActor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ public static StaticActor CreateNewInstance<T>()
/// <returns>The created or already existing <see cref="StaticActor"/> instance.</returns>
public static StaticActor CreateNewInstance(Type type)
{
EObject @object = CreateDefaultSubobject<StaticActor>(type);
EActor @object = CreateDefaultSubobject<StaticActor>(type);
@object.Name = "__" + type.Name + " (StaticActor)";
@object.SearchForHostObjectIfNull = true;
@object.ComponentInitialize();
return @object.Cast<StaticActor>();
}

Expand Down Expand Up @@ -181,6 +182,7 @@ protected virtual void PostInitialize_Static()
/// </remarks>
protected virtual void BeginPlay_Static()
{
SubscribeEvents();
}

/// <summary>
Expand Down
16 changes: 11 additions & 5 deletions Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public class Player : GameEntity
public const string INFO_CATEGORY = "Player_Info";

#pragma warning disable SA1401
/// <summary>
/// The default role behaviour class.
/// </summary>
public static Type DEFAULT_ROLE_BEHAVIOUR = null;

/// <summary>
/// The default player class.
/// </summary>
Expand Down Expand Up @@ -664,10 +669,10 @@ public PlayerPermissions RemoteAdminPermissions
/// This role is automatically cached until it changes, and it is recommended to use this property directly rather than storing the property yourself.
/// </para>
/// <para>
/// 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)"/>.
/// 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)"/>.
/// </para>
/// </summary>
/// <seealso cref="Role.Set(RoleTypeId, SpawnReason, RoleSpawnFlags)"/>
/// <seealso cref="Role.Set(RoleTypeId, RoleChangeReason, RoleSpawnFlags)"/>
[EProperty(readOnly: true, category: ROLES_CATEGORY)]
public Role Role
{
Expand Down Expand Up @@ -3988,8 +3993,9 @@ public void PlayGunSound(Vector3 position, ItemType itemType, byte volume, byte
/// <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>
public void ChangeAppearance(RoleTypeId type, IEnumerable<Player> playersToAffect, bool skipJump = false, byte unitId = 0)
{
if (ReferenceHub.gameObject == null || !RoleExtensions.TryGetRoleBase(type, out PlayerRoleBase roleBase))
if (ReferenceHub.gameObject == null || !type.TryGetRoleBase(out PlayerRoleBase roleBase))
return;

bool isRisky = type.GetRoleBase().Team is Team.Dead || IsDead;

NetworkWriterPooled writer = NetworkWriterPool.Get();
Expand All @@ -4001,6 +4007,7 @@ public void ChangeAppearance(RoleTypeId type, IEnumerable<Player> playersToAffec
{
if (Role.Base is not PHumanRole)
isRisky = true;

writer.WriteByte(unitId);
}

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

ushort value = 0;
fpc?.FpcModule.MouseLook.GetSyncValues(0, out value, out ushort _);
fpc.FpcModule.MouseLook.GetSyncValues(0, out ushort value, out ushort _);
writer.WriteRelativePosition(RelativePosition);
writer.WriteUShort(value);
}
Expand Down
8 changes: 4 additions & 4 deletions Exiled.API/Features/Roles/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ public static RoleTypeId Random(bool includeNonPlayableRoles = false, IEnumerabl
/// Sets the player's <see cref="RoleTypeId"/>.
/// </summary>
/// <param name="newRole">The new <see cref="RoleTypeId"/> to be set.</param>
/// <param name="reason">The <see cref="Enums.SpawnReason"/> defining why the player's role was changed.</param>
public virtual void Set(RoleTypeId newRole, SpawnReason reason = null) => Set(newRole, reason ?? Enums.SpawnReason.ForceClass, RoleSpawnFlags.All);
/// <param name="reason">The <see cref="RoleChangeReason"/> defining why the player's role was changed.</param>
public virtual void Set(RoleTypeId newRole, RoleChangeReason reason = RoleChangeReason.RemoteAdmin) => Set(newRole, reason, RoleSpawnFlags.All);

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

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions Exiled.CustomModules/API/Commands/CustomItem/Give.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out s

if (arguments.Count == 0)
{
response = "give <Custom item name/Custom item ID> [Nickname/PlayerID/UserID/all/*]";
response = "give <Custom item ID> [Nickname/PlayerID/UserID/all/*]";
return false;
}

if (!CustomItem.TryGet(arguments.At(0), out CustomItem item))
if (!CustomItem.TryGet(arguments.At(0), out CustomItem item) && (!uint.TryParse(arguments.At(0), out uint id) || !CustomItem.TryGet(id, out item)) && item is null)
{
response = $"Custom item {arguments.At(0)} not found!";
return false;
Expand Down
Loading

0 comments on commit 7b17ebf

Please sign in to comment.