Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
73f4de2
Decals
MS-crew Jun 2, 2026
70c2e5b
Update EXILED/Exiled.API/Features/Map.cs
MS-crew Jun 3, 2026
ae154b2
consitent
MS-crew Jun 3, 2026
258abed
Merge branch 'DecalSpawn' of https://github.com/MS-crew/EXILEDPR into…
MS-crew Jun 3, 2026
7f35729
refactor: CustomScpTermination (#629)
XingYeNotFish Jun 4, 2026
c91697c
obsulutes
MS-crew Jun 4, 2026
d254366
Merge branch 'master' into DecalSpawn
MS-crew Jun 4, 2026
af2ec1a
directly usin rpcs
MS-crew Jun 4, 2026
a9d58b2
fix increment & helper methods
MS-crew Jun 5, 2026
9c075f2
Revert "fix increment & helper methods"
MS-crew Jun 5, 2026
eccf7d7
suggestion
louis1706 Jun 6, 2026
1dcd166
Merge pull request #1 from louis1706/suggestion
MS-crew Jun 6, 2026
e488ff9
update
MS-crew Jun 6, 2026
c768459
fix
MS-crew Jun 7, 2026
b74a19e
removing
MS-crew Jun 7, 2026
191f17f
movevininggg
MS-crew Jun 7, 2026
eb6bfbf
Indicator method
MS-crew Jun 7, 2026
92cf98c
Where did this come from?
MS-crew Jun 7, 2026
ec87764
sound & fake shoot
MS-crew Jun 7, 2026
12d5e24
update
MS-crew Jun 8, 2026
81ed9ea
Merge branch 'dev' into DecalSpawn
MS-crew Jun 8, 2026
cd07ff6
gix
MS-crew Jun 8, 2026
2b1c5ae
docs & wrong if check
MS-crew Jun 8, 2026
7e2bf46
cahced variables
MS-crew Jun 8, 2026
f316fec
renaming
MS-crew Jun 8, 2026
b5187e8
dellete
MS-crew Jun 8, 2026
e7342c2
i realized there is double, pump ,disruptor action modulle too so i r…
MS-crew Jun 8, 2026
f591c6e
f
MS-crew Jun 8, 2026
d3d1424
fuck it let be longht
MS-crew Jun 8, 2026
5f791fe
Valera was right its basic rpcs we dont need its
MS-crew Jun 9, 2026
1e4d70d
fix
MS-crew Jun 9, 2026
894b4af
enter
MS-crew Jun 9, 2026
9bfcf33
Merge branch 'dev' into pr/842
louis1706 Jul 16, 2026
c4c442c
Revert "dellete"
louis1706 Jul 16, 2026
36449a2
remove breaking change for merging into master
louis1706 Jul 16, 2026
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
16 changes: 16 additions & 0 deletions EXILED/Exiled.API/Features/Items/Firearm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Exiled.API.Features.Items
using System.Linq;

using CameraShaking;

using Enums;

using Exiled.API.Features.Items.FirearmModules;
Expand All @@ -20,12 +21,18 @@ namespace Exiled.API.Features.Items
using Exiled.API.Features.Pickups;
using Exiled.API.Interfaces;
using Exiled.API.Structs;

using Extensions;

using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Autosync;
using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Attachments.Components;
using InventorySystem.Items.Firearms.Modules;

using UnityEngine;

using static InventorySystem.Items.Firearms.Modules.AnimatorReloaderModuleBase;

using BaseFirearm = InventorySystem.Items.Firearms.Firearm;
Expand Down Expand Up @@ -75,6 +82,10 @@ public Firearm(BaseFirearm itemBase)
AnimatorReloaderModule = animatorReloaderModule;
break;

case ImpactEffectsModule impactEffectsModule:
ImpactEffectsModule = impactEffectsModule;
break;

default:
break;
}
Expand Down Expand Up @@ -151,6 +162,11 @@ public static IReadOnlyDictionary<Player, Dictionary<FirearmType, AttachmentIden
/// </summary>
public AnimatorReloaderModuleBase AnimatorReloaderModule { get; }

/// <summary>
/// Gets an impact effects module for the current firearm.
/// </summary>
public ImpactEffectsModule ImpactEffectsModule { get; }

/// <summary>
/// Gets or sets the amount of ammo in the firearm magazine.
/// </summary>
Expand Down
122 changes: 122 additions & 0 deletions EXILED/Exiled.API/Features/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,40 @@ namespace Exiled.API.Features
using System.Linq;

using CommandSystem.Commands.RemoteAdmin.Cleanup;

using Decals;

using Enums;

using Exiled.API.Extensions;
using Exiled.API.Features.Items.Keycards;
using Exiled.API.Features.Pickups;

using Interactables.Interobjects;

using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Autosync;
using InventorySystem.Items.Firearms.Modules;
using InventorySystem.Items.Pickups;
using InventorySystem.Items.ThrowableProjectiles;

using Items;

using LightContainmentZoneDecontamination;

using MapGeneration;

using Mirror;

using PlayerRoles.Ragdolls;

using RelativePositioning;

using RemoteAdmin;

using UnityEngine;

using Utils;
using Utils.Networking;

Expand Down Expand Up @@ -436,6 +454,110 @@ public static void CleanAllRagdolls(IEnumerable<Ragdoll> ragDolls)
[Obsolete("Use PlaceBlood(this Player, Vector3, Vector3, RoleTypeId, int) instead.")]
public static void PlaceBlood(Vector3 position, Vector3 direction) => _ = 0;

/// <summary>
/// Spawns a blood decal.
/// </summary>
/// <param name="position">The position of the blood decal.</param>
/// <param name="sourcePosition">The source position of the blood decal.</param>
/// <returns><see langword="true"/> if the blood decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public static bool SpawnBlood(Vector3 position, Vector3 sourcePosition) => SpawnDecal(position, sourcePosition, DecalPoolType.Blood, FirearmType.Com15);

/// <summary>
/// Spawns a blood decal for the specified players.
/// </summary>
/// <param name="players">The players for which to spawn the blood decal.</param>
/// <param name="position">The position of the blood decal.</param>
/// <param name="sourcePosition">The source position of the blood decal.</param>
/// <returns><see langword="true"/> if the blood decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public static bool SpawnBlood(IEnumerable<Player> players, Vector3 position, Vector3 sourcePosition) => SpawnDecal(players, position, sourcePosition, DecalPoolType.Blood, FirearmType.Com15);

/// <summary>
/// Spawns a decal.
/// </summary>
/// <param name="position">The position of the decal.</param>
/// <param name="sourcePosition">The source position of the decal.</param>
/// <param name="decalType">The <see cref="Decals.DecalPoolType"/>.</param>
/// <param name="firearmType">The <see cref="Enums.FirearmType"/> to use.</param>
/// <returns><see langword="true"/> if the decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public static bool SpawnDecal(Vector3 position, Vector3 sourcePosition, DecalPoolType decalType, FirearmType firearmType = FirearmType.Com15)
{
if (!InventoryItemLoader.TryGetItem(firearmType.GetItemType(), out ItemBase itemBase))
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

Firearm firearm = (Firearm)Item.Get(itemBase);
Comment thread
MS-crew marked this conversation as resolved.
Outdated
if (firearm == null)
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

ImpactEffectsModule impactEffectsModule = firearm.ImpactEffectsModule;
if (impactEffectsModule == null)
{
Log.Error($"Failed to spawn decal: Could not find an ImpactEffectsModule for {firearmType}.");
return false;
}

using (new AutosyncRpc(impactEffectsModule.ItemId, out NetworkWriter writer))
{
writer.WriteByte(impactEffectsModule.SyncId);
writer.WriteSubheader(ImpactEffectsModule.RpcType.ImpactDecal);
writer.WriteByte((byte)decalType);
writer.WriteRelativePosition(new RelativePosition(position));
writer.WriteRelativePosition(new RelativePosition(sourcePosition));
}

return true;
}

/// <summary>
/// Spawns a decal for the specified targets.
/// </summary>
/// <param name="targets">The targets for which to spawn the decal.</param>
/// <param name="position">The position of the decal.</param>
/// <param name="sourcePosition">The source position of the decal.</param>
/// <param name="decalType">The <see cref="Decals.DecalPoolType"/>.</param>
/// <param name="firearmType">The <see cref="Enums.FirearmType"/> to use.</param>
/// <returns><see langword="true"/> if the decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public static bool SpawnDecal(IEnumerable<Player> targets, Vector3 position, Vector3 sourcePosition, DecalPoolType decalType, FirearmType firearmType = FirearmType.Com15)
{
if (!InventoryItemLoader.TryGetItem(firearmType.GetItemType(), out ItemBase itemBase))
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

Firearm firearm = (Firearm)Item.Get(itemBase);
if (firearm == null)
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

ImpactEffectsModule impactEffectsModule = firearm.ImpactEffectsModule;
if (impactEffectsModule == null)
{
Log.Error($"Failed to spawn decal: Could not find an ImpactEffectsModule for {firearmType}.");
return false;
}

HashSet<ReferenceHub> targetHubs = targets.Select(p => p.ReferenceHub).ToHashSet();

using (new AutosyncRpc(impactEffectsModule.ItemId, hub => targetHubs.Contains(hub), out NetworkWriter writer))
{
writer.WriteByte(impactEffectsModule.SyncId);
writer.WriteSubheader(ImpactEffectsModule.RpcType.ImpactDecal);
writer.WriteByte((byte)decalType);
writer.WriteRelativePosition(new RelativePosition(position));
writer.WriteRelativePosition(new RelativePosition(sourcePosition));
}

return true;
}

/// <summary>
/// Gets all the near cameras.
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions EXILED/Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ namespace Exiled.API.Features
using System.Runtime.CompilerServices;

using Core;

using CustomPlayerEffects;
using CustomPlayerEffects.Danger;

using DamageHandlers;

using Decals;

using Enums;

using Exiled.API.Features.Core.Interfaces;
using Exiled.API.Features.CustomStats;
using Exiled.API.Features.Doors;
Expand All @@ -29,25 +35,36 @@ namespace Exiled.API.Features
using Exiled.API.Features.Roles;
using Exiled.API.Interfaces;
using Exiled.API.Structs;

using Extensions;

using Footprinting;

using global::Scp914;

using Hints;

using Interactables.Interobjects;

using InventorySystem;
using InventorySystem.Disarming;
using InventorySystem.Items;
using InventorySystem.Items.Armor;
using InventorySystem.Items.Autosync;
using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Modules;
using InventorySystem.Items.Firearms.ShotEvents;
using InventorySystem.Items.Usables;
using InventorySystem.Items.Usables.Scp330;

using MapGeneration.Distributors;
using MapGeneration.Rooms;

using MEC;

using Mirror;
using Mirror.LiteNetLib4Mirror;

using PlayerRoles;
using PlayerRoles.FirstPersonControl;
using PlayerRoles.FirstPersonControl.Thirdperson;
Expand All @@ -56,16 +73,22 @@ namespace Exiled.API.Features
using PlayerRoles.RoleAssign;
using PlayerRoles.Spectating;
using PlayerRoles.Voice;

using PlayerStatsSystem;

using RelativePositioning;

using RemoteAdmin;

using RoundRestarting;

using Unity.Collections.LowLevel.Unsafe;

using UnityEngine;

using Utils;
using Utils.Networking;

using VoiceChat;
using VoiceChat.Playbacks;

Expand Down Expand Up @@ -3845,6 +3868,56 @@ public void PlayGunSound(FirearmType itemType, float pitch = 1, int clipIndex =
[Obsolete("Use PlaceBlood(this Player, Vector3, Vector3, RoleTypeId, int) instead.")]
public void PlaceBlood(Vector3 direction) => Map.PlaceBlood(Position, direction);

/// <summary>
/// Spawns a blood decal for this player.
/// </summary>
/// <param name="position">The position of the blood decal.</param>
/// <param name="sourcePosition">The source position of the blood decal.</param>
/// <returns><see langword="true"/> if the blood decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public bool SpawnBlood(Vector3 position, Vector3 sourcePosition) => SpawnDecal(position, sourcePosition, DecalPoolType.Blood);

/// <summary>
/// Spawns a decal for this player.
/// </summary>
/// <param name="position">The position of the decal.</param>
/// <param name="sourcePosition">The source position of the decal.</param>
/// <param name="decalType">The <see cref="Decals.DecalPoolType"/>.</param>
/// <param name="firearmType">The <see cref="Enums.FirearmType"/> to use.</param>
/// <returns><see langword="true"/> if the decal was successfully spawned; otherwise, <see langword="false"/>.</returns>
public bool SpawnDecal(Vector3 position, Vector3 sourcePosition, DecalPoolType decalType, FirearmType firearmType = FirearmType.Com15)
{
if (!InventoryItemLoader.TryGetItem(firearmType.GetItemType(), out ItemBase itemBase))
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

Firearm firearm = (Firearm)Item.Get(itemBase);
if (firearm == null)
{
Log.Error($"Failed to spawn decal: Could not find a Firearm for {firearmType}.");
return false;
}

ImpactEffectsModule impactEffectsModule = firearm.ImpactEffectsModule;
if (impactEffectsModule == null)
{
Log.Error($"Failed to spawn decal: Could not find an ImpactEffectsModule for {firearmType}.");
return false;
}

using (new AutosyncRpc(impactEffectsModule.ItemId, ReferenceHub, out NetworkWriter writer))
{
writer.WriteByte(impactEffectsModule.SyncId);
writer.WriteSubheader(ImpactEffectsModule.RpcType.ImpactDecal);
writer.WriteByte((byte)decalType);
writer.WriteRelativePosition(new RelativePosition(position));
writer.WriteRelativePosition(new RelativePosition(sourcePosition));
}

return true;
}

/// <inheritdoc cref="Map.GetNearCameras(Vector3, float)"/>
public IEnumerable<Camera> GetNearCameras(float toleration = 15f) => Map.GetNearCameras(Position, toleration);

Expand Down
Loading