159 lines
No EOL
6.7 KiB
C#
159 lines
No EOL
6.7 KiB
C#
using System.Drawing;
|
|
using CounterStrikeSharp.API;
|
|
using CounterStrikeSharp.API.Core;
|
|
using CounterStrikeSharp.API.Core.Attributes;
|
|
using CounterStrikeSharp.API.Modules.Utils;
|
|
using jRandomSkills.src.player;
|
|
using static jRandomSkills.jRandomSkills;
|
|
|
|
namespace jRandomSkills
|
|
{
|
|
public class Ninja : ISkill
|
|
{
|
|
private const Skills skillName = Skills.Ninja;
|
|
private static readonly float idlePercentInvisibility = Config.GetValue<float>(skillName, "idlePercentInvisibility");
|
|
private static readonly float duckPercentInvisibility = Config.GetValue<float>(skillName, "duckPercentInvisibility");
|
|
private static readonly float knifePercentInvisibility = Config.GetValue<float>(skillName, "knifePercentInvisibility");
|
|
private static readonly Dictionary<nint, float> invisibilityChanged = [];
|
|
private static readonly Dictionary<ulong, List<uint>> invisibleEntities = [];
|
|
|
|
public static void LoadSkill()
|
|
{
|
|
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
|
|
}
|
|
|
|
public static void NewRound()
|
|
{
|
|
invisibilityChanged.Clear();
|
|
}
|
|
|
|
public static void WeaponEquip(EventItemEquip @event)
|
|
{
|
|
var player = @event.Userid;
|
|
if (!Instance.IsPlayerValid(player)) return;
|
|
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
|
|
|
if (playerInfo?.Skill != skillName) return;
|
|
UpdateNinja(player);
|
|
}
|
|
|
|
public static void WeaponPickup(EventItemPickup @event)
|
|
{
|
|
var player = @event.Userid;
|
|
if (!Instance.IsPlayerValid(player)) return;
|
|
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
|
|
|
if (playerInfo?.Skill != skillName) return;
|
|
UpdateNinja(player);
|
|
}
|
|
|
|
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
|
|
{
|
|
foreach (var (info, player) in infoList)
|
|
{
|
|
if (player == null) continue;
|
|
foreach ((var playerId, var itemList) in invisibleEntities)
|
|
if (player.SteamID != playerId)
|
|
foreach (var item in itemList)
|
|
info.TransmitEntities.Remove(item);
|
|
}
|
|
}
|
|
|
|
public static void OnTick()
|
|
{
|
|
foreach (var player in Utilities.GetPlayers())
|
|
{
|
|
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
|
if (playerInfo?.Skill == skillName)
|
|
UpdateNinja(player);
|
|
}
|
|
}
|
|
|
|
public static void EnableSkill(CCSPlayerController _)
|
|
{
|
|
SkillUtils.EnableTransmit();
|
|
}
|
|
|
|
public static void DisableSkill(CCSPlayerController player)
|
|
{
|
|
SetPlayerVisibility(player, 0);
|
|
SetWeaponVisibility(player, 0);
|
|
invisibleEntities.Remove(player.SteamID);
|
|
}
|
|
|
|
private static void UpdateNinja(CCSPlayerController? player)
|
|
{
|
|
if (player == null || !player.IsValid) return;
|
|
var pawn = player.PlayerPawn?.Value;
|
|
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
|
|
|
var flags = (PlayerFlags)pawn.Flags;
|
|
var buttons = player.Buttons;
|
|
|
|
var weaponServices = pawn.WeaponServices;
|
|
if (weaponServices == null) return;
|
|
|
|
var activeWeapon = weaponServices.ActiveWeapon.Value;
|
|
float percentInvisibility = 0;
|
|
|
|
if (buttons.HasFlag(PlayerButtons.Duck))
|
|
percentInvisibility += duckPercentInvisibility;
|
|
if (activeWeapon != null && activeWeapon.DesignerName == "weapon_knife")
|
|
percentInvisibility += knifePercentInvisibility;
|
|
if (!buttons.HasFlag(PlayerButtons.Moveleft) && !buttons.HasFlag(PlayerButtons.Moveright) && !buttons.HasFlag(PlayerButtons.Forward) && !buttons.HasFlag(PlayerButtons.Back) && flags.HasFlag(PlayerFlags.FL_ONGROUND))
|
|
percentInvisibility += idlePercentInvisibility;
|
|
|
|
SetWeaponVisibility(player, percentInvisibility);
|
|
if (invisibilityChanged.TryGetValue(player.Handle, out float oldInvisibility))
|
|
if (percentInvisibility == oldInvisibility)
|
|
return;
|
|
|
|
invisibilityChanged[player.Handle] = percentInvisibility;
|
|
SetPlayerVisibility(player, percentInvisibility);
|
|
}
|
|
|
|
private static void SetPlayerVisibility(CCSPlayerController player, float percentInvisibility)
|
|
{
|
|
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");
|
|
}
|
|
}
|
|
|
|
private static void SetWeaponVisibility(CCSPlayerController player, float percentInvisibility)
|
|
{
|
|
if (!Instance.IsPlayerValid(player)) return;
|
|
var playerPawn = player.PlayerPawn.Value!;
|
|
if (playerPawn.WeaponServices == null) return;
|
|
|
|
var color = Color.FromArgb(Math.Max(255 - (int)(255 * percentInvisibility * 2), 0), 255, 255, 255);
|
|
|
|
invisibleEntities.Remove(player.SteamID);
|
|
if (color.A != 0) return;
|
|
|
|
foreach (var weapon in playerPawn.WeaponServices.MyWeapons)
|
|
{
|
|
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
|
|
{
|
|
if (invisibleEntities.TryGetValue(player.SteamID, out var items))
|
|
{
|
|
if (!items.Contains(weapon.Index))
|
|
items.Add(weapon.Index);
|
|
}
|
|
else
|
|
invisibleEntities.Add(player.SteamID, [weapon.Index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dedede", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float idlePercentInvisibility = .3f, float duckPercentInvisibility = .3f, float knifePercentInvisibility = .3f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates)
|
|
{
|
|
public float IdlePercentInvisibility { get; set; } = idlePercentInvisibility;
|
|
public float DuckPercentInvisibility { get; set; } = duckPercentInvisibility;
|
|
public float KnifePercentInvisibility { get; set; } = knifePercentInvisibility;
|
|
}
|
|
}
|
|
} |