Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/fix[Exiled 9]: The honored one😭 #133

Open
wants to merge 32 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ad66a85
init
IRacle1 Sep 23, 2024
f5cc66f
Merge remote-tracking branch 'source/dev' into one
IRacle1 Sep 23, 2024
957350d
Merge branch 'dev' into one
IRacle1 Oct 11, 2024
0892ecd
🤯
IRacle1 Oct 11, 2024
4ea4b63
079 fix
IRacle1 Oct 11, 2024
6468b3c
`ValidatingVisibility`
IRacle1 Oct 11, 2024
b188280
`CopyProperties` fix
IRacle1 Sep 29, 2024
9364608
xd
IRacle1 Oct 12, 2024
8695c65
scp sl update🤯🤯🤯 fix
IRacle1 Oct 22, 2024
efbb0b4
another 018 fix
IRacle1 Oct 23, 2024
07391bb
better logic for consumables and `UseItem` reowo
IRacle1 Oct 23, 2024
eec582f
coms
IRacle1 Oct 23, 2024
78add72
docs fix
IRacle1 Oct 23, 2024
971d039
Merge branch 'dev' into one
IRacle1 Oct 27, 2024
e1bf463
Merge branch 'scpsl14' into one
IRacle1 Dec 4, 2024
2a6f170
Merge remote-tracking branch 'source/scpsl14' into one
IRacle1 Dec 4, 2024
18bb03e
fix
IRacle1 Dec 4, 2024
425ef63
that
IRacle1 Dec 4, 2024
31d1476
fixes
IRacle1 Dec 4, 2024
383ad63
Merge branch 'scpsl14' into one
IRacle1 Dec 8, 2024
9cce646
Merge branch 'scpsl14' into one
IRacle1 Dec 14, 2024
dd0d481
projectile thing
IRacle1 Dec 14, 2024
f937809
xd
IRacle1 Dec 14, 2024
0300220
[review:] all reviews by yamato
IRacle1 Dec 14, 2024
d3849f2
[build:] build error fix😥
IRacle1 Dec 14, 2024
efa9099
Merge branch 'scpsl14' into one
louis1706 Dec 26, 2024
48a1f85
Merge branch 'dev' into one
louis1706 Dec 26, 2024
7b1352a
Merge branch 'dev' into one
louis1706 Jan 9, 2025
d0b5175
Merge Dev branch into Pr/133
louis1706 Jan 19, 2025
1070e35
Merge branch 'one' of https://github.com/IRacle1/EXILED into pr/133
louis1706 Jan 19, 2025
dd90c10
Merge branch 'dev' into one
louis1706 Jan 19, 2025
8e62c07
Merge branch 'dev' into one
louis1706 Jan 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 11 additions & 58 deletions EXILED/Exiled.API/Extensions/MirrorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ namespace Exiled.API.Extensions
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

using Exiled.API.Enums;
using Exiled.API.Features.Roles;

using Features;
using Features.Pools;

Expand All @@ -24,7 +27,6 @@ namespace Exiled.API.Extensions
using PlayerRoles;
using PlayerRoles.FirstPersonControl;
using PlayerRoles.PlayableScps.Scp049.Zombies;
using PlayerRoles.PlayableScps.Scp1507;
using PlayerRoles.Voice;
using RelativePositioning;

Expand Down Expand Up @@ -229,9 +231,7 @@ public static void SetName(this Player target, Player player, string name)
/// </summary>
/// <param name="player">Player to change.</param>
/// <param name="type">Model type.</param>
/// <param name="skipJump">Whether to skip the little jump that works around an invisibility issue.</param>
/// <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 static void ChangeAppearance(this Player player, RoleTypeId type, bool skipJump = false, byte unitId = 0) => ChangeAppearance(player, type, Player.List.Where(x => x != player), skipJump, unitId);
public static void ChangeAppearance(this Player player, RoleTypeId type) => ChangeAppearance(player, type, Player.List.Where(x => x != player));

/// <summary>
/// Change <see cref="Player"/> character model for appearance.
Expand All @@ -240,70 +240,23 @@ public static void SetName(this Player target, Player player, string name)
/// <param name="player">Player to change.</param>
/// <param name="type">Model type.</param>
/// <param name="playersToAffect">The players who should see the changed appearance.</param>
/// <param name="skipJump">Whether to skip the little jump that works around an invisibility issue.</param>
/// <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 static void ChangeAppearance(this Player player, RoleTypeId type, IEnumerable<Player> playersToAffect, bool skipJump = false, byte unitId = 0)
public static void ChangeAppearance(this Player player, RoleTypeId type, IEnumerable<Player> playersToAffect)
{
if (!player.IsConnected || !RoleExtensions.TryGetRoleBase(type, out PlayerRoleBase roleBase))
if (!player.IsConnected)
return;

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

NetworkWriterPooled writer = NetworkWriterPool.Get();
writer.WriteUShort(38952);
writer.WriteUInt(player.NetId);
writer.WriteRoleType(type);

if (roleBase is HumanRole humanRole && humanRole.UsesUnitNames)
{
if (player.Role.Base is not HumanRole)
isRisky = true;
writer.WriteByte(unitId);
}

if (roleBase is ZombieRole)
{
if (player.Role.Base is not ZombieRole)
isRisky = true;

writer.WriteUShort((ushort)Mathf.Clamp(Mathf.CeilToInt(player.MaxHealth), ushort.MinValue, ushort.MaxValue));
writer.WriteBool(true);
}

if (roleBase is Scp1507Role)
if (!player.Role.CheckAppearanceCompatibility(type))
louis1706 marked this conversation as resolved.
Show resolved Hide resolved
{
if (player.Role.Base is not Scp1507Role)
isRisky = true;

writer.WriteByte((byte)player.Role.SpawnReason);
}

if (roleBase is FpcStandardRoleBase fpc)
{
if (player.Role.Base is not FpcStandardRoleBase playerfpc)
isRisky = true;
else
fpc = playerfpc;

ushort value = 0;
fpc?.FpcModule.MouseLook.GetSyncValues(0, out value, out ushort _);
writer.WriteRelativePosition(player.RelativePosition);
writer.WriteUShort(value);
Log.Error($"Prevent Seld-Desync of {player.Nickname} ({player.Role.Type}) with {type}");
return;
}

foreach (Player target in playersToAffect)
{
if (target != player || !isRisky)
target.Connection.Send(writer.ToArraySegment());
else
Log.Error($"Prevent Seld-Desync of {player.Nickname} with {type}");
player.Role.TrySetIndividualAppearance(target, type, false);
}

NetworkWriterPool.Return(writer);

// To counter a bug that makes the player invisible until they move after changing their appearance, we will teleport them upwards slightly to force a new position update for all clients.
if (!skipJump)
player.Position += Vector3.up * 0.25f;
player.Role.UpdateAppearance();
}

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion EXILED/Exiled.API/Extensions/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ public static void CopyProperties(this object target, object source)
throw new InvalidTypeException("Target and source type mismatch!");

foreach (PropertyInfo sourceProperty in type.GetProperties())
type.GetProperty(sourceProperty.Name)?.SetValue(target, sourceProperty.GetValue(source, null), null);
{
if (sourceProperty.SetMethod != null && sourceProperty.GetMethod != null)
sourceProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
}
}
}
}
31 changes: 30 additions & 1 deletion EXILED/Exiled.API/Extensions/RoleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ namespace Exiled.API.Extensions
using System.Linq;

using Enums;
using Features.Spawn;

using Exiled.API.Features;
using Exiled.API.Features.Roles;
using Exiled.API.Features.Spawn;
using Footprinting;
using InventorySystem;
using InventorySystem.Configs;
Expand Down Expand Up @@ -229,6 +232,32 @@ public static Dictionary<AmmoType, ushort> GetStartingAmmo(this RoleTypeId roleT
return info.Ammo.ToDictionary(kvp => kvp.Key.GetAmmoType(), kvp => kvp.Value);
}

/// <summary>
/// Gets a custom appearance for target <see cref="Player"/>, using <see cref="Role.GlobalAppearance"/>, <see cref="Role.TeamAppearances"/> and <see cref="Role.IndividualAppearances"/>.
/// </summary>
/// <param name="role">The player ><see cref="Role"/>, whose appearance we want to get.</param>
/// <param name="player">Target <see cref="Player"/>.</param>
/// <returns>A valid <see cref="RoleTypeId"/>, what target <see cref="Player"/> will see.</returns>
public static RoleTypeId GetAppearanceForPlayer(this Role role, Player player)
{
RoleTypeId appearance = role.GlobalAppearance;

if (player == null)
return appearance;

if (role.IndividualAppearances.TryGetValue(player, out appearance))
{
return appearance;
}

if (role.TeamAppearances.TryGetValue(player.Role.Team, out appearance))
{
return appearance;
}

return role.GlobalAppearance;
}

/// <summary>
/// Gets the <see cref="SpawnableFaction"/> of a <see cref="SpawnableWaveBase"/>.
/// </summary>
Expand Down
19 changes: 19 additions & 0 deletions EXILED/Exiled.API/Features/Items/Consumable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

namespace Exiled.API.Features.Items
{
using Exiled.API.Extensions;
using Exiled.API.Interfaces;
using InventorySystem.Items.Usables;

using BaseConsumable = InventorySystem.Items.Usables.Consumable;

Expand Down Expand Up @@ -40,6 +42,23 @@ internal Consumable(ItemType type)
/// </summary>
public new BaseConsumable Base { get; }

/// <inheritdoc/>
public override void Use(Player owner = null)
{
Player oldOwner = Owner;
owner ??= Owner;

if (owner is null)
throw new System.InvalidOperationException("The Owner of the item cannot be null.");

Base.Owner = owner.ReferenceHub;
Base.ActivateEffects();

typeof(UsableItemsController).InvokeStaticEvent(nameof(UsableItemsController.ServerOnUsingCompleted), new object[] { owner.ReferenceHub, Base });

Base.Owner = oldOwner.ReferenceHub;
}

/// <inheritdoc/>
internal override void ChangeOwner(Player oldOwner, Player newOwner)
{
Expand Down
86 changes: 24 additions & 62 deletions EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@ namespace Exiled.API.Features.Items
using Exiled.API.Features.Pickups;
using Exiled.API.Features.Pickups.Projectiles;

using InventorySystem.Items;
using InventorySystem.Items.Pickups;
using InventorySystem.Items.ThrowableProjectiles;
using UnityEngine;

using Object = UnityEngine.Object;

/// <summary>
/// A wrapper class for <see cref="ExplosionGrenade"/>.
/// </summary>
Expand All @@ -31,7 +27,6 @@ public class ExplosiveGrenade : Throwable
public ExplosiveGrenade(ThrowableItem itemBase)
: base(itemBase)
{
Projectile = (ExplosionGrenadeProjectile)((Throwable)this).Projectile;
}

/// <summary>
Expand All @@ -45,64 +40,30 @@ internal ExplosiveGrenade(ItemType type, Player player = null)
{
}

/// <summary>
/// Gets a <see cref="ExplosionGrenadeProjectile"/> to change grenade properties.
/// </summary>
public new ExplosionGrenadeProjectile Projectile { get; }

/// <summary>
/// Gets or sets the maximum radius of the grenade.
/// </summary>
public float MaxRadius
{
get => Projectile.MaxRadius;
set => Projectile.MaxRadius = value;
}
public float MaxRadius { get; set; }

/// <summary>
/// Gets or sets the multiplier for damage against <see cref="Side.Scp"/> players.
/// </summary>
public float ScpDamageMultiplier
{
get => Projectile.ScpDamageMultiplier;
set => Projectile.ScpDamageMultiplier = value;
}
public float ScpDamageMultiplier { get; set; }

/// <summary>
/// Gets or sets how long the <see cref="EffectType.Burned"/> effect will last.
/// </summary>
public float BurnDuration
{
get => Projectile.BurnDuration;
set => Projectile.BurnDuration = value;
}
public float BurnDuration { get; set; }

/// <summary>
/// Gets or sets how long the <see cref="EffectType.Deafened"/> effect will last.
/// </summary>
public float DeafenDuration
{
get => Projectile.DeafenDuration;
set => Projectile.DeafenDuration = value;
}
public float DeafenDuration { get; set; }

/// <summary>
/// Gets or sets how long the <see cref="EffectType.Concussed"/> effect will last.
/// </summary>
public float ConcussDuration
{
get => Projectile.ConcussDuration;
set => Projectile.ConcussDuration = value;
}

/// <summary>
/// Gets or sets how long the fuse will last.
/// </summary>
public float FuseTime
{
get => Projectile.FuseTime;
set => Projectile.FuseTime = value;
}
public float ConcussDuration { get; set; }

Comment on lines 43 to 67

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ? This change would be needed ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally didn't want to change the Projectile API structure, but still came to the conclusion that storing prefabs for throwables was a bad idea from the point of view of all cases😭
And removing it and writing all the properties and their relations correctly, is much more safer

/// <summary>
/// Spawns an active grenade on the map at the specified location.
Expand All @@ -115,28 +76,14 @@ public ExplosionGrenadeProjectile SpawnActive(Vector3 position, Player owner = n
#if DEBUG
Log.Debug($"Spawning active grenade: {FuseTime}");
#endif
ItemPickupBase ipb = Object.Instantiate(Projectile.Base, position, Quaternion.identity);

ipb.Info = new PickupSyncInfo(Type, Weight, ItemSerialGenerator.GenerateNext());

ExplosionGrenadeProjectile grenade = Pickup.Get<ExplosionGrenadeProjectile>(ipb);

grenade.Base.gameObject.SetActive(true);

grenade.MaxRadius = MaxRadius;
grenade.ScpDamageMultiplier = ScpDamageMultiplier;
grenade.BurnDuration = BurnDuration;
grenade.DeafenDuration = DeafenDuration;
grenade.ConcussDuration = ConcussDuration;
grenade.FuseTime = FuseTime;

grenade.PreviousOwner = owner ?? Server.Host;
ExplosionGrenadeProjectile projectile = CreateProjectile<ExplosionGrenadeProjectile>(position, Quaternion.identity);

grenade.Spawn();
projectile.PreviousOwner = owner;

grenade.Base.ServerActivate();
projectile.Activate();

return grenade;
return projectile;
}

/// <summary>
Expand Down Expand Up @@ -175,5 +122,20 @@ internal override void ReadPickupInfoBefore(Pickup pickup)
FuseTime = explosiveGrenadePickup.FuseTime;
}
}

/// <inheritdoc/>
protected override void InitializeProperties(ThrowableItem throwable)
{
base.InitializeProperties(throwable);

if (throwable.Projectile is ExplosionGrenade grenade)
{
MaxRadius = grenade._maxRadius;
ScpDamageMultiplier = grenade._scpDamageMultiplier;
BurnDuration = grenade._burnedDuration;
DeafenDuration = grenade._deafenedDuration;
ConcussDuration = grenade._concussedDuration;
}
}
}
}
Loading
Loading