Sboku/FindNearestAlivePlayerCondition.cs
using Sandbox;
using Sandbox.Sboku;
using Sandbox.Sboku.Shared;
using Sandbox.Shared;
using SWB.Demo;
using SWB.Player;
using SWB.Shared;
using System.Linq;
using System.Numerics;
using static Sandbox.PhysicsContact;
public sealed class FindNearestAlivePlayerCondition : ISbokuCondition
{
private readonly SbokuBase bot;
public FindNearestAlivePlayerCondition(SbokuBase bot)
{
this.bot = bot;
}
public bool If()
{
//Log.Info($"[BOT {((BotAdapter)bot).BotIndex}] Condition.If() called");
var players = Game.ActiveScene.GetAllComponents<IPlayerBase>()
.Where(p => p.IsAlive && p.IsValid && p is not BotAdapter)
.ToList();
//Log.Info($"[BOT {((BotAdapter)bot).BotIndex}] Alive players found: {players.Count}");
return players.Count > 0;
}
public void Then()
{
IPlayerBase best = null;
float bestDist = float.MaxValue;
var players = Game.ActiveScene.GetAllComponents<IPlayerBase>()
.Where(p => p.IsAlive && p.IsValid && p is not BotAdapter)
.ToList();
if (players.Count == 0)
{
Log.Info($"[BOT {((BotAdapter)bot).BotIndex}] Then(): NO PLAYERS");
return;
}
foreach (var player in players)
{
float dist = Vector3.DistanceBetween(
bot.EyePos,
player.EyePos
);
if (dist < bestDist && dist < bot.SearchRange)
{
bestDist = dist;
best = player;
}
}
if (best is ISbokuTarget tgt)
bot.Target = tgt;
//Log.Info($"[BOT {((BotAdapter)bot).BotIndex}] TARGET SET -> {best.GameObject.Id}");
}
public bool IsTerminal() => false; // bot.Target != null;
}