2020-03-23 19:59:00 +08:00
|
|
|
|
using MinecraftClient.Mapping;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MinecraftClient.ChatBots
|
|
|
|
|
|
{
|
2020-03-28 00:48:41 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The AutoAttack bot will automatically attack any hostile mob close to the player
|
|
|
|
|
|
/// </summary>
|
2020-03-23 19:59:00 +08:00
|
|
|
|
class AutoAttack : ChatBot
|
|
|
|
|
|
{
|
|
|
|
|
|
private Dictionary<int, Entity> entitiesToAttack = new Dictionary<int, Entity>(); // mobs within attack range
|
|
|
|
|
|
private int attackCooldown = 6;
|
|
|
|
|
|
private int attackCooldownCounter = 6;
|
|
|
|
|
|
private Double attackSpeed = 4;
|
|
|
|
|
|
private Double attackCooldownSecond;
|
|
|
|
|
|
private int attackRange = 4;
|
|
|
|
|
|
private Double serverTPS;
|
2020-04-24 09:02:51 +12:00
|
|
|
|
private float health = 100;
|
2020-03-23 19:59:00 +08:00
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!GetEntityHandlingEnabled())
|
|
|
|
|
|
{
|
2020-04-01 21:15:35 +02:00
|
|
|
|
LogToConsole("Entity Handling is not enabled in the config file!");
|
|
|
|
|
|
LogToConsole("This bot will be unloaded.");
|
2020-03-23 19:59:00 +08:00
|
|
|
|
UnloadBot();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Update()
|
|
|
|
|
|
{
|
2020-04-24 22:14:30 +02:00
|
|
|
|
if (AutoEat.Eating | health == 0)
|
|
|
|
|
|
return;
|
2020-04-24 09:02:51 +12:00
|
|
|
|
|
|
|
|
|
|
if (attackCooldownCounter == 0)
|
2020-03-23 19:59:00 +08:00
|
|
|
|
{
|
2020-04-24 09:02:51 +12:00
|
|
|
|
attackCooldownCounter = attackCooldown;
|
|
|
|
|
|
if (entitiesToAttack.Count > 0)
|
2020-03-23 19:59:00 +08:00
|
|
|
|
{
|
2020-04-26 11:38:03 +12:00
|
|
|
|
foreach (KeyValuePair<int, Entity> entity in entitiesToAttack)
|
2020-03-23 19:59:00 +08:00
|
|
|
|
{
|
2020-04-26 11:38:03 +12:00
|
|
|
|
// check that we are in range once again.
|
|
|
|
|
|
bool shouldAttack = handleEntity(entity.Value);
|
|
|
|
|
|
if (shouldAttack)
|
|
|
|
|
|
{
|
|
|
|
|
|
// hit the entity!
|
|
|
|
|
|
InteractEntity(entity.Key, 1);
|
|
|
|
|
|
}
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-04-24 09:02:51 +12:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
attackCooldownCounter--;
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnEntitySpawn(Entity entity)
|
|
|
|
|
|
{
|
2020-04-23 22:17:20 +12:00
|
|
|
|
handleEntity(entity);
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
2020-04-24 22:14:30 +02:00
|
|
|
|
|
2020-03-24 15:03:32 +08:00
|
|
|
|
public override void OnEntityDespawn(Entity entity)
|
2020-03-23 19:59:00 +08:00
|
|
|
|
{
|
2020-04-23 22:17:20 +12:00
|
|
|
|
if (entitiesToAttack.ContainsKey(entity.ID))
|
2020-03-23 19:59:00 +08:00
|
|
|
|
{
|
2020-04-23 22:17:20 +12:00
|
|
|
|
entitiesToAttack.Remove(entity.ID);
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-04-24 22:14:30 +02:00
|
|
|
|
|
2020-03-23 19:59:00 +08:00
|
|
|
|
public override void OnEntityMove(Entity entity)
|
|
|
|
|
|
{
|
2020-04-23 22:17:20 +12:00
|
|
|
|
handleEntity(entity);
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-24 09:02:51 +12:00
|
|
|
|
public override void OnHealthUpdate(float health, int food)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.health = health;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-23 19:59:00 +08:00
|
|
|
|
public override void OnPlayerProperty(Dictionary<string, double> prop)
|
|
|
|
|
|
{
|
|
|
|
|
|
// adjust auto attack cooldown for maximum attack damage
|
|
|
|
|
|
if (prop.ContainsKey("generic.attackSpeed"))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (attackSpeed != prop["generic.attackSpeed"])
|
|
|
|
|
|
{
|
2020-03-31 19:03:08 +08:00
|
|
|
|
serverTPS = GetServerTPS();
|
2020-03-23 19:59:00 +08:00
|
|
|
|
attackSpeed = prop["generic.attackSpeed"];
|
|
|
|
|
|
attackCooldownSecond = 1 / attackSpeed * (serverTPS / 20.0); // server tps will affect the cooldown
|
|
|
|
|
|
attackCooldown = Convert.ToInt32(Math.Truncate(attackCooldownSecond / 0.1) + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnServerTpsUpdate(double tps)
|
|
|
|
|
|
{
|
|
|
|
|
|
serverTPS = tps;
|
|
|
|
|
|
// re-calculate attack speed
|
|
|
|
|
|
attackCooldownSecond = 1 / attackSpeed * (serverTPS / 20.0); // server tps will affect the cooldown
|
|
|
|
|
|
attackCooldown = Convert.ToInt32(Math.Truncate(attackCooldownSecond / 0.1) + 1);
|
|
|
|
|
|
}
|
2020-04-23 22:17:20 +12:00
|
|
|
|
|
2020-04-26 11:38:03 +12:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Checks to see if the entity should be attacked. If it should be attacked, it will add the entity
|
|
|
|
|
|
/// To a list of entities to attack every few ticks.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="entity">The entity to handle</param>
|
|
|
|
|
|
/// <returns>If the entity should be attacked</returns>
|
|
|
|
|
|
public bool handleEntity(Entity entity)
|
2020-04-23 22:17:20 +12:00
|
|
|
|
{
|
2020-05-24 18:21:22 +02:00
|
|
|
|
if (!entity.Type.IsHostile())
|
2020-04-26 11:38:03 +12:00
|
|
|
|
return false;
|
2020-04-23 22:17:20 +12:00
|
|
|
|
|
|
|
|
|
|
bool isBeingAttacked = entitiesToAttack.ContainsKey(entity.ID);
|
|
|
|
|
|
if (GetCurrentLocation().Distance(entity.Location) < attackRange)
|
|
|
|
|
|
{
|
|
|
|
|
|
// check to see if entity has not been marked as tracked, and if not, track it.
|
|
|
|
|
|
if (!isBeingAttacked)
|
|
|
|
|
|
{
|
|
|
|
|
|
entitiesToAttack.Add(entity.ID, entity);
|
|
|
|
|
|
}
|
2020-04-26 11:38:03 +12:00
|
|
|
|
|
|
|
|
|
|
return true;
|
2020-04-24 22:14:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2020-04-23 22:17:20 +12:00
|
|
|
|
{
|
|
|
|
|
|
// remove marker on entity to attack it, as it is now out of range
|
|
|
|
|
|
if (isBeingAttacked)
|
|
|
|
|
|
{
|
|
|
|
|
|
entitiesToAttack.Remove(entity.ID);
|
|
|
|
|
|
}
|
2020-04-26 11:38:03 +12:00
|
|
|
|
|
|
|
|
|
|
return false;
|
2020-04-23 22:17:20 +12:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-03-23 19:59:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|