Merge upstream v1.2.4.b3: native CSS traces, drop Ray-Trace
Upstream replaced RayTraceApi/RayTraceImpl with CounterStrikeSharp's own Trace API (CSS 1.0.375), so RayTrace-MM and RayTrace-CSS-API are no longer needed. Also brings the CS2 1.41.8.3 gamedata fixes and the No Recoil, Long Zeus, Long Knife, Fragile Bomb and Tripwire fixes. Kept from this fork: Panorama skill card and target menu (PanoramaManager), css_setoverride, WASDMenuAPI removed, no tracked "Server Files" build output. Version 1.2.4.b3-panorama1.
This commit is contained in:
commit
d6f1bbb24f
23 changed files with 524 additions and 146 deletions
|
|
@ -98,6 +98,7 @@ namespace src.player
|
|||
!Instance.SkillPlayer.Any(p => !p.IsDrawing && p.Skill == Skills.Fortnite))
|
||||
Instance.SkillAction("Fortnite", "OnTakeDamage", args);
|
||||
|
||||
SkillUtils.ApplyNativeKill(entity, info);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using RayTraceAPI;
|
||||
using src.player.skills;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -108,6 +107,7 @@ namespace src.player
|
|||
TryUnhook(() => VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Unhook(OnWeaponCanAcquire, HookMode.Pre));
|
||||
TryUnhook(() => Instance.UnhookUserMessage(208, PlayerMakeSound));
|
||||
TryUnhook(() => Instance.RemoveListener<CheckTransmit>(CheckTransmit));
|
||||
TryUnhook(NoRecoil.RestoreSpread);
|
||||
}
|
||||
|
||||
private static void TryUnhook(Action unhook)
|
||||
|
|
@ -507,6 +507,7 @@ namespace src.player
|
|||
private static void OnTick()
|
||||
{
|
||||
ReportStall();
|
||||
NoRecoil.RestoreSpread();
|
||||
|
||||
long perfStart = PerfLog.Start();
|
||||
lock (setLock)
|
||||
|
|
@ -794,7 +795,7 @@ namespace src.player
|
|||
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * 80;
|
||||
|
||||
ulong mask = (ulong)(InteractionLayers.MASK_WORLD_ONLY | InteractionLayers.Player | InteractionLayers.NPC);
|
||||
ulong mask = (ulong)Masks.SolidBrushOnly | (ulong)(Contents.Player | Contents.Npc);
|
||||
ulong contents = 0;
|
||||
var result = RayTrace.TraceShape(player, eyePos, endPos, mask, contents);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ namespace src.player
|
|||
|
||||
private static void OnMapStart(string mapName)
|
||||
{
|
||||
skills.NoRecoil.ForgetSpread();
|
||||
PlayerManager.SetServerActive(true);
|
||||
Instance.GameRules = null;
|
||||
Event.OnMapChange();
|
||||
|
|
@ -53,6 +54,8 @@ namespace src.player
|
|||
|
||||
private static void OnMapEnd()
|
||||
{
|
||||
skills.NoRecoil.RestoreSpread();
|
||||
skills.NoRecoil.ForgetSpread();
|
||||
PerfLog.Info("===== MAP END (clean map change) =====");
|
||||
Debug.WriteToDebug("===== MAP END (clean map change) =====");
|
||||
BotManager.Stop();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using RayTraceAPI;
|
||||
using src.player.skills;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -98,14 +97,14 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
bool isWarmup = Instance.GameRules == null || Instance.GameRules.WarmupPeriod == true;
|
||||
bool isWarmup = IsWarmupPeriod();
|
||||
isTransmitRegistered = false;
|
||||
setSkillRetries = 0;
|
||||
SkillUtils.ClearKillCredits();
|
||||
SkillUtils.ClearCurses();
|
||||
Instance.AddTimer(.1f, () => DisableAll(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && InPlayingTeam(p)))
|
||||
{
|
||||
var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (skillPlayer == null) continue;
|
||||
|
|
@ -115,18 +114,21 @@ namespace src.player
|
|||
|
||||
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
|
||||
int freezetime = SkillUtils.CvarValue("mp_freezetime", 0);
|
||||
freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0));
|
||||
int introDelay = IsTeamIntroPeriod() ? 7 : 0;
|
||||
freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + introDelay);
|
||||
|
||||
setSkillTimer?.Kill();
|
||||
|
||||
if (isWarmup)
|
||||
{
|
||||
setSkillTimer = Instance?.AddTimer(1f, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
Debug.WriteToDebug("RoundStart: warmup, SetSkill scheduled in 1.00s.", DebugCategory.Round);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f;
|
||||
float timeToDraw = introDelay + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f;
|
||||
setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
Debug.WriteToDebug($"RoundStart: SetSkill scheduled in {timeToDraw:F2}s (freezetime={freezetime}, intro={introDelay}, timer={(setSkillTimer == null ? "null" : "ok")}).", DebugCategory.Round);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +295,22 @@ namespace src.player
|
|||
private static void SetSkill()
|
||||
{
|
||||
long perfStart = PerfLog.Start();
|
||||
SetSkillCore();
|
||||
|
||||
try
|
||||
{
|
||||
SetSkillCore();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteToDebug($"SetSkill threw: {ex}", DebugCategory.Skill);
|
||||
|
||||
if (setSkillRetries < MaxSetSkillRetries)
|
||||
{
|
||||
setSkillRetries++;
|
||||
setSkillTimer = Instance?.AddTimer(.5f, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
PerfLog.End("SetSkill total", perfStart, 2.0);
|
||||
}
|
||||
|
||||
|
|
@ -472,10 +489,46 @@ namespace src.player
|
|||
|
||||
private static int CountConnectedPlayers()
|
||||
{
|
||||
try { return Utilities.GetPlayers().Count(p => p != null && p.IsValid && !p.IsHLTV); }
|
||||
try
|
||||
{
|
||||
return Utilities.GetPlayers().Count(p =>
|
||||
{
|
||||
if (p == null || !p.IsValid || p.IsHLTV) return false;
|
||||
var pawn = p.PlayerPawn?.Value;
|
||||
return pawn != null && pawn.IsValid;
|
||||
});
|
||||
}
|
||||
catch { return 0; }
|
||||
}
|
||||
|
||||
private static bool InPlayingTeam(CCSPlayerController player)
|
||||
{
|
||||
try { return player.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; }
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
private static bool IsWarmupPeriod()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gameRules = Instance?.GameRules;
|
||||
if (gameRules == null || gameRules.Handle == IntPtr.Zero) return true;
|
||||
return gameRules.WarmupPeriod;
|
||||
}
|
||||
catch { return true; }
|
||||
}
|
||||
|
||||
private static bool IsTeamIntroPeriod()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gameRules = Instance?.GameRules;
|
||||
if (gameRules == null || gameRules.Handle == IntPtr.Zero) return false;
|
||||
return gameRules.TeamIntroPeriod;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
private static void SetSkillCore()
|
||||
{
|
||||
setSkillTimer = null;
|
||||
|
|
@ -484,7 +537,7 @@ namespace src.player
|
|||
if (Instance == null) return;
|
||||
|
||||
// GameRules null = not ready; keep polling so skills land right after warmup ends.
|
||||
if (Instance.GameRules == null || Instance.GameRules.WarmupPeriod == true)
|
||||
if (IsWarmupPeriod())
|
||||
{
|
||||
if (++gameRulesPolls % 10 == 0)
|
||||
Debug.WriteToDebug($"SetSkill waiting: gameRules={(Instance.GameRules == null ? "null" : "warmup")}, poll {gameRulesPolls}.", DebugCategory.Skill);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.Timers;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using RayTraceAPI;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
|
|
@ -341,7 +340,7 @@ namespace src.player.skills
|
|||
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + playerPawn.ViewOffset.Z);
|
||||
Vector endPos = eyePos + SkillUtils.GetForwardVector(playerPawn.V_angle) * 4096f;
|
||||
|
||||
ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets);
|
||||
ulong mask = (ulong)(Contents.Solid | Contents.Window | Contents.PassBullets);
|
||||
var result = RayTrace.TraceShape(player, eyePos, endPos, mask);
|
||||
|
||||
if (result.HasValue && result.Value.HitWorld(out _))
|
||||
|
|
@ -370,7 +369,7 @@ namespace src.player.skills
|
|||
Vector endPos = cameraVector + SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * -5;
|
||||
cameraVector += SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * 5;
|
||||
|
||||
ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets);
|
||||
ulong mask = (ulong)(Contents.Solid | Contents.Window | Contents.PassBullets);
|
||||
var result = RayTrace.TraceShape(player, cameraVector, endPos, mask);
|
||||
|
||||
if (result.HasValue && result.Value.HitWorld(out _))
|
||||
|
|
|
|||
|
|
@ -29,10 +29,16 @@ namespace src.player.skills
|
|||
}
|
||||
|
||||
public static void BombPlanted(EventBombPlanted _)
|
||||
{
|
||||
plantedC4 = FindPlantedC4();
|
||||
}
|
||||
|
||||
private static Vector? FindPlantedC4()
|
||||
{
|
||||
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
|
||||
if (plantedBomb == null || !plantedBomb.IsValid || plantedBomb.AbsOrigin == null) return;
|
||||
plantedC4 = new(plantedBomb.AbsOrigin.X, plantedBomb.AbsOrigin.Y, plantedBomb.AbsOrigin.Z);
|
||||
if (plantedBomb == null || !plantedBomb.IsValid || plantedBomb.AbsOrigin == null) return null;
|
||||
if (!plantedBomb.BombTicking || plantedBomb.BombDefused) return null;
|
||||
return new(plantedBomb.AbsOrigin.X, plantedBomb.AbsOrigin.Y, plantedBomb.AbsOrigin.Z);
|
||||
}
|
||||
|
||||
private static void RemoveBomb()
|
||||
|
|
@ -49,14 +55,21 @@ namespace src.player.skills
|
|||
if (lastTick == Server.TickCount) return;
|
||||
|
||||
var player = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (player == null || !player.IsValid || plantedC4 == null) return;
|
||||
|
||||
var pos = new Vector(@event.X, @event.Y, @event.Z);
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null || playerInfo.Skill != skillName) return;
|
||||
|
||||
if (SkillUtils.Distance(plantedC4, pos) >= 8)
|
||||
plantedC4 ??= FindPlantedC4();
|
||||
if (plantedC4 == null) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||
|
||||
var eyePos = new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
var impactPos = new Vector(@event.X, @event.Y, @event.Z);
|
||||
|
||||
if (DistanceToSegment(plantedC4, eyePos, impactPos) >= 8)
|
||||
return;
|
||||
|
||||
lastTick = Server.TickCount;
|
||||
|
|
@ -71,6 +84,16 @@ namespace src.player.skills
|
|||
Localization.PrintTranslationToChatAll($" {ChatColors.Gold}{{0}}: {ChatColors.Red}{bombHealth}{ChatColors.Gold}/{ChatColors.Green}{maxBombHealth}", ["fragilebomb_bomb_health"]);
|
||||
}
|
||||
|
||||
private static float DistanceToSegment(Vector point, Vector start, Vector end)
|
||||
{
|
||||
float lineX = end.X - start.X, lineY = end.Y - start.Y, lineZ = end.Z - start.Z;
|
||||
float lengthSquared = lineX * lineX + lineY * lineY + lineZ * lineZ;
|
||||
float t = lengthSquared <= .0001f ? 0f : Math.Clamp(((point.X - start.X) * lineX + (point.Y - start.Y) * lineY + (point.Z - start.Z) * lineZ) / lengthSquared, 0f, 1f);
|
||||
|
||||
float dx = start.X + lineX * t - point.X, dy = start.Y + lineY * t - point.Y, dz = start.Z + lineZ * t - point.Z;
|
||||
return MathF.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 1, Rarity rarity = Rarity.Common, int maxBombHealth = 1000) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
public int MaxBombHealth { get; set; } = maxBombHealth;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace src.player.skills
|
|||
private const string victimSound = "Player.DamageBody.Victim";
|
||||
private const string heavyHitSound = "Weapon_Knife.Hit.Heavy.Flesh";
|
||||
private const string lightHitSound = "Weapon_Knife.Hit.Light.Flesh";
|
||||
private const string tracerParticle = "particles/weapons/cs_weapon_fx/weapon_tracers_rifle_wisp.vpcf";
|
||||
|
||||
private static bool hooked = false;
|
||||
private const int actionCode = 503;
|
||||
|
|
@ -30,6 +31,7 @@ namespace src.player.skills
|
|||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
Instance.AddToManifest(tracerParticle);
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
|
|
@ -113,6 +115,9 @@ namespace src.player.skills
|
|||
if (result == null || !result.HasValue)
|
||||
return;
|
||||
|
||||
if (result.Value.Distance() > 70)
|
||||
SkillUtils.CreateTracer(player, tracerParticle, result.Value);
|
||||
|
||||
if (!result.Value.HitPlayer(out CCSPlayerController? target) || target == null)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@ namespace src.player.skills
|
|||
public class LongZeus : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.LongZeus;
|
||||
private const string shockParticle = "particles/blood_impact/impact_taser_bodyfx.vpcf";
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
Instance.AddToManifest(shockParticle);
|
||||
}
|
||||
|
||||
public unsafe static void WeaponFire(EventWeaponFire @event)
|
||||
|
|
@ -40,7 +42,12 @@ namespace src.player.skills
|
|||
if (target.Handle == player.Handle) return;
|
||||
if (!SkillsInfo.GetValue<bool>(skillName, "friendlyFire") && player.Team == target.Team) return;
|
||||
|
||||
SkillUtils.TakeHealth(target.PlayerPawn.Value, 9999, player, KillfeedIcons.Taser);
|
||||
var targetPawn = target.PlayerPawn.Value;
|
||||
if (targetPawn == null || !targetPawn.IsValid) return;
|
||||
|
||||
EntityManager.CreateEntityParticle(player.Index, shockParticle, targetPawn);
|
||||
SkillUtils.RegisterNativeKill(targetPawn, pawn, activeWeapon, DamageTypes_t.DMG_SHOCK);
|
||||
SkillUtils.TakeHealth(targetPawn, 9999);
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,27 @@ namespace src.player.skills
|
|||
private static readonly ConcurrentDictionary<uint, byte> holders = [];
|
||||
private static readonly ConcurrentDictionary<uint, string> originalNoSpreadValues = [];
|
||||
|
||||
private sealed class SpreadPatch(CCSWeaponBaseVData vdata)
|
||||
{
|
||||
public readonly CCSWeaponBaseVData VData = vdata;
|
||||
public readonly CFiringModeFloat[] Fields =
|
||||
[
|
||||
vdata.Spread, vdata.InaccuracyCrouch, vdata.InaccuracyStand, vdata.InaccuracyJump,
|
||||
vdata.InaccuracyLand, vdata.InaccuracyLadder, vdata.InaccuracyFire, vdata.InaccuracyMove
|
||||
];
|
||||
public readonly float[] Values = new float[16];
|
||||
public int Count;
|
||||
public float JumpInitial;
|
||||
public float JumpApex;
|
||||
public float Reload;
|
||||
public bool Active;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<nint, SpreadPatch> spreadPatches = [];
|
||||
private static readonly List<SpreadPatch> activePatches = [];
|
||||
private static readonly Dictionary<nint, CCSWeaponBaseVData> wantedVData = [];
|
||||
private static readonly HashSet<nint> blockedVData = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
|
|
@ -83,6 +104,106 @@ namespace src.player.skills
|
|||
catch { }
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (holders.IsEmpty) return;
|
||||
|
||||
wantedVData.Clear();
|
||||
blockedVData.Clear();
|
||||
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (player == null || !player.IsValid || !player.PawnIsAlive) continue;
|
||||
|
||||
var vdata = GetActiveWeaponVData(player);
|
||||
if (vdata == null) continue;
|
||||
|
||||
bool isHolder = holders.ContainsKey(player.Index) && PlayerManager.GetPlayerByIndex(player.Index)?.Skill == skillName;
|
||||
if (isHolder)
|
||||
wantedVData[vdata.Handle] = vdata;
|
||||
else
|
||||
blockedVData.Add(vdata.Handle);
|
||||
}
|
||||
|
||||
foreach (var (handle, vdata) in wantedVData)
|
||||
{
|
||||
if (!blockedVData.Contains(handle))
|
||||
PatchSpread(vdata);
|
||||
}
|
||||
}
|
||||
|
||||
private static CCSWeaponBaseVData? GetActiveWeaponVData(CCSPlayerController player)
|
||||
{
|
||||
var weapon = player.PlayerPawn.Value?.WeaponServices?.ActiveWeapon.Value;
|
||||
if (weapon == null || !weapon.IsValid) return null;
|
||||
|
||||
var vdata = weapon.As<CCSWeaponBase>().VData;
|
||||
return vdata == null || vdata.Handle == IntPtr.Zero ? null : vdata;
|
||||
}
|
||||
|
||||
private static void PatchSpread(CCSWeaponBaseVData vdata)
|
||||
{
|
||||
if (!spreadPatches.TryGetValue(vdata.Handle, out var patch))
|
||||
{
|
||||
patch = new SpreadPatch(vdata);
|
||||
spreadPatches[vdata.Handle] = patch;
|
||||
}
|
||||
|
||||
if (patch.Active) return;
|
||||
|
||||
int index = 0;
|
||||
foreach (var field in patch.Fields)
|
||||
{
|
||||
var values = field.Values;
|
||||
for (int i = 0; i < values.Length && index < patch.Values.Length; i++)
|
||||
{
|
||||
patch.Values[index++] = values[i];
|
||||
values[i] = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
patch.Count = index;
|
||||
patch.JumpInitial = vdata.InaccuracyJumpInitial;
|
||||
patch.JumpApex = vdata.InaccuracyJumpApex;
|
||||
patch.Reload = vdata.InaccuracyReload;
|
||||
|
||||
vdata.InaccuracyJumpInitial = 0f;
|
||||
vdata.InaccuracyJumpApex = 0f;
|
||||
vdata.InaccuracyReload = 0f;
|
||||
|
||||
patch.Active = true;
|
||||
activePatches.Add(patch);
|
||||
}
|
||||
|
||||
public static void RestoreSpread()
|
||||
{
|
||||
if (activePatches.Count == 0) return;
|
||||
|
||||
foreach (var patch in activePatches)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (var field in patch.Fields)
|
||||
{
|
||||
var values = field.Values;
|
||||
for (int i = 0; i < values.Length && index < patch.Count; i++)
|
||||
values[i] = patch.Values[index++];
|
||||
}
|
||||
|
||||
patch.VData.InaccuracyJumpInitial = patch.JumpInitial;
|
||||
patch.VData.InaccuracyJumpApex = patch.JumpApex;
|
||||
patch.VData.InaccuracyReload = patch.Reload;
|
||||
patch.Active = false;
|
||||
}
|
||||
|
||||
activePatches.Clear();
|
||||
}
|
||||
|
||||
public static void ForgetSpread()
|
||||
{
|
||||
activePatches.Clear();
|
||||
spreadPatches.Clear();
|
||||
}
|
||||
|
||||
public static void WeaponFire(EventWeaponFire @event)
|
||||
{
|
||||
var player = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using jRandomSkills.src.utils;
|
||||
using RayTraceAPI;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
|
|
@ -22,7 +21,7 @@ namespace src.player.skills
|
|||
private static readonly List<Flight> flights = [];
|
||||
private static readonly object flightLock = new();
|
||||
private static readonly Color tracerColor = Color.FromArgb(170, 255, 226, 140);
|
||||
private static readonly ulong worldOnlyMask = (ulong)InteractionLayers.MASK_WORLD_ONLY;
|
||||
private static readonly ulong worldOnlyMask = (ulong)Masks.SolidBrushOnly;
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using RayTraceAPI;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
|
|
@ -104,19 +103,7 @@ namespace src.player.skills
|
|||
|
||||
private static void DestroyWire(uint beamIndex)
|
||||
{
|
||||
var beam = Utilities.GetEntityFromIndex<CBeam>((int)beamIndex);
|
||||
if (beam != null && beam.IsValid)
|
||||
{
|
||||
beam.Width = 0;
|
||||
beam.EndWidth = 0;
|
||||
beam.Render = Color.FromArgb(0, 0, 0, 0);
|
||||
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_fWidth");
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_fEndWidth");
|
||||
Utilities.SetStateChanged(beam, "CBaseModelEntity", "m_clrRender");
|
||||
}
|
||||
|
||||
EntityManager.DestroyEntity(beamIndex);
|
||||
EntityManager.DestroyBeam(beamIndex);
|
||||
}
|
||||
|
||||
public static void UseSkill(CCSPlayerController player)
|
||||
|
|
@ -175,7 +162,7 @@ namespace src.player.skills
|
|||
Vector rightDir = SkillUtils.GetForwardVector(new QAngle(0, yaw - 90, 0));
|
||||
Vector leftDir = SkillUtils.GetForwardVector(new QAngle(0, yaw + 90, 0));
|
||||
|
||||
ulong wallMask = (ulong)InteractionLayers.MASK_WORLD_ONLY;
|
||||
ulong wallMask = (ulong)Masks.SolidBrushOnly;
|
||||
|
||||
var rightHit = RayTrace.TraceShape(player, origin, origin + rightDir * maxDistance, wallMask, 0);
|
||||
var leftHit = RayTrace.TraceShape(player, origin, origin + leftDir * maxDistance, wallMask, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue