Updates & Fixes
# Updates & Fixes - Vote system: Timer now resets after each vote - Automatic copying of gamedata files from source to server (Thanks to vinicius-trev for the help) - Improved power assignment at round start - Observers can now see invisible players. - Added geolocation support for Turkey and Czechia - New power: Illiterate - In development: Smoker skill - Baseball: Decoy now have the same collision as players (PlayerClip) - Noclip: Reworked - Pilot: Currently broken - Replicator: Added crouching animations for replicas - SoundMaker: Reworked (automatically play a sound every 2s (only for you)) - Wallhack: Glow disabled for dead players # TODO - Add/update descriptions for new/reworked skills - Fix Pilot, SniperElite
This commit is contained in:
parent
f76093ef6e
commit
09803748bc
28 changed files with 691 additions and 295 deletions
|
|
@ -1,9 +1,13 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using static src.jRandomSkills;
|
||||
using System.Collections.Concurrent;
|
||||
using CS2TraceRay.Class;
|
||||
using CS2TraceRay.Struct;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
|
|
@ -87,52 +91,139 @@ namespace src.player.skills
|
|||
public static void UseSkill(CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
var duration = SkillsInfo.GetValue<float>(skillName, "duration");
|
||||
if (playerPawn?.CBodyComponent == null) return;
|
||||
|
||||
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
|
||||
{
|
||||
if (!player.IsValid || !player.PawnIsAlive) return;
|
||||
if (skillInfo.IsFlying)
|
||||
{
|
||||
StopFlying(player, skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skillInfo.CanUse)
|
||||
{
|
||||
var duration = SkillsInfo.GetValue<float>(skillName, "duration");
|
||||
|
||||
skillInfo.CanUse = false;
|
||||
skillInfo.IsFlying = true;
|
||||
skillInfo.Cooldown = DateTime.Now;
|
||||
skillInfo.LastPosition = playerPawn.AbsOrigin == null ? null : new Vector(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z);
|
||||
SetNoclip(player, true);
|
||||
skillInfo.Timer?.Kill();
|
||||
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_NOCLIP;
|
||||
Instance.AddTimer(duration, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !skillInfo.IsFlying) return;
|
||||
skillInfo.IsFlying = false;
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK;
|
||||
});
|
||||
|
||||
Instance.AddTimer(duration + 4, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return;
|
||||
if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return;
|
||||
skillInfo.IsFlying = false;
|
||||
var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z);
|
||||
if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z)
|
||||
playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0,0,0));
|
||||
});
|
||||
}
|
||||
else if (skillInfo.IsFlying)
|
||||
{
|
||||
skillInfo.IsFlying = false;
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK;
|
||||
|
||||
Instance.AddTimer(4, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return;
|
||||
if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return;
|
||||
skillInfo.IsFlying = false;
|
||||
var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z);
|
||||
if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z)
|
||||
playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0, 0, 0));
|
||||
skillInfo.Timer = Instance.AddTimer(duration, () =>
|
||||
{
|
||||
StopFlying(player, skillInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetNoclip(CCSPlayerController player, bool noclip = true)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive) return;
|
||||
|
||||
playerPawn.MoveType = noclip ? MoveType_t.MOVETYPE_NOCLIP : MoveType_t.MOVETYPE_WALK;
|
||||
Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType);
|
||||
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_MoveType");
|
||||
}
|
||||
|
||||
private static void StopFlying(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
skillInfo.Timer?.Kill();
|
||||
skillInfo.Timer = null;
|
||||
|
||||
if (!skillInfo.IsFlying) return;
|
||||
skillInfo.IsFlying = false;
|
||||
|
||||
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
|
||||
SetNoclip(player, false);
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || skillInfo.IsFlying) return;
|
||||
|
||||
Vector? safePoint = GetCorrectPosition(player, skillInfo);
|
||||
playerPawn.Teleport(safePoint ?? skillInfo.LastPosition, null, new Vector(0, 0, 0));
|
||||
}
|
||||
|
||||
private static Vector? GetCorrectPosition(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return null;
|
||||
|
||||
Vector currentPos = playerPawn.AbsOrigin;
|
||||
float offset = 50;
|
||||
|
||||
Vector[] checkOffsets =
|
||||
{
|
||||
currentPos,
|
||||
currentPos + new Vector(offset, 0, 10),
|
||||
currentPos + new Vector(-offset, 0, 10),
|
||||
currentPos + new Vector(0, offset, 10),
|
||||
currentPos + new Vector(0, -offset, 10),
|
||||
|
||||
currentPos + new Vector(offset, 0, 60),
|
||||
currentPos + new Vector(-offset, 0, 60),
|
||||
currentPos + new Vector(0, offset, 60),
|
||||
currentPos + new Vector(0, -offset, 60),
|
||||
};
|
||||
|
||||
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = playerPawn.Collision.CollisionGroup;
|
||||
bool hasGround = false;
|
||||
|
||||
foreach (Vector targetPos in checkOffsets)
|
||||
{
|
||||
Vector start = new(targetPos.X, targetPos.Y, targetPos.Z + 70);
|
||||
Vector end = new(targetPos.X, targetPos.Y, targetPos.Z - 1000);
|
||||
|
||||
CGameTrace groundTrace = TraceRay.TraceShape(start, end, mask, contents, player);
|
||||
if (!groundTrace.DidHit()) continue;
|
||||
|
||||
hasGround = true;
|
||||
Vector newPos =
|
||||
groundTrace.EndPos.Z > targetPos.Z
|
||||
? new(groundTrace.EndPos.X, groundTrace.EndPos.Y, groundTrace.EndPos.Z)
|
||||
: targetPos;
|
||||
|
||||
if (IsPositionSafe(newPos, player))
|
||||
return newPos;
|
||||
}
|
||||
|
||||
if (hasGround)
|
||||
skillInfo.Cooldown = DateTime.Now.AddSeconds(-SkillsInfo.GetValue<float>(skillName, "cooldown") + SkillsInfo.GetValue<float>(skillName, "cooldownWhenStuck"));
|
||||
return hasGround ? currentPos : null;
|
||||
}
|
||||
|
||||
private static bool IsPositionSafe(Vector pos, CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
|
||||
|
||||
float footHeight = 0;
|
||||
float headHeight = 70;
|
||||
float innerDist = 12;
|
||||
|
||||
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = playerPawn.Collision.CollisionGroup;
|
||||
|
||||
Vector s1 = new(pos.X - innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e1 = new(pos.X + innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t1 = TraceRay.TraceShape(s1, e1, mask, contents, player);
|
||||
if (t1.DidHit() || t1.AllSolid) return false;
|
||||
|
||||
Vector s2 = new(pos.X + innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e2 = new(pos.X - innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t2 = TraceRay.TraceShape(s2, e2, mask, contents, player);
|
||||
if (t2.DidHit() || t2.AllSolid) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class PlayerSkillInfo
|
||||
{
|
||||
public ulong SteamID { get; set; }
|
||||
|
|
@ -140,11 +231,13 @@ namespace src.player.skills
|
|||
public bool IsFlying { get; set; }
|
||||
public DateTime Cooldown { get; set; }
|
||||
public Vector? LastPosition { get; set; }
|
||||
public Timer? Timer { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f, float cooldownWhenStuck = 5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float Cooldown { get; set; } = cooldown;
|
||||
public float CooldownWhenStuck { get; set; } = cooldownWhenStuck;
|
||||
public float Duration { get; set; } = duration;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue