New 0.0.1alpha

This commit is contained in:
MelodyMaster
2025-07-26 13:10:39 +08:00
parent 806866d5e2
commit da6ae3956d
8 changed files with 1242 additions and 33 deletions

View File

@ -1,33 +0,0 @@
using CounterStrikeSharp.API.Core;
namespace NebulaMistCSS
{
public class HelloWorldPlugin : BasePlugin
{
public override string ModuleName => "NebulaMistCSS";
public override string ModuleVersion => "0.0.1";
public override void Load(bool hotReload)
{
Console.WriteLine("Hello World!");
}
}
}

View File

@ -0,0 +1,33 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core.Attributes.Registration;
namespace NebulaMistCSS.Event.PlayerEvents
{
internal class PlayerJoin
{
private readonly NebulaMistCSS _plugin;
public PlayerJoin(NebulaMistCSS plugin)
{
_plugin = plugin;
}
[GameEventHandler]
public HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info)
{
var player = @event.Userid;
if (player != null && player.IsValid && !player.IsBot)
{
// 在聊天框显示欢迎信息
Server.PrintToChatAll($" \x04欢迎 \x03{player.PlayerName} \x04加入Nebulamist服务器");
//运行一个指令
Server.ExecuteCommand($"exec ss");
}
return HookResult.Continue;
}
}
}

View File

@ -0,0 +1,154 @@
//using CounterStrikeSharp.API.Core;
//using CounterStrikeSharp.API;
//using CounterStrikeSharp.API.Modules.Utils;
//using System;
//using System.Collections.Generic;
//using CounterStrikeSharp.API.Modules.Events;
//namespace NebulaMistCSS.Event.ServerEvents
//{
// public class GrenadeChain
// {
// private readonly NebulaMistCSS _plugin;
// private readonly HashSet<ulong> _chainGrenadePlayers = new();
// private readonly HashSet<string> _triggeredGrenades = new();
// public GrenadeChain(NebulaMistCSS plugin)
// {
// _plugin = plugin;
// }
// public HookResult OnPlayerChat(EventPlayerChat @event, GameEventInfo info)
// {
// var player = Utilities.GetPlayerFromUserid(@event.Userid);
// if (player == null || !player.IsValid) return HookResult.Continue;
// string message = @event.Text?.Trim() ?? "";
// if (message.Equals("ls", StringComparison.OrdinalIgnoreCase) ||
// message.Equals("!连锁", StringComparison.OrdinalIgnoreCase))
// {
// ToggleChainGrenades(player);
// return HookResult.Stop;
// }
// return HookResult.Continue;
// }
// private void ToggleChainGrenades(CCSPlayerController player)
// {
// try
// {
// ulong steamId = player.SteamID;
// if (_chainGrenadePlayers.Contains(steamId))
// {
// _chainGrenadePlayers.Remove(steamId);
// player.PrintToChat($" \x04[连锁手雷] \x01已\x02关闭");
// Server.PrintToChatAll($" \x04[连锁手雷] \x03{player.PlayerName} \x01关闭了连锁手雷");
// }
// else
// {
// _chainGrenadePlayers.Add(steamId);
// player.PrintToChat($" \x04[连锁手雷] \x01已\x02开启");
// Server.PrintToChatAll($" \x04[连锁手雷] \x03{player.PlayerName} \x01开启了连锁手雷");
// }
// }
// catch (Exception ex)
// {
// player.PrintToChat($" \x04[连锁手雷] \x01操作失败: {ex.Message}");
// }
// }
// public HookResult OnGrenadeThrown(EventGrenadeThrown @event, GameEventInfo info)
// {
// try
// {
// var player = @event.Userid;
// if (player == null || !player.IsValid) return HookResult.Continue;
// ulong steamId = player.SteamID;
// if (_chainGrenadePlayers.Contains(steamId))
// {
// string grenadeType = @event.Weapon ?? "";
// if (grenadeType.Contains("hegrenade"))
// {
// player.PrintToChat($" \x04[连锁手雷] \x01检测到HE手雷准备连锁");
// // 延迟触发,确保手雷实体已创建
// AddTimer(0.3f, () => {
// TriggerNearbyGrenades();
// });
// }
// }
// }
// catch { }
// return HookResult.Continue;
// }
// private void TriggerNearbyGrenades()
// {
// try
// {
// bool triggered = false;
// // 查找所有HE手雷实体并触发
// var heGrenades = Utilities.FindAllEntitiesByDesignerName<CDynamicProp>("hegrenade_projectile");
// foreach (var grenade in heGrenades)
// {
// if (grenade != null && grenade.IsValid)
// {
// string grenadeId = grenade.Handle.ToString();
// if (!_triggeredGrenades.Contains(grenadeId))
// {
// try
// {
// grenade.AcceptInput("Kill");
// _triggeredGrenades.Add(grenadeId);
// triggered = true;
// }
// catch { }
// }
// }
// }
// if (triggered)
// {
// Server.PrintToChatAll($" \x04[连锁手雷] \x01连锁爆炸已触发!");
// }
// }
// catch (Exception ex)
// {
// Console.WriteLine($"TriggerNearbyGrenades Error: {ex.Message}");
// }
// }
// private void AddTimer(float delay, Action action)
// {
// try
// {
// var timer = new CounterStrikeSharp.API.Modules.Timers.Timer(delay, action);
// }
// catch { }
// }
// public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
// {
// try
// {
// var player = @event.Userid;
// if (player != null && player.IsValid)
// {
// ulong steamId = player.SteamID;
// _chainGrenadePlayers.Remove(steamId);
// }
// }
// catch { }
// return HookResult.Continue;
// }
// }
//}

186
Features/BotController.cs Normal file
View File

@ -0,0 +1,186 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using System.Linq;
using CounterStrikeSharp.API.Modules.Events;
namespace NebulaMistCSS.Features
{
public class BotController
{
private readonly NebulaMistCSS _plugin;
private bool _botsStopped = false; // Bot是否被停止
private int _savedBotQuota = 10;
public BotController(NebulaMistCSS plugin)
{
_plugin = plugin;
}
public HookResult OnPlayerChat(EventPlayerChat @event, GameEventInfo info)
{
var player = Utilities.GetPlayerFromUserid(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
string message = @event.Text?.Trim() ?? "";
// 检查不同的Bot命令
if (message.Equals("bot", StringComparison.OrdinalIgnoreCase))
{
// 切换Bot启用/禁用状态
ToggleBots(player);
return HookResult.Stop;
}
else if (message.Equals("addbot", StringComparison.OrdinalIgnoreCase))
{
// 添加一个Bot
AddOneBot(player);
return HookResult.Stop;
}
else if (message.Equals("botstop", StringComparison.OrdinalIgnoreCase))
{
// 停止/启动Bot移动
ToggleBotMovement(player);
return HookResult.Stop;
}
return HookResult.Continue;
}
private void ToggleBots(CCSPlayerController player)
{
var currentBots = Utilities.GetPlayers().Count(p => p != null && p.IsValid && p.IsBot);
if (currentBots > 0)
{
// 禁用Bot踢出所有Bot
DisableBots();
Server.PrintToChatAll($" \x04[Bot控制] \x03{player.PlayerName} \x01禁用了所有Bot");
player.PrintToChat($" \x04[Bot控制] \x01Bot已禁用");
}
else
{
// 启用Bot添加一个Bot
EnableBots();
Server.PrintToChatAll($" \x04[Bot控制] \x03{player.PlayerName} \x01启用了Bot");
player.PrintToChat($" \x04[Bot控制] \x01已添加一个Bot");
}
}
private void AddOneBot(CCSPlayerController player)
{
try
{
// 随机添加T或CT Bot
var random = new Random();
if (random.Next(2) == 0)
{
Server.ExecuteCommand("bot_add_t");
}
else
{
Server.ExecuteCommand("bot_add_ct");
}
Server.PrintToChatAll($" \x04[Bot控制] \x03{player.PlayerName} \x01添加了一个Bot");
player.PrintToChat($" \x04[Bot控制] \x01成功添加一个Bot");
}
catch (Exception ex)
{
player.PrintToChat($" \x04[Bot控制] \x01添加Bot失败: {ex.Message}");
Console.WriteLine($"[BotController] 添加Bot时出错: {ex.Message}");
}
}
private void ToggleBotMovement(CCSPlayerController player)
{
if (_botsStopped)
{
// 启动Bot移动
ResumeBotMovement();
Server.PrintToChatAll($" \x04[Bot控制] \x03{player.PlayerName} \x01让Bot开始移动");
player.PrintToChat($" \x04[Bot控制] \x01Bot已开始移动");
_botsStopped = false;
}
else
{
// 停止Bot移动
StopBotMovement();
Server.PrintToChatAll($" \x04[Bot控制] \x03{player.PlayerName} \x01让Bot停止移动");
player.PrintToChat($" \x04[Bot控制] \x01Bot已停止移动");
_botsStopped = true;
}
}
private void DisableBots()
{
try
{
// 踢出所有Bot
Server.ExecuteCommand("bot_kick all");
Console.WriteLine("[BotController] 所有Bot已禁用");
}
catch (Exception ex)
{
Console.WriteLine($"[BotController] 禁用Bot时出错: {ex.Message}");
}
}
private void EnableBots()
{
try
{
// 添加一个Bot
AddOneBotToGame();
Console.WriteLine("[BotController] Bot已启用");
}
catch (Exception ex)
{
Console.WriteLine($"[BotController] 启用Bot时出错: {ex.Message}");
}
}
private void AddOneBotToGame()
{
try
{
// 添加一个Bot到游戏中
Server.ExecuteCommand("bot_add");
}
catch (Exception ex)
{
Console.WriteLine($"[BotController] 添加Bot到游戏时出错: {ex.Message}");
}
}
private void StopBotMovement()
{
try
{
// 设置Bot为冻结状态
var bots = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot).ToList();
foreach (var bot in bots)
{
// 给Bot设置冻结状态通过设置移动速度为0
Server.ExecuteCommand($"bot_stop 1");
}
}
catch (Exception ex)
{
Console.WriteLine($"[BotController] 停止Bot移动时出错: {ex.Message}");
}
}
private void ResumeBotMovement()
{
try
{
// 恢复Bot移动
Server.ExecuteCommand($"bot_stop 0");
}
catch (Exception ex)
{
Console.WriteLine($"[BotController] 恢复Bot移动时出错: {ex.Message}");
}
}
}
}

182
Features/KillHealthshot.cs Normal file
View File

@ -0,0 +1,182 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using System;
using System.Collections.Generic;
using CounterStrikeSharp.API.Modules.Events;
namespace NebulaMistCSS.Features
{
public class KillHealthshot
{
private readonly NebulaMistCSS _plugin;
private readonly Dictionary<ulong, int> _playerHealthshots = new();
private readonly Dictionary<ulong, int> _killStreak = new();
public KillHealthshot(NebulaMistCSS plugin)
{
_plugin = plugin;
}
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
{
try
{
var attacker = @event.Attacker;
var victim = @event.Userid;
// 检查攻击者是否有效且不是自己
if (attacker != null && attacker.IsValid && attacker != victim)
{
// 检查是否是玩家击杀(而不是世界伤害等)
if (!attacker.IsBot) // 排除Bot击杀
{
GiveHealthshotReward(attacker);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"KillHealthshot Error: {ex.Message}");
}
return HookResult.Continue;
}
private void GiveHealthshotReward(CCSPlayerController player)
{
try
{
if (player == null || !player.IsValid || !player.PawnIsAlive)
return;
ulong steamId = player.SteamID;
// 增加击杀计数
if (!_killStreak.ContainsKey(steamId))
_killStreak[steamId] = 0;
_killStreak[steamId]++;
// 给予血针奖励
if (!_playerHealthshots.ContainsKey(steamId))
_playerHealthshots[steamId] = 0;
_playerHealthshots[steamId]++;
// 给玩家添加血针(医疗针)
player.GiveNamedItem("weapon_healthshot");
// 通知玩家
player.PrintToChat($" \x04[奖励] \x01击杀获得血针 (+1)");
// 连续击杀奖励
if (_killStreak[steamId] >= 3)
{
player.PrintToChat($" \x04[连杀] \x01{_killStreak[steamId]}连杀! 额外奖励!");
player.GiveNamedItem("weapon_healthshot"); // 额外奖励
_playerHealthshots[steamId]++;
}
// 全服通知(可选)
// Server.PrintToChatAll($" \x04[击杀] \x03{player.PlayerName} \x01获得血针奖励");
}
catch (Exception ex)
{
Console.WriteLine($"GiveHealthshotReward Error: {ex.Message}");
}
}
public HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info)
{
try
{
var attacker = @event.Attacker;
var victim = @event.Userid;
// 如果玩家被伤害但未死亡,重置连杀
if (victim != null && victim.IsValid && victim != attacker)
{
ulong victimSteamId = victim.SteamID;
if (_killStreak.ContainsKey(victimSteamId))
{
_killStreak[victimSteamId] = 0;
}
}
}
catch { }
return HookResult.Continue;
}
public HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info)
{
try
{
var player = @event.Userid;
if (player != null && player.IsValid)
{
ulong steamId = player.SteamID;
// 玩家重生时重置连杀
if (_killStreak.ContainsKey(steamId))
_killStreak[steamId] = 0;
// 可选:重生时给予基础血针
// player.GiveNamedItem("weapon_healthshot");
}
}
catch { }
return HookResult.Continue;
}
public HookResult OnPlayerChat(EventPlayerChat @event, GameEventInfo info)
{
try
{
var player = Utilities.GetPlayerFromUserid(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
string message = @event.Text?.Trim() ?? "";
// 查看当前血针数量
if (message.Equals("!hs", StringComparison.OrdinalIgnoreCase) ||
message.Equals("!healthshot", StringComparison.OrdinalIgnoreCase))
{
ulong steamId = player.SteamID;
int healthshots = _playerHealthshots.ContainsKey(steamId) ? _playerHealthshots[steamId] : 0;
int streak = _killStreak.ContainsKey(steamId) ? _killStreak[steamId] : 0;
player.PrintToChat($" \x04[血针] \x01你有 \x02{healthshots} \x01个血针");
player.PrintToChat($" \x04[连杀] \x01当前连杀: \x02{streak}");
return HookResult.Stop;
}
}
catch { }
return HookResult.Continue;
}
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
{
try
{
var player = @event.Userid;
if (player != null && player.IsValid)
{
ulong steamId = player.SteamID;
// 清理玩家数据
if (_playerHealthshots.ContainsKey(steamId))
_playerHealthshots.Remove(steamId);
if (_killStreak.ContainsKey(steamId))
_killStreak.Remove(steamId);
}
}
catch { }
return HookResult.Continue;
}
}
}

105
Features/MapChanger.cs Normal file
View File

@ -0,0 +1,105 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using System.Text;
using CounterStrikeSharp.API.Modules.Events;
namespace NebulaMistCSS
{
public class MapChanger
{
private readonly NebulaMistCSS _plugin;
private readonly Dictionary<string, string> _mapList = new Dictionary<string, string>
{
// 竞技地图
{"de_dust2", "沙漠迷城"},
{"de_inferno", "炼狱小镇"},
{"de_mirage", "荒漠迷城"},
{"de_nuke", "核子危机"},
{"de_overpass", "死亡游乐园"},
{"de_ancient", "远古遗迹"},
{"de_anubis", "阿努比斯"},
// 休闲地图
{"cs_office", "办公室"},
{"cs_italy", "意大利小镇"},
{"de_train", "列车停放站"},
{"de_shortnuke", "短核子"},
// 死亡竞赛地图
{"de_dust2_se", "沙漠迷城 SE"},
{"ar_shoots", "射击场"},
{"ar_baggage", "行李仓库"}
};
public MapChanger(NebulaMistCSS plugin)
{
_plugin = plugin;
}
public HookResult OnPlayerChat(EventPlayerChat @event, GameEventInfo info)
{
var player = Utilities.GetPlayerFromUserid(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
string message = @event.Text?.Trim() ?? "";
// 检查是否是换图命令
if (message.StartsWith("map", StringComparison.OrdinalIgnoreCase) ||
message.StartsWith("/map", StringComparison.OrdinalIgnoreCase))
{
string[] args = message.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (args.Length > 1)
{
// 如果有参数,检查是否是数字
if (int.TryParse(args[1], out int mapIndex) && mapIndex > 0 && mapIndex <= _mapList.Count)
{
// 获取对应的地图
var mapEntry = _mapList.ElementAt(mapIndex - 1);
string selectedMap = mapEntry.Key;
string mapNameChinese = mapEntry.Value;
Server.ExecuteCommand($"changelevel {selectedMap}");
Server.PrintToChatAll($" \x04[换图系统] \x03{player.PlayerName} \x01选择了地图: \x02{mapNameChinese} ({selectedMap})");
}
else
{
ShowMapList(player);
}
}
else
{
// 显示地图列表
ShowMapList(player);
}
return HookResult.Stop; // 阻止消息显示在聊天中
}
return HookResult.Continue;
}
private void ShowMapList(CCSPlayerController player)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(" \x04======= 地图列表 =======");
sb.AppendLine(" ");
int index = 1;
foreach (var map in _mapList)
{
sb.AppendLine($" \x01{index}. \x03{map.Value} \x01({map.Key})");
index++;
}
sb.AppendLine(" ");
sb.AppendLine($" \x04========================");
sb.AppendLine($" \x01输入 \x02map <编号> \x01来选择地图");
sb.AppendLine($" \x01例如: \x02map 1");
player.PrintToChat(sb.ToString());
}
}
}

View File

@ -0,0 +1,438 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Modules.Utils;
using System;
using System.Collections.Generic;
using System.Drawing;
using CounterStrikeSharp.API.Modules.Events;
namespace NebulaMistCSS.Features
{
public class PlayerInfoDisplay
{
private readonly NebulaMistCSS _plugin;
private readonly Dictionary<ulong, Vector> _playerLastPositions = new();
private readonly Dictionary<ulong, float> _lastParticleTime = new();
private readonly Random _random = new Random();
private readonly List<(CPointWorldText text, float creationTime, ulong ownerSteamId)> _activeParticles = new();
private readonly Dictionary<ulong, bool> _circleEffectEnabled = new(); // 新增:环绕效果开关
private readonly Dictionary<ulong, float> _circleEffectStartTime = new(); // 新增:环绕效果开始时间
private float _lastCleanupTime = 0f;
public PlayerInfoDisplay(NebulaMistCSS plugin)
{
_plugin = plugin;
}
public void OnTick()
{
try
{
float currentTime = Server.CurrentTime;
// 定期清理过期粒子
if (currentTime - _lastCleanupTime > 0.5f)
{
CleanupExpiredParticles(currentTime);
_lastCleanupTime = currentTime;
}
// 清理已完成的粒子
for (int i = _activeParticles.Count - 1; i >= 0; i--)
{
var (textEntity, creationTime, ownerSteamId) = _activeParticles[i];
if (currentTime - creationTime > 1.0f) // 2秒后移除
{
try
{
if (textEntity != null && textEntity.IsValid)
{
textEntity.Remove();
}
}
catch { }
_activeParticles.RemoveAt(i);
}
}
// 处理常规移动粒子和环绕粒子
foreach (var player in Utilities.GetPlayers())
{
if (player == null || !player.IsValid || !player.PawnIsAlive)
continue;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid)
continue;
var playerPos = pawn.AbsOrigin;
if (playerPos == null) continue;
ulong steamId = player.SteamID;
// 常规移动粒子效果
var particlePos = new Vector(playerPos.X, playerPos.Y, playerPos.Z + 0f);
// 更新玩家位置记录
if (!_playerLastPositions.ContainsKey(steamId))
{
_playerLastPositions[steamId] = particlePos;
_lastParticleTime[steamId] = currentTime;
}
var lastPos = _playerLastPositions[steamId];
// 检查是否移动了足够距离或时间间隔
float distance = GetDistance(particlePos, lastPos);
float timeSinceLastParticle = currentTime - (_lastParticleTime.ContainsKey(steamId) ? _lastParticleTime[steamId] : 0);
// 只有在玩家移动时才生成粒子
if (distance > 15.0f || timeSinceLastParticle > 0.15f)
{
GenerateTextParticles(particlePos, currentTime, steamId);
_playerLastPositions[steamId] = particlePos;
_lastParticleTime[steamId] = currentTime;
}
// 处理环绕粒子效果
if (_circleEffectEnabled.ContainsKey(steamId) && _circleEffectEnabled[steamId])
{
GenerateCircleParticles(player, pawn, currentTime, steamId);
}
}
}
catch { }
}
private void GenerateTextParticles(Vector position, float currentTime, ulong ownerSteamId)
{
try
{
// 生成1个彩色文字粒子
int particleCount = _random.Next(1, 1);
for (int i = 0; i < particleCount; i++)
{
// 随机偏移位置
float offsetX = (float)(_random.NextDouble() - 0.5) * 20.0f;
float offsetY = (float)(_random.NextDouble() - 0.5) * 20.0f;
float offsetZ = (float)(_random.NextDouble() * 15.0f);
var particlePos = new Vector(
position.X + offsetX,
position.Y + offsetY,
position.Z + offsetZ
);
// 创建文字粒子
CreateTextParticle(particlePos, currentTime, ownerSteamId);
}
}
catch { }
}
private void GenerateCircleParticles(CCSPlayerController player, CCSPlayerPawn pawn, float currentTime, ulong ownerSteamId)
{
try
{
var playerPos = pawn.AbsOrigin;
if (playerPos == null) return;
// 获取效果开始时间
float startTime = _circleEffectStartTime.ContainsKey(ownerSteamId) ? _circleEffectStartTime[ownerSteamId] : currentTime;
float elapsedTime = currentTime - startTime;
// 生成多个环绕粒子8-12个
int particleCount = 8;
for (int i = 0; i < particleCount; i++)
{
// 计算环绕角度
float angle = (elapsedTime * 300.0f) + (i * (360.0f / particleCount)); // 旋转速度 + 均匀分布
float radius = 25.0f; // 环绕半径
// 计算粒子位置
float radians = angle * (float)(Math.PI / 180.0);
var particlePos = new Vector(
playerPos.X + (float)(Math.Cos(radians) * radius),
playerPos.Y + (float)(Math.Sin(radians) * radius),
playerPos.Z + 30.0f + (float)(Math.Sin(elapsedTime * 2.0f + i) * 20.0f) // 上下浮动
);
// 创建环绕粒子
CreateCircleParticle(particlePos, currentTime, ownerSteamId, i);
}
}
catch { }
}
private void CreateTextParticle(Vector position, float creationTime, ulong ownerSteamId)
{
try
{
// 使用 point_worldtext 创建文字粒子
var textParticle = Utilities.CreateEntityByName<CPointWorldText>("point_worldtext");
if (textParticle != null && textParticle.IsValid)
{
textParticle.DispatchSpawn();
textParticle.MessageText = "*"; // 使用星号作为粒子
textParticle.Color = GetRandomColor(); // 随机颜色
textParticle.FontSize = 40; // 字体大小
textParticle.Enabled = true;
textParticle.Fullbright = true;
textParticle.WorldUnitsPerPx = 0.15f;
textParticle.JustifyHorizontal = PointWorldTextJustifyHorizontal_t.POINT_WORLD_TEXT_JUSTIFY_HORIZONTAL_CENTER;
textParticle.JustifyVertical = PointWorldTextJustifyVertical_t.POINT_WORLD_TEXT_JUSTIFY_VERTICAL_CENTER;
// 设置位置
textParticle.Teleport(position, new QAngle(0, 0, 0), new Vector(0, 0, 0));
// 添加到活动粒子列表,包含所有者信息
_activeParticles.Add((textParticle, creationTime, ownerSteamId));
}
}
catch { }
}
private void CreateCircleParticle(Vector position, float creationTime, ulong ownerSteamId, int particleIndex)
{
try
{
// 使用 point_worldtext 创建环绕粒子
var textParticle = Utilities.CreateEntityByName<CPointWorldText>("point_worldtext");
if (textParticle != null && textParticle.IsValid)
{
textParticle.DispatchSpawn();
textParticle.MessageText = "●"; // 使用实心圆点
textParticle.Color = GetRainbowColor(particleIndex); // 彩虹颜色
textParticle.FontSize = 40; // 较小的字体
textParticle.Enabled = true;
textParticle.Fullbright = true;
textParticle.WorldUnitsPerPx = 0.1f;
textParticle.JustifyHorizontal = PointWorldTextJustifyHorizontal_t.POINT_WORLD_TEXT_JUSTIFY_HORIZONTAL_CENTER;
textParticle.JustifyVertical = PointWorldTextJustifyVertical_t.POINT_WORLD_TEXT_JUSTIFY_VERTICAL_CENTER;
// 设置位置
textParticle.Teleport(position, new QAngle(0, 0, 0), new Vector(0, 0, 0));
// 添加到活动粒子列表
_activeParticles.Add((textParticle, creationTime, ownerSteamId));
}
}
catch { }
}
private Color GetRandomColor()
{
// 生成五颜六色的粒子颜色
int colorType = _random.Next(6);
return colorType switch
{
0 => Color.Red,
1 => Color.Green,
2 => Color.Blue,
3 => Color.Yellow,
4 => Color.Magenta,
5 => Color.Cyan,
_ => Color.White
};
}
private Color GetRainbowColor(int index)
{
// 生成彩虹色
int hue = (index * 36) % 360; // 每个粒子不同的色调
return HslToRgb(hue, 100, 50);
}
private Color HslToRgb(int hue, int saturation, int lightness)
{
// 简单的HSL到RGB转换
float h = hue / 360.0f;
float s = saturation / 100.0f;
float l = lightness / 100.0f;
if (s == 0)
{
int gray = (int)(l * 255);
return Color.FromArgb(gray, gray, gray);
}
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
float p = 2 * l - q;
int r = (int)(HueToRgb(p, q, h + 1.0f / 3.0f) * 255);
int g = (int)(HueToRgb(p, q, h) * 255);
int b = (int)(HueToRgb(p, q, h - 1.0f / 3.0f) * 255);
return Color.FromArgb(r, g, b);
}
private float HueToRgb(float p, float q, float t)
{
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1.0f / 6.0f) return p + (q - p) * 6 * t;
if (t < 1.0f / 2.0f) return q;
if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6;
return p;
}
private void CleanupExpiredParticles(float currentTime)
{
try
{
// 清理无效粒子引用
_activeParticles.RemoveAll(item =>
item.text == null || !item.text.IsValid);
}
catch { }
}
private float GetDistance(Vector pos1, Vector pos2)
{
try
{
float dx = pos1.X - pos2.X;
float dy = pos1.Y - pos2.Y;
float dz = pos1.Z - pos2.Z;
return (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
}
catch
{
return 0f;
}
}
private void RemovePlayerParticles(ulong steamId)
{
try
{
// 移除指定玩家的所有粒子
for (int i = _activeParticles.Count - 1; i >= 0; i--)
{
var (textEntity, creationTime, ownerSteamId) = _activeParticles[i];
if (ownerSteamId == steamId)
{
try
{
if (textEntity != null && textEntity.IsValid)
{
textEntity.Remove();
}
}
catch { }
_activeParticles.RemoveAt(i);
}
}
// 清理玩家位置数据
if (_playerLastPositions.ContainsKey(steamId))
_playerLastPositions.Remove(steamId);
if (_lastParticleTime.ContainsKey(steamId))
_lastParticleTime.Remove(steamId);
// 清理环绕效果数据
if (_circleEffectEnabled.ContainsKey(steamId))
_circleEffectEnabled.Remove(steamId);
if (_circleEffectStartTime.ContainsKey(steamId))
_circleEffectStartTime.Remove(steamId);
}
catch { }
}
// 新增:处理聊天命令
public HookResult OnPlayerChat(EventPlayerChat @event, GameEventInfo info)
{
try
{
var player = Utilities.GetPlayerFromUserid(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
string message = @event.Text?.Trim() ?? "";
// 处理环绕粒子命令
if (message.Equals("cd", StringComparison.OrdinalIgnoreCase))
{
ToggleCircleEffect(player);
return HookResult.Stop;
}
}
catch { }
return HookResult.Continue;
}
private void ToggleCircleEffect(CCSPlayerController player)
{
try
{
ulong steamId = player.SteamID;
if (_circleEffectEnabled.ContainsKey(steamId) && _circleEffectEnabled[steamId])
{
// 关闭环绕效果
_circleEffectEnabled[steamId] = false;
player.PrintToChat($" \x04[粒子效果] \x01环绕粒子已\x02关闭");
Server.PrintToChatAll($" \x04[粒子效果] \x03{player.PlayerName} \x01关闭了环绕粒子");
}
else
{
// 开启环绕效果
_circleEffectEnabled[steamId] = true;
_circleEffectStartTime[steamId] = Server.CurrentTime; // 记录开始时间
player.PrintToChat($" \x04[粒子效果] \x01环绕粒子已\x02开启");
Server.PrintToChatAll($" \x04[粒子效果] \x03{player.PlayerName} \x01开启了环绕粒子");
}
}
catch (Exception ex)
{
player.PrintToChat($" \x04[粒子效果] \x01操作失败: {ex.Message}");
}
}
public HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info)
{
try
{
var player = @event.Userid;
if (player != null && player.IsValid)
{
RemovePlayerParticles(player.SteamID);
}
}
catch { }
return HookResult.Continue;
}
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
{
try
{
var player = @event.Userid;
if (player != null && player.IsValid)
{
// 玩家死亡时清除该玩家的所有粒子
RemovePlayerParticles(player.SteamID);
}
}
catch { }
return HookResult.Continue;
}
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
{
try
{
var player = @event.Userid;
if (player != null && player.IsValid)
{
RemovePlayerParticles(player.SteamID);
}
}
catch { }
return HookResult.Continue;
}
}
}

144
Main.cs Normal file
View File

@ -0,0 +1,144 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Events;
using Microsoft.Extensions.Logging;
using NebulaMistCSS.Event.PlayerEvents;
//using NebulaMistCSS.Event.ServerEvents;
using NebulaMistCSS.Features;
using static CounterStrikeSharp.API.Core.Listeners;
namespace NebulaMistCSS
{
public class NebulaMistCSS : BasePlugin
{
//事件名定义
//{
//注册玩家加入事件的定义
//{
private PlayerJoin _playerJoin;
//}
//换图事件的定义
//{
private MapChanger _mapChanger;
//机器人事件的定义
//{
private BotController _botController;
//}
//浮游信息事件的定义
//{
private PlayerInfoDisplay _playerInfoDisplay;
//}
//击杀回血事件的定义
//{
private KillHealthshot _killHealthshot;
//}
////手雷连锁事件的定义
////{
//private GrenadeChain _grenadeChain;
////}
public override string ModuleName => "NebulaMistCSS";
public override string ModuleVersion => "0.0.1a";
public override void Load(bool hotReload)
{
Server.ExecuteCommand("sv_enablebunnyhopping 0");
Server.ExecuteCommand("sv_autobunnyhopping 0");
Server.ExecuteCommand("sv_airaccelerate 100");
Server.ExecuteCommand("sv_accelerate 5.5");
Server.ExecuteCommand("sv_friction 5.2");
Server.ExecuteCommand("sv_maxspeed 320");
Server.ExecuteCommand("sv_staminajumpcost 1");
Server.ExecuteCommand("sv_staminalandcost 1");
//控制台显示
Console.WriteLine("Nebulamist CSS已加载");
//写入日志
Logger.LogInformation("Nebulamist CSS已加载");
//注册玩家加入事件
//{
_playerJoin = new PlayerJoin(this);
RegisterEventHandler<EventPlayerConnectFull>(_playerJoin.OnPlayerConnectFull);
//}
//换图的事件
//{
_mapChanger = new MapChanger(this);
RegisterEventHandler<EventPlayerChat>(_mapChanger.OnPlayerChat);
//}
//机器人的事件
//{
_botController = new BotController(this);
RegisterEventHandler<EventPlayerChat>(_botController.OnPlayerChat);
//}
//浮游信息的事件
//{
_playerInfoDisplay = new PlayerInfoDisplay(this);
RegisterEventHandler<EventPlayerSpawn>(_playerInfoDisplay.OnPlayerSpawn);
RegisterEventHandler<EventPlayerDeath>(_playerInfoDisplay.OnPlayerDeath);
RegisterListener<OnTick>(_playerInfoDisplay.OnTick);
RegisterEventHandler<EventPlayerChat>(_playerInfoDisplay.OnPlayerChat);
//}
//击杀回血的事件
//{
_killHealthshot = new KillHealthshot(this);
RegisterEventHandler<EventPlayerChat>(_killHealthshot.OnPlayerChat); // 血针功能
RegisterEventHandler<EventPlayerDeath>(_killHealthshot.OnPlayerDeath);
RegisterEventHandler<EventPlayerHurt>(_killHealthshot.OnPlayerHurt);
RegisterEventHandler<EventPlayerSpawn>(_killHealthshot.OnPlayerSpawn);
RegisterEventHandler<EventPlayerDisconnect>(_killHealthshot.OnPlayerDisconnect);
//}
////手雷连锁事件的事件
////{
//_grenadeChain = new GrenadeChain(this);
//RegisterEventHandler<EventPlayerChat>(_grenadeChain.OnPlayerChat); // 连锁手雷
//RegisterEventHandler<EventGrenadeThrown>(_grenadeChain.OnGrenadeThrown); // 手雷投掷事件
//RegisterEventHandler<EventPlayerDisconnect>(_grenadeChain.OnPlayerDisconnect);
////}
}
public override void Unload(bool hotReload)
{
//控制台显示
Console.WriteLine("Nebulamist CSS已卸载");
//写入日志
Logger.LogInformation("Nebulamist CSS已卸载");
}
}
}