mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Implemented the Follow Player chat bot.
This commit is contained in:
parent
223c13561c
commit
c7ba5e5fa3
5 changed files with 225 additions and 4 deletions
175
MinecraftClient/ChatBots/FollowPlayer.cs
Normal file
175
MinecraftClient/ChatBots/FollowPlayer.cs
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
public class FollowPlayer : ChatBot
|
||||
{
|
||||
private string? _playerToFollow = null;
|
||||
private int _updateCounter = 0;
|
||||
private int _updateLimit;
|
||||
private int _stopAtDistance;
|
||||
private bool _unsafeEnabled = false;
|
||||
|
||||
public FollowPlayer(int updateLimit = 15, int stopAtDistance = 3)
|
||||
{
|
||||
_updateLimit = updateLimit;
|
||||
_stopAtDistance = stopAtDistance;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
if (!GetEntityHandlingEnabled())
|
||||
{
|
||||
LogToConsoleTranslated("extra.entity_required");
|
||||
LogToConsoleTranslated("general.bot_unload");
|
||||
UnloadBot();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetTerrainEnabled())
|
||||
{
|
||||
LogToConsoleTranslated("extra.terrainandmovement_required");
|
||||
LogToConsoleTranslated("general.bot_unload");
|
||||
UnloadBot();
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterChatBotCommand("follow", "cmd.follow.desc", "follow <player name|stop>", OnFollowCommand);
|
||||
}
|
||||
|
||||
private string OnFollowCommand(string cmd, string[] args)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
{
|
||||
if (args[0].Equals("stop", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (_playerToFollow == null)
|
||||
return Translations.TryGet("cmd.follow.already_stopped");
|
||||
|
||||
_playerToFollow = null;
|
||||
return Translations.TryGet("cmd.follow.stopping");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsValidName(args[0]))
|
||||
return Translations.TryGet("cmd.follow.invalid_name");
|
||||
|
||||
Entity? player = GetEntities().Values.ToList().Find(entity =>
|
||||
entity.Type == EntityType.Player && !string.IsNullOrEmpty(entity.Name) && entity.Name.Equals(args[0], StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (player == null)
|
||||
return Translations.TryGet("cmd.follow.invalid_player");
|
||||
|
||||
if (!CanMoveThere(player.Location))
|
||||
return Translations.TryGet("cmd.follow.cant_reach_player");
|
||||
|
||||
if (_playerToFollow != null && _playerToFollow.Equals(args[0], StringComparison.OrdinalIgnoreCase))
|
||||
return Translations.TryGet("cmd.follow.already_following", _playerToFollow);
|
||||
|
||||
string result = Translations.TryGet(_playerToFollow != null ? "cmd.follow.switched" : "cmd.follow.started", player.Name!);
|
||||
_playerToFollow = args[0].Trim().ToLower();
|
||||
|
||||
LogToConsoleTranslated("cmd.follow.note");
|
||||
|
||||
if (args.Length == 2 && args[1].Equals("-f", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_unsafeEnabled = true;
|
||||
LogToConsoleTranslated("cmd.follow.unsafe_enabled");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return Translations.TryGet("cmd.follow.desc") + ": " + Translations.TryGet("cmd.follow.usage");
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
_updateCounter++;
|
||||
}
|
||||
|
||||
public override void OnEntityMove(Entity entity)
|
||||
{
|
||||
|
||||
if (_updateCounter < _updateLimit)
|
||||
return;
|
||||
|
||||
_updateCounter = 0;
|
||||
|
||||
if (entity.Type != EntityType.Player)
|
||||
return;
|
||||
|
||||
if (_playerToFollow == null || string.IsNullOrEmpty(entity.Name))
|
||||
return;
|
||||
|
||||
if (_playerToFollow != entity.Name.ToLower())
|
||||
return;
|
||||
|
||||
if (!CanMoveThere(entity.Location))
|
||||
return;
|
||||
|
||||
// Stop at specified distance from plater (prevents pushing player around)
|
||||
double distance = Distance(entity.Location, GetCurrentLocation());
|
||||
|
||||
if (distance < _stopAtDistance)
|
||||
return;
|
||||
|
||||
MoveToLocation(entity.Location, _unsafeEnabled);
|
||||
}
|
||||
|
||||
public override void OnEntitySpawn(Entity entity)
|
||||
{
|
||||
if (entity.Type != EntityType.Player)
|
||||
return;
|
||||
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) && _playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsoleTranslated("cmd.follow.player_came_to_the_range", _playerToFollow);
|
||||
LogToConsoleTranslated("cmd.follow.resuming");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEntityDespawn(Entity entity)
|
||||
{
|
||||
if (entity.Type != EntityType.Player)
|
||||
return;
|
||||
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(entity.Name) && _playerToFollow.Equals(entity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsoleTranslated("cmd.follow.player_left_the_range", _playerToFollow);
|
||||
LogToConsoleTranslated("cmd.follow.pausing");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPlayerLeave(Guid uuid, string? name)
|
||||
{
|
||||
if (_playerToFollow != null && !string.IsNullOrEmpty(name) && _playerToFollow.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToConsoleTranslated("cmd.follow.player_left", _playerToFollow);
|
||||
LogToConsoleTranslated("cmd.follow.stopping");
|
||||
_playerToFollow = null;
|
||||
}
|
||||
}
|
||||
|
||||
private double Distance(Location location1, Location location2)
|
||||
{
|
||||
return Math.Sqrt(
|
||||
((location1.X - location2.X) * (location1.X - location2.X)) +
|
||||
((location1.Y - location2.Y) * (location1.Y - location2.Y)) +
|
||||
((location1.Z - location2.Z) * (location1.Z - location2.Z)));
|
||||
}
|
||||
|
||||
private bool CanMoveThere(Location location)
|
||||
{
|
||||
ChunkColumn? chunkColumn = GetWorld().GetChunkColumn(location);
|
||||
|
||||
if (chunkColumn == null || chunkColumn.FullyLoaded == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue