v1.2.2.b1
This commit is contained in:
parent
0fb3d63cd8
commit
46195c2663
147 changed files with 3470 additions and 2161 deletions
|
|
@ -80,6 +80,8 @@ namespace src.utils
|
|||
public bool KillerSkillChatInfo { get; set; }
|
||||
public bool TeamMateSkillChatInfo { get; set; }
|
||||
public bool SummaryAfterTheRound { get; set; }
|
||||
public bool EnableBotSkills { get; set; }
|
||||
public bool EnableBotKickDebug { get; set; }
|
||||
public bool DebugMode { get; set; }
|
||||
public string? AlternativeSkillButton { get; set; }
|
||||
public float SkillTimeBeforeStart { get; set; }
|
||||
|
|
@ -87,7 +89,7 @@ namespace src.utils
|
|||
public float SkillDescriptionDuration { get; set; }
|
||||
public bool DisplayAlwaysDescription { get; set; }
|
||||
public bool DisableSpectateHUD { get; set; }
|
||||
public bool FlashingHtmlHudFix { get; set; }
|
||||
public bool EnableFlashingHtmlHudFix { get; set; }
|
||||
public bool TraceRayBeam { get; set; }
|
||||
public string DisableHUDOnDeathPermission { get; set; }
|
||||
public bool DisableSkillsOnRoundEnd { get; set; }
|
||||
|
|
@ -105,13 +107,15 @@ namespace src.utils
|
|||
KillerSkillChatInfo = true;
|
||||
TeamMateSkillChatInfo = true;
|
||||
SummaryAfterTheRound = true;
|
||||
EnableBotSkills = true;
|
||||
EnableBotKickDebug = false;
|
||||
DebugMode = false;
|
||||
AlternativeSkillButton = null;
|
||||
SkillTimeBeforeStart = 7;
|
||||
SkillHudDuration = -1;
|
||||
SkillDescriptionDuration = 7;
|
||||
DisplayAlwaysDescription = false;
|
||||
FlashingHtmlHudFix = true;
|
||||
EnableFlashingHtmlHudFix = false;
|
||||
TraceRayBeam = false;
|
||||
DisableSpectateHUD = false;
|
||||
DisableHUDOnDeathPermission = "@jRandomSkills/death";
|
||||
|
|
|
|||
273
jRandomSkills - SRC Files/src/utils/EntityManager.cs
Normal file
273
jRandomSkills - SRC Files/src/utils/EntityManager.cs
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.utils
|
||||
{
|
||||
public static class EntityManager
|
||||
{
|
||||
public const uint SystemOwnerIndex = uint.MaxValue;
|
||||
private static readonly ConcurrentDictionary<uint, EntityData> trackedEntities = [];
|
||||
|
||||
private struct EntityData
|
||||
{
|
||||
public uint EntityIndex;
|
||||
public uint PlayerIndex;
|
||||
public string EntityType;
|
||||
public DateTime CreatedAt;
|
||||
}
|
||||
|
||||
public static void RegisterEntity(uint entityIndex, uint playerIndex, string entityType)
|
||||
{
|
||||
if (entityIndex == 0) return;
|
||||
|
||||
trackedEntities[entityIndex] = new EntityData
|
||||
{
|
||||
EntityIndex = entityIndex,
|
||||
PlayerIndex = playerIndex,
|
||||
EntityType = entityType,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
public static void RegisterExisting(CBaseEntity? entity, uint playerIndex, string entityType)
|
||||
{
|
||||
if (entity == null || !entity.IsValid) return;
|
||||
RegisterEntity(entity.Index, playerIndex, entityType);
|
||||
}
|
||||
|
||||
public static List<uint> GetPlayerEntities(uint playerIndex, string? entityType = null)
|
||||
{
|
||||
return [.. trackedEntities
|
||||
.Where(kvp => kvp.Value.PlayerIndex == playerIndex && (string.IsNullOrEmpty(entityType) || kvp.Value.EntityType == entityType))
|
||||
.Select(kvp => kvp.Key)];
|
||||
}
|
||||
|
||||
public static int GetTrackedCount(uint playerIndex) => GetPlayerEntities(playerIndex).Count;
|
||||
|
||||
public static (int totalTracked, int ownerCount) GetStatistics()
|
||||
{
|
||||
return (trackedEntities.Count, trackedEntities.Values.Select(e => e.PlayerIndex).Distinct().Count());
|
||||
}
|
||||
|
||||
|
||||
public static CParticleSystem? CreateTrackedParticleSystem(uint playerIndex, string particleName, float? autoDestroySeconds = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system");
|
||||
if (particle == null || !particle.IsValid) return null;
|
||||
|
||||
particle.EffectName = particleName;
|
||||
particle.StartActive = true;
|
||||
particle.DispatchSpawn();
|
||||
|
||||
RegisterEntity(particle.Index, playerIndex, "particle_system");
|
||||
ScheduleAutoDestroy(particle.Index, autoDestroySeconds);
|
||||
return particle;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedParticleSystem: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CDynamicProp? CreateTrackedDynamicProp(uint playerIndex, string designerName = "prop_dynamic")
|
||||
{
|
||||
try
|
||||
{
|
||||
var prop = Utilities.CreateEntityByName<CDynamicProp>(designerName);
|
||||
if (prop == null || !prop.IsValid) return null;
|
||||
|
||||
RegisterEntity(prop.Index, playerIndex, designerName);
|
||||
return prop;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedDynamicProp: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CDynamicProp? CreateTrackedPropOverride(uint playerIndex)
|
||||
{
|
||||
return CreateTrackedDynamicProp(playerIndex, "prop_dynamic_override");
|
||||
}
|
||||
|
||||
public static CEnvShake? CreateTrackedEnvShake(uint playerIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var shake = Utilities.CreateEntityByName<CEnvShake>("env_shake");
|
||||
if (shake == null || !shake.IsValid) return null;
|
||||
|
||||
shake.DispatchSpawn();
|
||||
RegisterEntity(shake.Index, playerIndex, "env_shake");
|
||||
return shake;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedEnvShake: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CChicken? CreateTrackedChicken(uint playerIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var chicken = Utilities.CreateEntityByName<CChicken>("chicken");
|
||||
if (chicken == null || !chicken.IsValid) return null;
|
||||
|
||||
chicken.DispatchSpawn();
|
||||
RegisterEntity(chicken.Index, playerIndex, "chicken");
|
||||
return chicken;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedChicken: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CPhysicsPropMultiplayer? CreateTrackedPhysicsProp(uint playerIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prop = Utilities.CreateEntityByName<CPhysicsPropMultiplayer>("prop_physics_multiplayer");
|
||||
if (prop == null || !prop.IsValid) return null;
|
||||
|
||||
RegisterEntity(prop.Index, playerIndex, "prop_physics_multiplayer");
|
||||
return prop;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedPhysicsProp: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CTriggerMultiple? CreateTrackedTrigger(uint playerIndex, string name, float radius, Vector pos)
|
||||
{
|
||||
if (pos == null) return null;
|
||||
|
||||
try
|
||||
{
|
||||
var trigger = Utilities.CreateEntityByName<CTriggerMultiple>("trigger_multiple");
|
||||
if (trigger == null || trigger.AbsOrigin == null) return null;
|
||||
|
||||
trigger.Collision.SolidType = SolidType_t.SOLID_CAPSULE;
|
||||
trigger.Collision.SolidFlags = 0;
|
||||
trigger.Spawnflags = 1;
|
||||
trigger.Globalname = $"{name}_{trigger.Index}";
|
||||
trigger.Collision.SolidFlags = 1;
|
||||
|
||||
trigger.AbsOrigin.X = pos.X;
|
||||
trigger.AbsOrigin.Y = pos.Y;
|
||||
trigger.AbsOrigin.Z = pos.Z;
|
||||
|
||||
trigger.Collision.CapsuleRadius = radius;
|
||||
trigger.Collision.BoundingRadius = radius;
|
||||
trigger.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_TRIGGER;
|
||||
trigger.Collision.EnablePhysics = 1;
|
||||
trigger.Collision.TriggerBloat = 0;
|
||||
trigger.Collision.SurroundType = SurroundingBoundsType_t.USE_OBB_COLLISION_BOUNDS;
|
||||
trigger.Collision.CollisionAttribute.CollisionFunctionMask = 39;
|
||||
trigger.Collision.CollisionAttribute.CollisionGroup = 2;
|
||||
|
||||
trigger.DispatchSpawn();
|
||||
RegisterEntity(trigger.Index, playerIndex, "trigger_multiple");
|
||||
return trigger;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedTrigger: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static CBeam? CreateTrackedBeam(uint playerIndex, Vector start, Vector end, Color color)
|
||||
{
|
||||
try
|
||||
{
|
||||
var beam = Utilities.CreateEntityByName<CBeam>("beam");
|
||||
if (beam == null || !beam.IsValid) return null;
|
||||
|
||||
beam.Render = color;
|
||||
beam.Width = 2.0f;
|
||||
beam.EndWidth = 2.0f;
|
||||
beam.Teleport(start);
|
||||
|
||||
beam.EndPos.X = end.X;
|
||||
beam.EndPos.Y = end.Y;
|
||||
beam.EndPos.Z = end.Z;
|
||||
|
||||
beam.DispatchSpawn();
|
||||
RegisterEntity(beam.Index, playerIndex, "beam");
|
||||
return beam;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] CreateTrackedBeam: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DestroyEntity(uint entityIndex)
|
||||
{
|
||||
trackedEntities.TryRemove(entityIndex, out _);
|
||||
|
||||
try
|
||||
{
|
||||
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
|
||||
if (entity != null && entity.IsValid)
|
||||
{
|
||||
entity.AddEntityIOEvent("Kill", entity, delay: 0.1f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[EntityManager] DestroyEntity {entityIndex}: {ex.Message}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool DestroyEntity<T>(uint? entityIndex) where T : CBaseEntity
|
||||
{
|
||||
if (entityIndex == null) return false;
|
||||
return DestroyEntity(entityIndex.Value);
|
||||
}
|
||||
|
||||
public static void DestroyPlayerEntities(uint playerIndex)
|
||||
{
|
||||
foreach (var entityIndex in GetPlayerEntities(playerIndex).ToList())
|
||||
DestroyEntity(entityIndex);
|
||||
}
|
||||
|
||||
public static void DestroyAllTracked()
|
||||
{
|
||||
foreach (var entityIndex in trackedEntities.Keys.ToList())
|
||||
DestroyEntity(entityIndex);
|
||||
|
||||
trackedEntities.Clear();
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
DestroyAllTracked();
|
||||
}
|
||||
|
||||
private static void ScheduleAutoDestroy(uint entityIndex, float? seconds)
|
||||
{
|
||||
if (seconds is not > 0) return;
|
||||
Instance?.AddTimer(seconds.Value, () => DestroyEntity(entityIndex), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ namespace src.utils
|
|||
|
||||
private static string GetLangCode(CCSPlayerController? player)
|
||||
{
|
||||
if (player == null || !player.IsValid) return defaultLangCode;
|
||||
if (player == null || !player.IsValid || player.IsBot) return defaultLangCode;
|
||||
|
||||
string? fileLangCode = GetLangCodeFromFile(player.SteamID);
|
||||
if (!string.IsNullOrEmpty(fileLangCode))
|
||||
|
|
|
|||
135
jRandomSkills - SRC Files/src/utils/PlayerManager.cs
Normal file
135
jRandomSkills - SRC Files/src/utils/PlayerManager.cs
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using System.Collections.Concurrent;
|
||||
using src.player;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
|
||||
namespace src.utils
|
||||
{
|
||||
public static class PlayerManager
|
||||
{
|
||||
private static readonly ConcurrentDictionary<uint, jSkill_PlayerInfo> playersByIndex = [];
|
||||
|
||||
public static void Register(jSkill_PlayerInfo playerInfo)
|
||||
{
|
||||
if (playerInfo == null) return;
|
||||
playersByIndex[playerInfo.PlayerIndex] = playerInfo;
|
||||
}
|
||||
|
||||
public static void UnregisterPlayer(uint playerIndex)
|
||||
{
|
||||
playersByIndex.TryRemove(playerIndex, out _);
|
||||
}
|
||||
|
||||
public static jSkill_PlayerInfo? GetPlayerByIndex(uint? playerIndex)
|
||||
{
|
||||
if (playerIndex == null) return null;
|
||||
|
||||
playersByIndex.TryGetValue((uint)playerIndex, out var playerInfo);
|
||||
return playerInfo;
|
||||
}
|
||||
|
||||
public static CCSPlayerController? GetPlayerEvent(CCSPlayerController? player)
|
||||
{
|
||||
if (player == null || !player.IsValid)
|
||||
return null;
|
||||
|
||||
if (!player.ControllingBot)
|
||||
return player;
|
||||
|
||||
return Utilities.GetPlayers().FirstOrDefault(p =>
|
||||
p != null &&
|
||||
p.IsValid &&
|
||||
p.IsBot &&
|
||||
p.OriginalControllerOfCurrentPawn.Value != null && p.OriginalControllerOfCurrentPawn.Value == player)
|
||||
?? player;
|
||||
}
|
||||
|
||||
public static CCSPlayerController? GetPlayerFromEvent(CCSPlayerController? player)
|
||||
{
|
||||
if (player == null || !player.IsValid)
|
||||
return null;
|
||||
|
||||
if (!player.IsBot)
|
||||
return player;
|
||||
|
||||
return Utilities.GetPlayers().FirstOrDefault(p =>
|
||||
p != null &&
|
||||
p.IsValid &&
|
||||
!p.IsBot &&
|
||||
player.OriginalControllerOfCurrentPawn.Value != null && player.OriginalControllerOfCurrentPawn.Value == p)
|
||||
?? player;
|
||||
}
|
||||
|
||||
public static IEnumerable<jSkill_PlayerInfo> GetAllPlayers()
|
||||
{
|
||||
return playersByIndex.Values;
|
||||
}
|
||||
|
||||
public static IEnumerable<jSkill_PlayerInfo> GetAlivePlayers()
|
||||
{
|
||||
return playersByIndex.Values.Where(p =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var controller = Utilities.GetPlayerFromIndex((int)p.PlayerIndex);
|
||||
return controller != null && controller.IsValid && controller.PawnIsAlive;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static IEnumerable<jSkill_PlayerInfo> GetPlayersByTeam(CsTeam team)
|
||||
{
|
||||
return playersByIndex.Values.Where(p =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var controller = Utilities.GetPlayerFromIndex((int)p.PlayerIndex);
|
||||
return controller != null && controller.IsValid && controller.Team == team;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static int GetTeamPlayerCount(CsTeam team)
|
||||
{
|
||||
return GetPlayersByTeam(team).Count();
|
||||
}
|
||||
|
||||
public static int GetPlayerCountBySkill(Skills skills)
|
||||
{
|
||||
return playersByIndex.Values.Count(p => p.Skill == skills);
|
||||
}
|
||||
|
||||
public static bool UpdatePlayerSkill(uint playerIndex, Skills skill, Skills specialSkill = Skills.None)
|
||||
{
|
||||
if (playersByIndex.TryGetValue(playerIndex, out var playerInfo))
|
||||
{
|
||||
playerInfo.Skill = skill;
|
||||
playerInfo.SpecialSkill = specialSkill;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
playersByIndex.Clear();
|
||||
}
|
||||
|
||||
public static void SyncWithPlugin(jRandomSkills instance)
|
||||
{
|
||||
if (instance?.SkillPlayer == null) return;
|
||||
|
||||
foreach (var player in instance.SkillPlayer)
|
||||
Register(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
namespace src.utils
|
||||
using System.Drawing;
|
||||
|
||||
namespace src.utils
|
||||
{
|
||||
public enum Rarity
|
||||
{
|
||||
|
|
@ -14,11 +16,11 @@
|
|||
private static readonly object rarityLock = new();
|
||||
private static Dictionary<Rarity, float> rarityPercentages = new()
|
||||
{
|
||||
{ Rarity.Common, 40f },
|
||||
{ Rarity.Uncommon, 25f },
|
||||
{ Rarity.Rare, 20f },
|
||||
{ Rarity.Epic, 10f },
|
||||
{ Rarity.Legendary, 5f }
|
||||
{ Rarity.Common, 70f },
|
||||
{ Rarity.Uncommon, 14f },
|
||||
{ Rarity.Rare, 10f },
|
||||
{ Rarity.Epic, 5f },
|
||||
{ Rarity.Legendary, 1f }
|
||||
};
|
||||
|
||||
public static IReadOnlyDictionary<Rarity, float> RarityPercentages
|
||||
|
|
@ -60,23 +62,23 @@
|
|||
return rarityPercentages.TryGetValue(rarity, out var v) ? v : 0f;
|
||||
}
|
||||
|
||||
public static Rarity RollRarity()
|
||||
public static (double, Rarity) RollRarity()
|
||||
{
|
||||
var random = jRandomSkills.Instance?.Random ?? new Random();
|
||||
double roll = (random.NextDouble()) * 100.0;
|
||||
double roll = Random.Shared.NextDouble() * 100.0;
|
||||
double accum = 0.0;
|
||||
|
||||
lock (rarityLock)
|
||||
{
|
||||
foreach (var r in Enum.GetValues(typeof(Rarity)).Cast<Rarity>())
|
||||
{
|
||||
accum += GetRarityPercentage(r);
|
||||
float chance = rarityPercentages.TryGetValue(r, out var val) ? val : 0f;
|
||||
accum += chance;
|
||||
if (roll <= accum)
|
||||
return r;
|
||||
return (roll, r);
|
||||
}
|
||||
}
|
||||
|
||||
return Rarity.Common;
|
||||
return (roll, Rarity.Common);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,15 @@ namespace src.utils
|
|||
|
||||
public static CustomTraceResult? TraceShape(CCSPlayerController player, Vector startPos, Vector endPos, ulong? mask = null, ulong? contents = null)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null)
|
||||
if (player == null || !player.IsValid) return null;
|
||||
|
||||
var playerPawn = player.PlayerPawn?.Value;
|
||||
if (playerPawn == null ||
|
||||
!playerPawn.IsValid ||
|
||||
playerPawn.Handle == IntPtr.Zero ||
|
||||
playerPawn.Collision == null ||
|
||||
playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE ||
|
||||
playerPawn.CBodyComponent?.SceneNode == null)
|
||||
return null;
|
||||
|
||||
var rayTrace = RayTraceInterface.Get();
|
||||
|
|
@ -27,10 +34,22 @@ namespace src.utils
|
|||
|
||||
if (mask == null)
|
||||
{
|
||||
mask = playerPawn.Collision.CollisionAttribute.InteractsWith | (ulong)InteractionLayers.Hitboxes;
|
||||
mask &= ~(ulong)InteractionLayers.PlayerClip;
|
||||
try
|
||||
{
|
||||
if (playerPawn.Collision?.CollisionAttribute != null)
|
||||
{
|
||||
mask = playerPawn.Collision.CollisionAttribute.InteractsWith | (ulong)InteractionLayers.Hitboxes;
|
||||
mask &= ~(ulong)InteractionLayers.PlayerClip;
|
||||
}
|
||||
else
|
||||
mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Hitboxes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Hitboxes);
|
||||
}
|
||||
}
|
||||
contents ??= 0; // playerPawn.Collision.CollisionGroup;
|
||||
contents ??= 0;
|
||||
|
||||
bool drawBeam = Config.LoadedConfig.TraceRayBeam;
|
||||
|
||||
|
|
@ -41,28 +60,39 @@ namespace src.utils
|
|||
DrawBeam = drawBeam == true ? 1 : 0,
|
||||
};
|
||||
|
||||
rayTrace.TraceEndShape(startPos, endPos, playerPawn, options, out TraceResult result);
|
||||
var customResult = new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam);
|
||||
Vector mins = new(-0.5f, -0.5f, -0.5f);
|
||||
Vector maxs = new(0.5f, 0.5f, 0.5f);
|
||||
|
||||
if (drawBeam)
|
||||
Server.PrintToChatAll($"start: {startPos}, end: {result.EndPos}, didHit: {result.DidHit}, hit: {(customResult.HitEntity(out var entity) && !string.IsNullOrEmpty(entity?.DesignerName) ? entity.DesignerName : "None")}, mask: {(InteractionLayers)mask}, contents: {(InteractionLayers)contents}");
|
||||
TraceResult result = default;
|
||||
|
||||
return customResult;
|
||||
try
|
||||
{
|
||||
rayTrace.TraceHullShape(startPos, endPos, mins, maxs, playerPawn, options, out result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[jRandomSkills] A memory error was caught during RayTrace: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam);
|
||||
}
|
||||
|
||||
public static CustomTraceResult? EyeTrace(CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null)
|
||||
if (player == null || !player.IsValid) return null;
|
||||
|
||||
var playerPawn = player.PlayerPawn?.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null)
|
||||
return null;
|
||||
|
||||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||
if (playerInfo == null) return null;
|
||||
|
||||
float maxDistance = SkillsInfo.GetValue<float>(playerInfo.Skill, "maxDistance");
|
||||
if (maxDistance == 0) maxDistance = 4096f;
|
||||
|
||||
Vector startPos = new(playerPawn.AbsOrigin!.X, playerPawn.AbsOrigin!.Y, playerPawn.AbsOrigin!.Z + playerPawn.ViewOffset.Z);
|
||||
Vector startPos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + playerPawn.ViewOffset.Z);
|
||||
Vector endPos = startPos + SkillUtils.GetForwardVector(playerPawn.EyeAngles) * maxDistance;
|
||||
|
||||
return TraceShape(player, startPos, endPos);
|
||||
|
|
@ -70,38 +100,57 @@ namespace src.utils
|
|||
|
||||
public static CustomTraceResult? TraceHullShape(Vector startPos, Vector endPos, CCSPlayerController player, Vector? mins = null, Vector? maxs = null, ulong? mask = null, ulong? contents = null, QAngle? angle = null)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null)
|
||||
if (player == null || !player.IsValid) return null;
|
||||
|
||||
var playerPawn = player.PlayerPawn?.Value;
|
||||
if (playerPawn == null ||
|
||||
!playerPawn.IsValid ||
|
||||
playerPawn.Handle == IntPtr.Zero ||
|
||||
playerPawn.Collision == null ||
|
||||
playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE ||
|
||||
playerPawn.CBodyComponent?.SceneNode == null)
|
||||
return null;
|
||||
|
||||
var rayTrace = RayTraceInterface.Get();
|
||||
if (rayTrace == null)
|
||||
return null;
|
||||
|
||||
mask ??= playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
contents ??= 0; // playerPawn.Collision.CollisionGroup;
|
||||
Vector safeMins = mins ?? playerPawn.Collision.Mins;
|
||||
Vector safeMaxs = maxs ?? playerPawn.Collision.Maxs;
|
||||
|
||||
ulong safeMask = mask ?? playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong safeContents = contents ?? 0;
|
||||
|
||||
bool drawBeam = Config.LoadedConfig.TraceRayBeam;
|
||||
|
||||
TraceResult result = default;
|
||||
TraceOptions options = new()
|
||||
{
|
||||
InteractsWith = (ulong)mask,
|
||||
InteractsExclude = (ulong)contents,
|
||||
InteractsWith = safeMask,
|
||||
InteractsExclude = safeContents,
|
||||
DrawBeam = drawBeam == true ? 1 : 0,
|
||||
};
|
||||
|
||||
mins ??= playerPawn.Collision.Mins;
|
||||
maxs ??= playerPawn.Collision.Maxs;
|
||||
CEntityInstance? entityToIgnore = (playerPawn.LifeState == (byte)LifeState_t.LIFE_ALIVE)
|
||||
? playerPawn
|
||||
: null;
|
||||
|
||||
rayTrace.TraceHullShape(startPos, endPos, mins, maxs, playerPawn, options, out TraceResult result);
|
||||
try
|
||||
{
|
||||
rayTrace.TraceHullShape(startPos, endPos, safeMins, safeMaxs, entityToIgnore, options, out result);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (drawBeam)
|
||||
{
|
||||
angle ??= new(0, playerPawn.EyeAngles.Y, 0);
|
||||
DrawBoxEdges(startPos, endPos, angle, mins, maxs, Color.Green);
|
||||
DrawBoxEdges(startPos, endPos, angle, safeMins, safeMaxs, Color.Green);
|
||||
}
|
||||
|
||||
return new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam);
|
||||
return new CustomTraceResult(result, startPos, safeMask, safeContents, drawBeam);
|
||||
}
|
||||
|
||||
private static void DrawBoxEdges(Vector start, Vector end, QAngle angles, Vector mins, Vector maxs, Color color)
|
||||
|
|
@ -112,7 +161,7 @@ namespace src.utils
|
|||
|
||||
Vector visualStart = start - (forward * halfLength);
|
||||
Vector visualEnd = end + (forward * halfLength);
|
||||
|
||||
|
||||
Vector GetVertex(Vector center, float rx, float ux)
|
||||
{
|
||||
return center + (right * rx) + (up * ux);
|
||||
|
|
@ -300,4 +349,4 @@ namespace src.utils
|
|||
EndsWith
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -105,11 +105,7 @@ namespace src.utils
|
|||
public static void SafeKillEntity<T>(uint? index) where T : CBaseEntity
|
||||
{
|
||||
if (index == null) return;
|
||||
|
||||
var ent = Utilities.GetEntityFromIndex<T>((int)index);
|
||||
if (ent == null || !ent.IsValid) return;
|
||||
|
||||
ent.AddEntityIOEvent("Kill", ent, delay: 0.1f);
|
||||
EntityManager.DestroyEntity(index.Value);
|
||||
}
|
||||
|
||||
public static bool IsValid<T>(this CHandle<T>? handle) where T : NativeEntity
|
||||
|
|
@ -150,23 +146,9 @@ namespace src.utils
|
|||
SnapViewAngles.Invoke(pawn, angle);
|
||||
}
|
||||
|
||||
public static CBeam? CreateLine(Vector start, Vector end, Color color)
|
||||
public static CBeam? CreateLine(Vector start, Vector end, Color color, uint ownerPlayerIndex = EntityManager.SystemOwnerIndex)
|
||||
{
|
||||
CBeam beam = Utilities.CreateEntityByName<CBeam>("beam")!;
|
||||
if (beam == null) return null;
|
||||
|
||||
beam.Render = color;
|
||||
beam.Width = 2.0f;
|
||||
beam.EndWidth = 2.0f;
|
||||
beam.Teleport(start);
|
||||
|
||||
beam.EndPos.X = end.X;
|
||||
beam.EndPos.Y = end.Y;
|
||||
beam.EndPos.Z = end.Z;
|
||||
|
||||
beam.DispatchSpawn();
|
||||
|
||||
return beam;
|
||||
return EntityManager.CreateTrackedBeam(ownerPlayerIndex, start, end, color);
|
||||
}
|
||||
|
||||
public static void SetPlayerCollisions(CCSPlayerController? player, bool enable)
|
||||
|
|
@ -176,7 +158,7 @@ namespace src.utils
|
|||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || !player.PawnIsAlive || pawn.CBodyComponent == null) return;
|
||||
if (pawn == null || !pawn.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE || pawn.CBodyComponent == null) return;
|
||||
|
||||
var collision = pawn.Collision;
|
||||
if (collision == null) return;
|
||||
|
|
@ -264,21 +246,19 @@ namespace src.utils
|
|||
SmokeGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 45, teamNum);
|
||||
}
|
||||
|
||||
public static void TakeHealth(CCSPlayerPawn? pawn, int damage)
|
||||
public static bool TakeHealth(CCSPlayerPawn? pawn, int damage)
|
||||
{
|
||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
return;
|
||||
return false;
|
||||
|
||||
var player = pawn.Controller.Value;
|
||||
if (player != null && player.IsValid && player.SteamID != 0)
|
||||
{
|
||||
ulong steamId = player.SteamID;
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null) return false;
|
||||
|
||||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == steamId);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
var jester = Jester.GetJesterInfo(steamId);
|
||||
if (jester?.Active == true) return;
|
||||
var jester = Jester.GetJesterInfo(player.Index);
|
||||
if (jester?.Active == true) return false;
|
||||
}
|
||||
|
||||
int newHealth = (int)(pawn.Health - damage);
|
||||
|
|
@ -286,65 +266,49 @@ namespace src.utils
|
|||
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
|
||||
|
||||
if (pawn.Health <= 0)
|
||||
{
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (pawn == null || !pawn.IsValid) return;
|
||||
pawn?.CommitSuicide(false, true);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ResetPrintHTML(CCSPlayerController? player)
|
||||
{
|
||||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
|
||||
if (player == null || !player.IsValid) return;
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null) return;
|
||||
playerInfo.PrintHTML = null;
|
||||
}
|
||||
|
||||
public static CTriggerMultiple? CreateTrigger(string name, float radius, Vector pos)
|
||||
public static CTriggerMultiple? CreateTrigger(string name, float radius, Vector pos, uint ownerPlayerIndex = EntityManager.SystemOwnerIndex)
|
||||
{
|
||||
if (pos == null) return null;
|
||||
|
||||
var trigger = Utilities.CreateEntityByName<CTriggerMultiple>("trigger_multiple");
|
||||
if (trigger == null || trigger.AbsOrigin == null) return null;
|
||||
|
||||
trigger.Collision.SolidType = SolidType_t.SOLID_CAPSULE;
|
||||
trigger.Collision.SolidFlags = 0;
|
||||
trigger.Spawnflags = 1;
|
||||
trigger.Globalname = $"{name}_{trigger.Index}";
|
||||
trigger.Collision.SolidFlags = 1;
|
||||
|
||||
trigger.AbsOrigin.X = pos.X;
|
||||
trigger.AbsOrigin.Y = pos.Y;
|
||||
trigger.AbsOrigin.Z = pos.Z;
|
||||
|
||||
trigger.Collision.CapsuleRadius = radius;
|
||||
trigger.Collision.BoundingRadius = radius;
|
||||
|
||||
trigger.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_TRIGGER;
|
||||
trigger.Collision.EnablePhysics = 1;
|
||||
trigger.Collision.TriggerBloat = 0;
|
||||
|
||||
trigger.Collision.SurroundType = SurroundingBoundsType_t.USE_OBB_COLLISION_BOUNDS;
|
||||
trigger.Collision.CollisionAttribute.CollisionFunctionMask = 39;
|
||||
trigger.Collision.CollisionAttribute.CollisionGroup = 2;
|
||||
|
||||
trigger.DispatchSpawn();
|
||||
return trigger;
|
||||
return EntityManager.CreateTrackedTrigger(ownerPlayerIndex, name, radius, pos);
|
||||
}
|
||||
|
||||
public static void AddHealth(CCSPlayerPawn? pawn, int extraHealth, int? maxHealth = null)
|
||||
public static bool AddHealth(CCSPlayerPawn? pawn, int extraHealth, int? maxHealth = null)
|
||||
{
|
||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
return;
|
||||
return false;
|
||||
|
||||
maxHealth ??= pawn.MaxHealth;
|
||||
|
||||
if (pawn.Health == maxHealth)
|
||||
return false;
|
||||
|
||||
int newHealth = (int)(pawn.Health + extraHealth);
|
||||
pawn.Health = Math.Min(newHealth, (int)maxHealth);
|
||||
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
|
||||
|
||||
pawn.MaxHealth = (int)maxHealth;
|
||||
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iMaxHealth");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void RestoreHealth(CCSPlayerController? player)
|
||||
|
|
@ -356,10 +320,28 @@ namespace src.utils
|
|||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
return;
|
||||
|
||||
pawn.Health = (int)player.PawnHealth;
|
||||
var p = PlayerManager.GetPlayerFromEvent(player);
|
||||
if (p == null || !p.IsValid)
|
||||
return;
|
||||
|
||||
pawn.Health = (int)p.PawnHealth;
|
||||
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
|
||||
}
|
||||
|
||||
public static void SetPlayerInvisibility(CCSPlayerController player, float percentInvisibility)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.PlayerPawn == null)
|
||||
return;
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn != null)
|
||||
{
|
||||
var color = Color.FromArgb(Math.Max(255 - (int)(255 * percentInvisibility), 0), 255, 255, 255);
|
||||
playerPawn.Render = color;
|
||||
Utilities.SetStateChanged(playerPawn, "CBaseModelEntity", "m_clrRender");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetDesignerName(CBasePlayerWeapon? weapon)
|
||||
{
|
||||
if (weapon == null || !weapon.IsValid) return string.Empty;
|
||||
|
|
@ -406,7 +388,7 @@ namespace src.utils
|
|||
var manager = GetMenuManager();
|
||||
if (manager == null) return;
|
||||
|
||||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
bool isIlliterate = Illiterate.CheckIlliterateSkill(player);
|
||||
|
|
@ -428,9 +410,29 @@ namespace src.utils
|
|||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null || !playerInfo.DisplayHUD) return;
|
||||
|
||||
if (player.IsBot)
|
||||
{
|
||||
var pool = new List<string>();
|
||||
|
||||
foreach (var enemy in enemies)
|
||||
if (!string.IsNullOrEmpty(enemy.Item2))
|
||||
pool.Add(enemy.Item2);
|
||||
|
||||
if (lastElement != null && !string.IsNullOrEmpty(lastElement.Value.Item2))
|
||||
pool.Add(lastElement.Value.Item2);
|
||||
|
||||
if (pool.Count > 0)
|
||||
{
|
||||
string randomTarget = pool[Random.Shared.Next(pool.Count)];
|
||||
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [player, new[] { randomTarget }]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == playerInfo.Skill);
|
||||
if (skillData == null) return;
|
||||
|
||||
|
|
@ -454,8 +456,6 @@ namespace src.utils
|
|||
? ""
|
||||
: $"<font class='fontSize-{config.WSADMenuSelectInfoLineSize}' color='{config.WSADMenuSelectInfoLineColor}'>{skill_select_info}</font><br>";
|
||||
|
||||
|
||||
|
||||
var hudContent = infoLine + skillLine + remainingLine;
|
||||
|
||||
string controllsLine =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue