This commit is contained in:
Juzlus 2025-11-11 01:43:10 +01:00
parent 868372e6b7
commit 72e2910a68
40 changed files with 1191 additions and 244 deletions

View file

@ -102,9 +102,7 @@ namespace src.command
Server.PrintToConsole(Localization.GetTranslation("correct_form_setskill"));
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
return;
}
@ -115,9 +113,7 @@ namespace src.command
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
@ -131,9 +127,7 @@ namespace src.command
Server.PrintToConsole(Localization.GetTranslation("skill_not_found_setskill"));
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
return;
}
@ -152,12 +146,10 @@ namespace src.command
return;
}
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", false);
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}");
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}", false);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
}
else
{
@ -167,9 +159,7 @@ namespace src.command
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
}
}
@ -365,7 +355,7 @@ namespace src.command
if (!int.TryParse(command.GetArg(1), out int ctScore) || !int.TryParse(command.GetArg(2), out int tScore))
{
if (player != null && player.IsValid)
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setscore"), true);
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setscore"));
return;
}
@ -399,9 +389,7 @@ namespace src.command
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
return;
}
@ -413,9 +401,7 @@ namespace src.command
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
@ -430,9 +416,7 @@ namespace src.command
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
return;
}
@ -456,12 +440,10 @@ namespace src.command
return;
}
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", false);
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}");
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}", false);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
}
else
{
@ -471,9 +453,7 @@ namespace src.command
return;
}
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"), true);
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――");
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
}
}

View file

@ -21,7 +21,7 @@ namespace src
public ConcurrentBag<jSkill_PlayerInfo> SkillPlayer { get; set; } = [];
public Random Random { get; } = new Random();
public CCSGameRules? GameRules { get; set; }
public ConcurrentBag<string> ManifestResources { get; set; } = [ "models/actors/ghost_speaker.vmdl" ];
private ConcurrentBag<string> ManifestResources { get; set; } = [ "models/actors/ghost_speaker.vmdl" ];
public IWasdMenuManager? MenuManager;
public const string Tag = "jRandomSkills";
@ -47,6 +47,12 @@ namespace src
Instance.RegisterListener<OnServerPrecacheResources>(LoadManifest);
}
internal void AddToManifest(string prop)
{
if (!ManifestResources.Contains(prop))
ManifestResources.Add(prop);
}
internal void LoadManifest(ResourceManifest manifest)
{
foreach (var prop in ManifestResources)

View file

@ -454,7 +454,7 @@
"bombsite_b": "Bombsite B",
"teammate_skills": "Your teammates' skills",
"summary_start": "======SUMMARY=OF=THE=LAST=ROUND======",
"summary_start": "Summary of the last round",
"summary_end": "=======================================",
"menu_controlls_scroll": "W/S - Scroll",

View file

@ -454,7 +454,7 @@
"bombsite_b": "Site de bombe B",
"teammate_skills": "Compétences de vos coéquipiers",
"summary_start": "======RÉSUMÉ=DU=DERNIER=ROUND======",
"summary_start": "Résumé du dernier round",
"summary_end": "===================================",
"menu_controlls_scroll": "W/S - Défilement",

View file

@ -454,7 +454,7 @@
"bombsite_b": "Strefa detonacji B",
"teammate_skills": "Supermoce twoich sojuszników",
"summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======",
"summary_start": "Podsumowanie z ostatniej rundy",
"summary_end": "============================================",
"menu_controlls_scroll": "W/S – Przewijanie",

View file

@ -454,7 +454,7 @@
"bombsite_b": "Zona de detonação B",
"teammate_skills": "Habilidades dos seus companheiros de equipe",
"summary_start": "=======RESUMO=DA=ÚLTIMA=RODADA=======",
"summary_start": "Resumo da última rodada",
"summary_end": "=======================================",
"menu_controlls_scroll": "W/S - Rolar",

View file

@ -454,7 +454,7 @@
"bombsite_b": "爆轰区B",
"teammate_skills": "你队友的技能",
"summary_start": "=============上一回合总结==============",
"summary_start": "上一回合总结",
"summary_end": "=======================================",
"menu_controlls_scroll": "W/S - 滚动",

View file

@ -23,7 +23,7 @@ namespace src.menu
string cleanSkillName = Regex.Replace(selectedSkillName, pattern, "");
string skillName = cleanSkillName.Replace($" ★ ", "");
string skillDesc = player.GetSkillDescription(skillInfo.Skill);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{skillName}{ChatColors.Lime}: {skillDesc}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{skillName}{ChatColors.Lime}: {skillDesc}", border: "");
MenuManager.CloseActiveMenu(player);
});
}

View file

@ -68,6 +68,7 @@ public enum Skills
Chicken,
ChillOut,
Cutter,
Cypher,
Darkness,
Deactivator,
Deaf,
@ -97,6 +98,7 @@ public enum Skills
HealingSmoke,
Hermit,
HolyHandGrenade,
Iana,
Impostor,
InfiniteAmmo,
Jackal,
@ -132,6 +134,7 @@ public enum Skills
RadarHack,
Rambo,
RandomWeapon,
RCMelon,
ReZombie,
ReactiveArmor,
Regeneration,

View file

@ -1,6 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory;
@ -11,6 +12,7 @@ using src.utils;
using System.Collections.Concurrent;
using static CounterStrikeSharp.API.Core.Listeners;
using static src.jRandomSkills;
using static System.Net.Mime.MediaTypeNames;
namespace src.player
{
@ -261,7 +263,6 @@ namespace src.player
private static HookResult OnTriggerEnter(DynamicHook hook)
{
Server.PrintToChatAll("Start");
lock (setLock)
{
CBaseTrigger trigger = hook.GetParam<CBaseTrigger>(0);
@ -276,10 +277,9 @@ namespace src.player
private static HookResult OnTriggerExit(DynamicHook hook)
{
Server.PrintToChatAll("End");
lock (setLock)
{
CBaseTrigger trigger = hook.GetParam<CBaseTrigger>(0);
CBaseTrigger trigger = hook.GetParam<CBaseTrigger>(0);
CBaseEntity entity = hook.GetParam<CBaseEntity>(1);
foreach (var playerSkill in Instance.SkillPlayer)
@ -434,13 +434,11 @@ namespace src.player
if (Config.LoadedConfig.SummaryAfterTheRound && !string.IsNullOrEmpty(skillsText))
{
player.PrintToChat(" ");
player.PrintToChat($" {ChatColors.Lime}{player.GetTranslation("summary_start")}");
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("summary_start"), border: "t");
foreach (string text in skillsText.Split("\n"))
if (!string.IsNullOrEmpty(text))
player.PrintToChat(text);
player.PrintToChat($" {ChatColors.Lime}{player.GetTranslation("summary_end")}");
player.PrintToChat(" \n");
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("summary_start"), border: "b");
}
});
}
@ -482,8 +480,9 @@ namespace src.player
if (skillData == null || specialSkillData == null) return HookResult.Continue;
string skillDesc = victim.GetSkillDescription(skillData.Skill);
SkillUtils.PrintToChat(victim, $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}:", false);
SkillUtils.PrintToChat(victim, $"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}", false);
SkillUtils.PrintToChat(victim,
$"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}",
title: $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}");
}
}
return HookResult.Continue;
@ -582,6 +581,8 @@ namespace src.player
{
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None);
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (gameMode != Config.GameModes.FullRandom)
skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill);
@ -626,7 +627,8 @@ namespace src.player
}
if (randomSkill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
Instance?.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
skillPlayer.Skill = randomSkill.Skill;
@ -661,10 +663,11 @@ namespace src.player
if (!string.IsNullOrEmpty(teammateSkills))
{
SkillUtils.PrintToChat(player, $" {ChatColors.Lime}{player.GetTranslation("teammate_skills")}:", false);
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "t");
foreach (string text in teammateSkills.Split("\n"))
if (!string.IsNullOrEmpty(text))
player.PrintToChat(text);
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "b");
}
});
}
@ -709,6 +712,8 @@ namespace src.player
{
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None);
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (gameMode != Config.GameModes.FullRandom)
skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill);
@ -745,7 +750,8 @@ namespace src.player
}
if (randomSkill.Display && Config.LoadedConfig.YourSkillChatInfo)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
skillPlayer.Skill = randomSkill.Skill;
skillPlayer.SpecialSkill = Skills.None;

View file

@ -1,4 +1,5 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -23,7 +24,8 @@ namespace src.player.skills
float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newScale;
newScale = (float)Math.Round(newScale, 2);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public static void OnTakeDamage(DynamicHook h)

View file

@ -43,7 +43,8 @@ namespace src.player.skills
float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom"), 1);
playerInfo.SkillChance = gravityModifier;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, gravityModifier)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, gravityModifier)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
player.PlayerPawn.Value.ActualGravityScale = gravityModifier;
}

View file

@ -1,3 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -33,7 +34,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
private static void RotateEnemy(CCSPlayerController player)

View file

@ -1,22 +1,29 @@
using System.Drawing;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
public class C4Camouflage : ISkill
{
private const Skills skillName = Skills.C4Camouflage;
private static readonly ConcurrentDictionary<ulong, ConcurrentBag<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
}
public static void NewRound()
{
invisiblePlayers.Clear();
}
public static void WeaponPickup(EventItemPickup @event)
@ -30,7 +37,7 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
var player = @event.Userid!;
var weapon = @event.Item;
if (!Instance.IsPlayerValid(player)) return;
@ -38,25 +45,16 @@ namespace src.player.skills
if (playerInfo?.Skill != skillName) return;
if (weapon == "c4")
{
SetPlayerVisibility(player!, false);
SetWeaponVisibility(player!, false);
}
invisiblePlayers.TryAdd(player, 0);
else
{
SetPlayerVisibility(player!, true);
SetWeaponVisibility(player!, true);
}
invisiblePlayers.TryRemove(player, out _);
}
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
{
if (!player.PawnIsAlive)
if (invisibleEntities.ContainsKey(player.SteamID))
invisibleEntities.TryRemove(player.SteamID, out _);
}
invisiblePlayers.TryRemove(player, out _);
}
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
@ -64,14 +62,22 @@ namespace src.player.skills
foreach (var (info, player) in infoList)
{
if (player == null) continue;
foreach ((var playerId, var itemList) in invisibleEntities)
if (player.SteamID != playerId)
foreach (var entityIndex in itemList)
{
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
}
foreach (var _player in invisiblePlayers.Keys)
if (player.SteamID != _player.SteamID)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
@ -88,54 +94,54 @@ namespace src.player.skills
var activeWeapon = playerPawn.WeaponServices.ActiveWeapon.Value;
if (activeWeapon.DesignerName != "weapon_c4") return;
SetPlayerVisibility(player, false);
SetWeaponVisibility(player, false);
invisiblePlayers.TryAdd(player, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
SetPlayerVisibility(player, true);
SetWeaponVisibility(player, true);
invisibleEntities.TryRemove(player.SteamID, out _);
invisiblePlayers.TryRemove(player, out _);
}
private static void SetPlayerVisibility(CCSPlayerController player, bool enabled)
public static void PlayerHurt(EventPlayerHurt @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player)) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
var color = Color.FromArgb(enabled ? 255 : 0, 255, 255, 255);
playerPawn.Render = color;
Utilities.SetStateChanged(playerPawn, "CBaseModelEntity", "m_clrRender");
}
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!;
if (particle == null) return;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start");
}
private static void SetWeaponVisibility(CCSPlayerController player, bool visible)
private static uint? HideBomb(CCSPlayerController player)
{
if (!Instance.IsPlayerValid(player)) return;
var playerPawn = player.PlayerPawn.Value!;
if (playerPawn.WeaponServices == null) return;
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
invisibleEntities.TryRemove(player.SteamID, out _);
foreach (var weapon in playerPawn.WeaponServices.MyWeapons)
{
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
{
if (!visible)
{
if (invisibleEntities.TryGetValue(player.SteamID, out var items))
{
if (!items.Contains(weapon.Index))
items.Add(weapon.Index);
}
else
invisibleEntities.TryAdd(player.SteamID, [weapon.Index]);
}
}
}
var bomb = bombEntities.FirstOrDefault();
if (bomb == null) return null;
if (visible)
invisibleEntities.TryRemove(player.SteamID, out _);
// if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00911f", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -1,3 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -37,7 +38,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -0,0 +1,287 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using System.Numerics;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
public class Cypher : ISkill
{
private const Skills skillName = Skills.Cypher;
private static readonly ConcurrentDictionary<CCSPlayerController, PlayerSkill> playersInfo = [];
private static readonly object setLock = new();
private const string cameraPropModel = "models/props/de_train/hr_train_s2/train_electronics/train_electronics_security_camera_01.vmdl";
private const string cameraViewModel = "models/actors/ghost_speaker.vmdl";
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
jRandomSkills.Instance.AddToManifest(cameraPropModel);
jRandomSkills.Instance.AddToManifest(cameraViewModel);
}
public static void NewRound()
{
foreach (var playerSkill in playersInfo.Values)
KillCamera(playerSkill);
lock (setLock)
playersInfo.Clear();
}
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
ChangeCamera(playerSkill);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
playersInfo.TryAdd(player, new PlayerSkill
{
Player = player,
CameraProp = null,
CameraView = null,
CameraActive = false,
NextCamera = 0,
PlayerCameraRaw = player.PlayerPawn.Value.CameraServices.ViewEntity.Raw,
});
}
public static void DisableSkill(CCSPlayerController player)
{
if (playersInfo.TryGetValue(player, out var playerSkill))
{
ChangeCamera(playerSkill, true);
KillCamera(playerSkill);
}
playersInfo.TryRemove(player, out _);
}
private static void KillCamera(PlayerSkill playerSkill)
{
if (playerSkill.CameraView != null && playerSkill.CameraView.IsValid)
{
playerSkill.CameraView.AcceptInput("Kill");
playerSkill.CameraView = null;
playerSkill.CameraActive = false;
}
if (playerSkill.CameraProp != null && playerSkill.CameraProp.IsValid)
{
playerSkill.CameraProp.EmitSound("SolidMetal.BulletImpact");
playerSkill.CameraProp.AcceptInput("Kill");
playerSkill.CameraProp = null;
}
}
public static void OnTick()
{
foreach (var playerSkill in playersInfo.Values)
{
if (playerSkill.CameraActive && playerSkill.CameraView != null && playerSkill.CameraView.IsValid)
{
var pawn = playerSkill.Player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) continue;
if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{
DisableSkill(playerSkill.Player);
continue;
}
playerSkill.CameraView.Teleport(null, pawn.V_angle);
}
UpdateHUD(playerSkill);
}
}
private static void ChangeCamera(PlayerSkill player, bool forceToDefault = false)
{
player.CameraActive = forceToDefault ? false : !player.CameraActive;
if (player.CameraProp == null && !forceToDefault)
{
if (player.NextCamera > Server.TickCount) return;
player.CameraProp = CreateCameraProp(player.Player);
player.CameraView = CreateCameraView(player.Player);
player.NextCamera = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
}
var pawn = player.Player.PlayerPawn.Value;
if (player.PlayerCameraRaw == 0)
return;
BlockWeapon(player.Player, player.CameraActive);
pawn!.CameraServices!.ViewEntity.Raw = player.CameraActive && player.CameraView != null ? player.CameraView.EntityHandle.Raw : player.PlayerCameraRaw;
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices");
}
private static CDynamicProp? CreateCameraProp(CCSPlayerController player)
{
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic_override");
if (camera == null || !camera.IsValid) return null;
camera.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.SteamID}";
camera.DispatchSpawn();
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return null;
Vector? cameraVector = GetNewCameraPosition(player);
Vector diffVector = SkillUtils.GetForwardVector(playerPawn.V_angle) * 10;
if (cameraVector == null) return null;
cameraVector = new Vector(cameraVector.X + diffVector.X, cameraVector.Y + diffVector.Y, cameraVector.Z);
Server.NextFrame(() =>
{
camera.SetModel(cameraPropModel);
camera.Teleport(cameraVector, new QAngle(0, playerPawn.V_angle.Y + 180, 0));
});
return camera;
}
private static CDynamicProp? CreateCameraView(CCSPlayerController player)
{
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic");
if (camera == null || !camera.IsValid) return null;
camera.DispatchSpawn();
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return null;
Vector? cameraVector = GetNewCameraPosition(player);
Vector diffVector = SkillUtils.GetForwardVector(playerPawn.V_angle) * 25;
if (cameraVector == null) return null;
cameraVector = new Vector(cameraVector.X - diffVector.X, cameraVector.Y - diffVector.Y, cameraVector.Z);
if (cameraVector == null) return null;
Server.NextFrame(() =>
{
camera.SetModel(cameraViewModel);
camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(cameraVector, playerPawn.EyeAngles);
});
return camera;
}
public static void OnTakeDamage(DynamicHook h)
{
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null)
return;
if (string.IsNullOrEmpty(param.Entity.Name)) return;
if (!param.Entity.Name.StartsWith("CypherCamera_")) return;
var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID);
if (steamID == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
{
ChangeCamera(playerSkill, true);
KillCamera(playerSkill);
}
}
private static void BlockWeapon(CCSPlayerController player, bool block)
{
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
foreach (var weapon in pawn.WeaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
{
weapon.Value.NextPrimaryAttackTick = block ? int.MaxValue : Server.TickCount;
weapon.Value.NextSecondaryAttackTick = block ? int.MaxValue : Server.TickCount;
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
private unsafe static Vector? GetNewCameraPosition(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return null;
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + playerPawn.ViewOffset.Z);
Vector endPos = eyePos + SkillUtils.GetForwardVector(playerPawn.V_angle) * 4096f;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = playerPawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
if (trace.HitWorld(out _))
return new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z);
return null;
}
private static void UpdateHUD(PlayerSkill playerSkill)
{
if (playerSkill == null || playerSkill.Player == null) return;
float cooldown = 0;
float time = (playerSkill.NextCamera - Server.TickCount) / 64;
cooldown = (int)Math.Ceiling(Math.Max(time, 0));
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
if (playerInfo == null) return;
if (cooldown == 0)
playerInfo.PrintHTML = null;
else if (playerSkill?.CameraProp == null)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
public class PlayerSkill
{
public required CCSPlayerController Player { get; set; }
public CDynamicProp? CameraProp { get; set; }
public CDynamicProp? CameraView { get; set; }
public uint PlayerCameraRaw { get; set; }
public bool CameraActive { get; set; }
public float NextCamera { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#34ebd5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
}
}
}

View file

@ -1,3 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -42,7 +43,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -95,7 +95,8 @@ namespace src.player.skills
}
SkillUtils.CreateMenu(player, menuItems);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");

View file

@ -37,7 +37,8 @@ namespace src.player.skills
playerInfo.SkillChance = newSize;
SkillUtils.ChangePlayerScale(player, newSize);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSize)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSize)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
}

View file

@ -26,7 +26,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
private static void SpawnExplosion(Vector vector)

View file

@ -61,7 +61,8 @@ namespace src.player.skills
jumpedPlayers.TryAdd(player.SteamID, 0);
playerPawn.VelocityModifier = newSpeed;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSpeed)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSpeed)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public static void DisableSkill(CCSPlayerController player)

View file

@ -18,7 +18,7 @@ namespace src.player.skills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
Instance.ManifestResources.Add(SkillsInfo.GetValue<string>(skillName, "propModel"));
Instance.AddToManifest(SkillsInfo.GetValue<string>(skillName, "propModel"));
}
public static void NewRound()

View file

@ -1,12 +1,12 @@
using System.Collections.Immutable;
using System.Drawing;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -25,20 +25,20 @@ namespace src.player.skills
"weapon_g3sg1", "weapon_nova", "weapon_xm1014", "weapon_mag7",
"weapon_sawedoff", "weapon_m249", "weapon_negev"
];
private static readonly ConcurrentDictionary<ulong, ConcurrentBag<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
public static void LoadSkill()
{
if (SkillsInfo.LoadedConfig.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true)
return;
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
}
public static void NewRound()
{
foreach (var player in Utilities.GetPlayers())
SetWeaponAttack(player, false);
invisiblePlayers.Clear();
}
public static void WeaponPickup(EventItemPickup @event)
@ -48,7 +48,6 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
if (playerInfo?.Skill != skillName) return;
SetWeaponVisibility(player!, false);
SetWeaponAttack(player!, true);
}
@ -59,7 +58,6 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
if (playerInfo?.Skill != skillName) return;
SetWeaponVisibility(player!, false);
SetWeaponAttack(player!, true);
}
@ -68,32 +66,37 @@ namespace src.player.skills
foreach (var (info, player) in infoList)
{
if (player == null) continue;
foreach ((var playerId, var itemList) in invisibleEntities)
if (player.SteamID != playerId)
foreach (var entityIndex in itemList)
{
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
}
foreach (var _player in invisiblePlayers.Keys)
if (player.SteamID != _player.SteamID)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
public static void EnableSkill(CCSPlayerController player)
{
Event.EnableTransmit();
SetPlayerVisibility(player, false);
SetWeaponVisibility(player, false);
SetWeaponAttack(player, true);
invisiblePlayers.TryAdd(player, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.ResetPrintHTML(player);
SetPlayerVisibility(player, true);
SetWeaponVisibility(player, true);
SetWeaponAttack(player, false);
invisibleEntities.TryRemove(player.SteamID, out _);
invisiblePlayers.TryRemove(player, out _);
}
public static void OnTick()
@ -104,51 +107,30 @@ namespace src.player.skills
if (playerInfo?.Skill == skillName)
UpdateHUD(player);
if (!player.PawnIsAlive)
if (invisibleEntities.ContainsKey(player.SteamID))
invisibleEntities.TryRemove(player.SteamID, out _);
invisiblePlayers.TryRemove(player, out _);
}
}
private static void SetPlayerVisibility(CCSPlayerController player, bool visible)
public static void PlayerHurt(EventPlayerHurt @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player)) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null)
{
var color = visible ? Color.FromArgb(255, 255, 255, 255) : Color.FromArgb(0, 255, 255, 255);
var shadowStrength = visible ? 1.0f : 0.0f;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
playerPawn.Render = color;
playerPawn.ShadowStrength = shadowStrength;
Utilities.SetStateChanged(playerPawn, "CBaseModelEntity", "m_clrRender");
}
}
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!;
if (particle == null) return;
private static void SetWeaponVisibility(CCSPlayerController player, bool visible)
{
if (!Instance.IsPlayerValid(player)) return;
var playerPawn = player.PlayerPawn.Value!;
if (playerPawn.WeaponServices == null) return;
particle.EffectName = bloodParticle;
particle.StartActive = true;
invisibleEntities.TryRemove(player.SteamID, out _);
foreach (var weapon in playerPawn.WeaponServices.MyWeapons)
{
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
{
if (!visible)
{
if (invisibleEntities.TryGetValue(player.SteamID, out var items))
{
if (!items.Contains(weapon.Index))
items.Add(weapon.Index);
}
else
invisibleEntities.TryAdd(player.SteamID, [weapon.Index]);
}
}
}
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
if (visible)
invisibleEntities.TryRemove(player.SteamID, out _);
particle.AcceptInput("Start");
}
private static void SetWeaponAttack(CCSPlayerController player, bool disableWeapon)
@ -188,6 +170,26 @@ namespace src.player.skills
playerInfo.PrintHTML = $"<font color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font>";
}
private static uint? HideBomb(CCSPlayerController player)
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
var bomb = bombEntities.FirstOrDefault();
if (bomb == null) return null;
if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFFFFF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
}

View file

@ -0,0 +1,301 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using System.Numerics;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
public class Iana : ISkill
{
private const Skills skillName = Skills.Iana;
private static readonly ConcurrentDictionary<CCSPlayerController, PlayerSkill> playersInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
foreach (var playerSkill in playersInfo.Values)
KillClone(playerSkill);
lock (setLock)
playersInfo.Clear();
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp == null && playerSkill.NextUse <= Server.TickCount)
CreateClone(playerSkill);
else if (playerSkill.CloneProp != null)
KillClone(playerSkill);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
playersInfo.TryAdd(player, new PlayerSkill
{
Player = player,
CloneProp = null,
NextUse = 0,
UseTime = 0,
});
}
public static void DisableSkill(CCSPlayerController player)
{
if (playersInfo.TryGetValue(player, out var playerSkill))
KillClone(playerSkill);
playersInfo.TryRemove(player, out _);
}
private static void KillClone(PlayerSkill playerSkill)
{
playerSkill.Player.EmitSound("SolidMetal.BulletImpact");
if (playerSkill.CloneProp != null && playerSkill.CloneProp.IsValid && playerSkill.CloneProp.AbsOrigin != null && playerSkill.CloneProp.AbsRotation != null)
{
var playerPawn = playerSkill.Player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
Vector pos = new(playerSkill.CloneProp.AbsOrigin.X, playerSkill.CloneProp.AbsOrigin.Y, playerSkill.CloneProp.AbsOrigin.Z);
QAngle angle = new(playerSkill.CloneProp.AbsRotation.X, playerSkill.CloneProp.AbsRotation.Y, playerSkill.CloneProp.AbsRotation.Z);
Server.NextFrame(() =>
{
playerPawn.Teleport(pos, angle);
});
}
playerSkill.CloneProp.AcceptInput("Kill");
playerSkill.CloneProp = null;
}
SkillUtils.ApplyScreenColor(playerSkill.Player, 0, 0, 0, 0, 10, 0, 2);
BlockWeapon(playerSkill.Player, false);
playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
playerSkill.UseTime = 0;
}
public static void OnTick()
{
foreach (var playerSkill in playersInfo.Values)
UpdateHUD(playerSkill);
}
private static CDynamicProp? CreateClone(PlayerSkill playerSkill)
{
var player = playerSkill.Player;
if (player == null) return null;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return null;
Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * 50;
Vector pos2 = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * (50 + 25);
if (!CheckPosition(player, pos2) || !((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_ONGROUND))
{
playerSkill.InfoTime = Server.TickCount;
return null;
}
var clone = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic");
if (clone == null || !clone.IsValid) return null;
clone.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
clone.Entity!.Name = clone.Globalname = $"IanaClone_{Server.TickCount}_{player.SteamID}";
clone.DispatchSpawn();
Server.NextFrame(() =>
{
clone.SetModel(playerPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
playerPawn.Teleport(pos);
SkillUtils.ApplyScreenColor(player, 255, 255, 0, 20, 100, 1020);
BlockWeapon(playerSkill.Player, true);
playerSkill.UseTime = Server.TickCount;
playerSkill.NextUse = Server.TickCount + 64000;
playerSkill.CloneProp = clone;
jRandomSkills.Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "Duration"), () =>
{
if (playerSkill.CloneProp != null)
KillClone(playerSkill);
});
jRandomSkills.Instance.AddTimer(2f, () => {
if (playerSkill.CloneProp == null)
return;
if (player.IsValid && player.PawnIsAlive)
SkillUtils.ApplyScreenColor(player,
r: 255,
g: 255,
b: 0,
a: 20,
duration: 100,
holdTime: 1020);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
});
return clone;
}
private unsafe static bool CheckPosition(CCSPlayerController player, Vector endPos)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
endPos.Z += 25;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = playerPawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
return !trace.DidHit();
}
public static void OnTakeDamage(DynamicHook h)
{
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || param.Entity == null || param2 == null)
return;
if (string.IsNullOrEmpty(param.Entity.Name)) return;
if (!param.Entity.Name.StartsWith("IanaClone_")) return;
var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID);
if (steamID == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
{
KillClone(playerSkill);
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null)
SkillUtils.TakeHealth(playerPawn, (int)param2.Damage);
}
}
public static void PlayerHurt(EventPlayerHurt @event)
{
var victim = @event.Userid!;
if (!jRandomSkills.Instance.IsPlayerValid(victim)) return;
if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
{
KillClone(playerSkill);
var victimPawn = victim.PlayerPawn.Value;
if (victimPawn == null) return;
SkillUtils.AddHealth(victimPawn, @event.DmgHealth);
}
}
private static void BlockWeapon(CCSPlayerController player, bool block)
{
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
foreach (var weapon in pawn.WeaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
{
weapon.Value.NextPrimaryAttackTick = block ? int.MaxValue : Server.TickCount;
weapon.Value.NextSecondaryAttackTick = block ? int.MaxValue : Server.TickCount;
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
private static void UpdateHUD(PlayerSkill playerSkill)
{
if (playerSkill == null || playerSkill.Player == null) return;
float cooldown = 0;
float time1 = (playerSkill.NextUse - Server.TickCount) / 64;
cooldown = (int)Math.Ceiling(Math.Max(time1, 0));
float duration = 0;
float time2 = SkillsInfo.GetValue<float>(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64;
duration = (int)Math.Ceiling(Math.Max(time2, 0));
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
if (playerInfo == null) return;
if (playerSkill.InfoTime + (64 * 2) > Server.TickCount)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("shade_nospace")}";
else if (cooldown == 0 && duration == 0)
playerInfo.PrintHTML = null;
else if (duration > 0)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#00FF00'>{duration}</font>")}";
else if (cooldown > 0)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
public class PlayerSkill
{
public required CCSPlayerController Player { get; set; }
public CDynamicProp? CloneProp { get; set; }
public float NextUse { get; set; }
public float UseTime { get; set; }
public int InfoTime { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d0d930", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30, float duration = 10) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
public float Duration { get; set; } = duration;
}
}
}

View file

@ -18,7 +18,7 @@ namespace src.player.skills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.ManifestResources.Add(SkillsInfo.GetValue<string>(skillName, "particleName"));
Instance.AddToManifest(SkillsInfo.GetValue<string>(skillName, "particleName"));
}
public static void NewRound()

View file

@ -38,7 +38,8 @@ namespace src.player.skills
SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum);
foreach (var _p in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist && !p.IsBot))
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}", false);
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" };
var randomFile = fileNames[new Random().Next(fileNames.Length)];

View file

@ -1,11 +1,12 @@
using System.Drawing;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -13,18 +14,23 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Ninja;
private static readonly ConcurrentDictionary<nint, float> invisibilityChanged = [];
private static readonly ConcurrentDictionary<ulong, ConcurrentBag<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
}
public static void NewRound()
{
lock (setLock)
{
invisibilityChanged.Clear();
invisiblePlayers.Clear();
}
}
public static void WeaponEquip(EventItemEquip @event)
@ -52,14 +58,22 @@ namespace src.player.skills
foreach (var (info, player) in infoList)
{
if (player == null) continue;
foreach ((var playerId, var itemList) in invisibleEntities)
if (player.SteamID != playerId)
foreach (var entityIndex in itemList)
{
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
}
foreach (var _player in invisiblePlayers.Keys)
if (player.SteamID != _player.SteamID)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
@ -71,8 +85,7 @@ namespace src.player.skills
if (playerInfo?.Skill == skillName)
UpdateNinja(player);
if (!player.PawnIsAlive)
if (invisibleEntities.ContainsKey(player.SteamID))
invisibleEntities.TryRemove(player.SteamID, out _);
invisiblePlayers.TryRemove(player, out _);
}
}
@ -84,8 +97,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SetPlayerVisibility(player, 0);
SetWeaponVisibility(player, 0);
invisibleEntities.TryRemove(player.SteamID, out _);
invisiblePlayers.TryRemove(player, out _);
}
private static void UpdateNinja(CCSPlayerController? player)
@ -110,13 +122,19 @@ namespace src.player.skills
if (!buttons.HasFlag(PlayerButtons.Moveleft) && !buttons.HasFlag(PlayerButtons.Moveright) && !buttons.HasFlag(PlayerButtons.Forward) && !buttons.HasFlag(PlayerButtons.Back) && flags.HasFlag(PlayerFlags.FL_ONGROUND))
percentInvisibility += SkillsInfo.GetValue<float>(skillName, "idlePercentInvisibility");
SetWeaponVisibility(player, percentInvisibility);
if (invisibilityChanged.TryGetValue(player.Handle, out float oldInvisibility))
if (percentInvisibility == oldInvisibility)
return;
invisibilityChanged.TryAdd(player.Handle, percentInvisibility);
SetPlayerVisibility(player, percentInvisibility);
if (percentInvisibility > .9)
invisiblePlayers.TryAdd(player, 0);
else
{
SetPlayerVisibility(player, percentInvisibility);
invisiblePlayers.TryRemove(player, out _);
}
}
private static void SetPlayerVisibility(CCSPlayerController player, float percentInvisibility)
@ -130,30 +148,46 @@ namespace src.player.skills
}
}
private static void SetWeaponVisibility(CCSPlayerController player, float percentInvisibility)
public static void PlayerHurt(EventPlayerHurt @event)
{
if (!Instance.IsPlayerValid(player)) return;
var playerPawn = player.PlayerPawn.Value!;
if (playerPawn.WeaponServices == null) return;
var player = @event.Userid;
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player)) return;
var color = Color.FromArgb(Math.Max(255 - (int)(255 * percentInvisibility * 2), 0), 255, 255, 255);
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
invisibleEntities.TryRemove(player.SteamID, out _);
if (color.A != 0) return;
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!;
if (particle == null) 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.TryAdd(player.SteamID, [weapon.Index]);
}
}
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start");
}
private static uint? HideBomb(CCSPlayerController player)
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
var bomb = bombEntities.FirstOrDefault();
if (bomb == null) return null;
if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dedede", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float idlePercentInvisibility = .3f, float duckPercentInvisibility = .3f, float knifePercentInvisibility = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -40,7 +40,8 @@ namespace src.player.skills
float extraJumps = (float)Instance.Random.Next(SkillsInfo.GetValue<int>(skillName, "extraJumpsMin"), SkillsInfo.GetValue<int>(skillName, "extraJumpsMax") + 1);
playerInfo.SkillChance = extraJumps;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, extraJumps)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, extraJumps)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
private static void GiveAdditionalJump(CCSPlayerController player)

View file

@ -1,3 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -29,7 +30,7 @@ namespace src.player.skills
{
player.Respawn();
Instance.AddTimer(.2f, () => player.Respawn());
SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"), false);
SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"));
}
}
}
@ -41,7 +42,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -1,3 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -37,7 +38,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
private static void PushEnemy(CCSPlayerController player, QAngle attackerAngle)

View file

@ -0,0 +1,292 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using System.Numerics;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
using static src.jRandomSkills;
namespace src.player.skills
{
public class RCMelon : ISkill
{
private const Skills skillName = Skills.RCMelon;
private static readonly ConcurrentDictionary<CCSPlayerController, PlayerSkill> playersInfo = [];
private const string melonProp = "models/cs_italy/italy_food_melon/italy_food_melon.vmdl";
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(melonProp);
}
public static void NewRound()
{
foreach (var playerSkill in playersInfo.Values)
KillClone(playerSkill);
lock (setLock)
playersInfo.Clear();
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
if (playerSkill.CloneProp == null && playerSkill.NextUse <= Server.TickCount)
CreateMelon(playerSkill);
else if (playerSkill.CloneProp != null)
KillClone(playerSkill);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
playersInfo.TryAdd(player, new PlayerSkill
{
Player = player,
CloneProp = null,
NextUse = 0,
UseTime = 0,
PlayerModel = player.PlayerPawn.Value!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName,
});
}
public static void DisableSkill(CCSPlayerController player)
{
if (playersInfo.TryGetValue(player, out var playerSkill))
KillClone(playerSkill);
playersInfo.TryRemove(player, out _);
}
private static void KillClone(PlayerSkill playerSkill)
{
playerSkill.Player.EmitSound("SolidMetal.BulletImpact");
if (playerSkill.CloneProp != null && playerSkill.CloneProp.IsValid && playerSkill.CloneProp.AbsOrigin != null && playerSkill.CloneProp.AbsRotation != null)
{
var playerPawn = playerSkill.Player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
Vector pos = new(playerSkill.CloneProp.AbsOrigin.X, playerSkill.CloneProp.AbsOrigin.Y, playerSkill.CloneProp.AbsOrigin.Z);
QAngle angle = new(playerSkill.CloneProp.AbsRotation.X, playerSkill.CloneProp.AbsRotation.Y, playerSkill.CloneProp.AbsRotation.Z);
Server.NextFrame(() =>
{
playerPawn.Teleport(pos, angle);
});
}
playerSkill.CloneProp.AcceptInput("Kill");
playerSkill.CloneProp = null;
}
BlockWeapon(playerSkill.Player, false);
playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
playerSkill.UseTime = 0;
}
public static void OnTick()
{
foreach (var playerSkill in playersInfo.Values)
UpdateHUD(playerSkill);
}
private static CDynamicProp? CreateMelon(PlayerSkill playerSkill)
{
var player = playerSkill.Player;
if (player == null) return null;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return null;
Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * 50;
Vector pos2 = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * (50 + 25);
if (!CheckPosition(player, pos2) || !((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_ONGROUND))
{
playerSkill.InfoTime = Server.TickCount;
return null;
}
var clone = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic");
if (clone == null || !clone.IsValid) return null;
clone.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
clone.Entity!.Name = clone.Globalname = $"IanaClone_{Server.TickCount}_{player.SteamID}";
clone.DispatchSpawn();
Server.NextFrame(() =>
{
clone.SetModel(playerSkill.PlayerModel);
clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
playerPawn.Teleport(pos);
BlockWeapon(playerSkill.Player, true);
playerSkill.UseTime = Server.TickCount;
playerSkill.NextUse = Server.TickCount + 64000;
playerSkill.CloneProp = clone;
Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "Duration"), () =>
{
if (playerSkill.CloneProp != null)
KillClone(playerSkill);
});
playerPawn.SetModel(melonProp);
});
return clone;
}
private unsafe static bool CheckPosition(CCSPlayerController player, Vector endPos)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
endPos.Z += 25;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = playerPawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
return !trace.DidHit();
}
public static void OnTakeDamage(DynamicHook h)
{
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || param.Entity == null || param2 == null)
return;
if (string.IsNullOrEmpty(param.Entity.Name)) return;
if (!param.Entity.Name.StartsWith("IanaClone_")) return;
var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID);
if (steamID == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player == null) return;
if (playersInfo.TryGetValue(player, out var playerSkill))
{
KillClone(playerSkill);
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null)
SkillUtils.TakeHealth(playerPawn, (int)param2.Damage);
}
}
public static void PlayerHurt(EventPlayerHurt @event)
{
var victim = @event.Userid!;
if (!Instance.IsPlayerValid(victim)) return;
if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
{
KillClone(playerSkill);
var victimPawn = victim.PlayerPawn.Value;
if (victimPawn == null) return;
SkillUtils.AddHealth(victimPawn, @event.DmgHealth);
}
}
private static void BlockWeapon(CCSPlayerController player, bool block)
{
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
foreach (var weapon in pawn.WeaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
{
weapon.Value.NextPrimaryAttackTick = block ? int.MaxValue : Server.TickCount;
weapon.Value.NextSecondaryAttackTick = block ? int.MaxValue : Server.TickCount;
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
private static void UpdateHUD(PlayerSkill playerSkill)
{
if (playerSkill == null || playerSkill.Player == null) return;
float cooldown = 0;
float time1 = (playerSkill.NextUse - Server.TickCount) / 64;
cooldown = (int)Math.Ceiling(Math.Max(time1, 0));
float duration = 0;
float time2 = SkillsInfo.GetValue<float>(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64;
duration = (int)Math.Ceiling(Math.Max(time2, 0));
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
if (playerInfo == null) return;
if (playerSkill.InfoTime + (64 * 2) > Server.TickCount)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("shade_nospace")}";
else if (cooldown == 0 && duration == 0)
playerInfo.PrintHTML = null;
else if (duration > 0)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#00FF00'>{duration}</font>")}";
else if (cooldown > 0)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
public class PlayerSkill
{
public required CCSPlayerController Player { get; set; }
public CDynamicProp? CloneProp { get; set; }
public float NextUse { get; set; }
public float UseTime { get; set; }
public int InfoTime { get; set; }
public string PlayerModel { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d0d930", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30, float duration = 10) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
public float Duration { get; set; } = duration;
}
}
}

View file

@ -83,7 +83,7 @@ namespace src.player.skills
Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int zombieHealth = 200) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int zombieHealth = 250) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int ZombieHealth { get; set; } = zombieHealth;
}

View file

@ -135,7 +135,7 @@ namespace src.player.skills
var attackerTeam = attackerPawn.TeamNum;
var replicaTeam = replica.Globalname.EndsWith("CT") ? 3 : 2;
SkillUtils.TakeHealth(attackerPawn, attackerTeam != replicaTeam ? 15 : 5);
SkillUtils.TakeHealth(attackerPawn, attackerTeam != replicaTeam ? SkillsInfo.GetValue<int>(skillName, "EnemyTeamDamage") : SkillsInfo.GetValue<int>(skillName, "YourTeamDamage"));
}
public class PlayerSkillInfo
@ -145,9 +145,11 @@ namespace src.player.skills
public DateTime Cooldown { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3000b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 15f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3000b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 15f, int yourTeamDamage = 10, int enemyTeamDamage = 20) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
public int YourTeamDamage { get; set; } = yourTeamDamage;
public int EnemyTeamDamage { get; set; } = enemyTeamDamage;
}
}
}

View file

@ -48,7 +48,8 @@ namespace src.player.skills
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public static void DisableSkill(CCSPlayerController player)

View file

@ -1,4 +1,5 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -22,7 +23,8 @@ namespace src.player.skills
float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newScale;
newScale = (float)Math.Round(newScale, 2);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public static void OnTakeDamage(DynamicHook h)

View file

@ -95,7 +95,8 @@ namespace src.player.skills
}
SkillUtils.CreateMenu(player, menuItems);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}", false);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");

View file

@ -96,6 +96,8 @@ namespace src.player.skills
if (camera == null || !camera.IsValid) return 0;
var pawn = player.PlayerPawn.Value;
if (pawn == null) return 0;
Server.NextFrame(() =>
{
camera.SetModel("models/actors/ghost_speaker.vmdl");

View file

@ -5,7 +5,6 @@ using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using System.Reflection.Metadata;
using static src.jRandomSkills;
namespace src.player.skills
@ -135,7 +134,7 @@ namespace src.player.skills
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int SmokeDamage { get; set; } = smokeDamage;
public float SmokeRadius { get; set; } = smokeRadius;

View file

@ -82,7 +82,7 @@ namespace src.player.skills
playerInfo.PrintHTML = SkillUtils.SecondsToTimer(seconds);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int changeRoundTime = 10, string soundEvent = "UIPanorama.sidemenu_select") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int changeRoundTime = 7, string soundEvent = "UIPanorama.sidemenu_select") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int ChangeRoundTime { get; set; } = changeRoundTime;
public string SoundEvent { get; set; } = soundEvent;

View file

@ -20,10 +20,14 @@ namespace src.utils
private static readonly MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int> HEGrenadeProjectile_CreateFunc = new(GameData.GetSignature("HEGrenadeProjectile_CreateFunc"));
private static readonly MemoryFunctionVoid<nint, float, RoundEndReason, nint, nint> TerminateRoundFunc = new(GameData.GetSignature("CCSGameRules_TerminateRound"));
public static void PrintToChat(CCSPlayerController player, string msg, bool isError)
public static void PrintToChat(CCSPlayerController player, string msg, string border = "tb", string title = jRandomSkills.Tag)
{
string checkIcon = isError ? $"{ChatColors.DarkRed}✖{ChatColors.LightRed}" : $"{ChatColors.Green}✔{ChatColors.Lime}";
player.PrintToChat($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} {jRandomSkills.Tag} {ChatColors.Green}] {checkIcon} {msg}");
if (border.Contains('t'))
player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◢◆◤ {title} ◥◆◣{ChatColors.Green}―――――――――――");
if (!string.IsNullOrEmpty(msg))
player.PrintToChat($" {ChatColors.Green} {msg}");
if (border.Contains('b'))
player.PrintToChat($" {ChatColors.Green}―――――――――――――――{new string('―', title.Length)}―――――――――――――――");
}
public static bool IsFreezeTime()
@ -81,7 +85,7 @@ namespace src.utils
{
using var msg = UserMessage.FromPartialName("Fade");
if (msg == null) return;
int packageColor = (a << 24) | (r << 16) | (g << 8) | b;
int packageColor = (a << 24) | (b << 16) | (g << 8) | r;
msg.SetInt("duration", duration);
msg.SetInt("hold_time", holdTime);