using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using Zeta;
using Zeta.Common;
using Zeta.CommonBot;
using Zeta.Common.Plugins;
using Zeta.Internals;
using Zeta.Internals.Actors;
using Zeta.Internals.Service;
namespace Eax.Plugins
{
public class Unstucker2 : IPlugin
{
// Settings
private static int CheckTime = 12; // Maximum time between checks in seconds (default: 40)
private static int Distance = 30; // Distance in yards that should be traveld within CheckTime (default:10)
private static int MaxStuckCount = 3; // Maximum allowed time for the but to try a unstucking routine
// advanced Settings
private static bool bDecreaseCount = true; // Decrease our stuck counter by 1 after each successful CheckTime period (false will reset it to 0)
private static int NeededLoggedPositions = 5; // how many logged positions are needed before checking stuck again (default: 5)
private static int PositionLoggingInterval = 2; // in seconds (default: 3)
private static int MaxRandomMoves = 4; // Maximum tries for doing the random move loop (preventing inf loop problem)
// Dont add below here
private bool IsRestarting { get; set; }
private bool IsChecking { get; set; }
private DateTime LastCheckTime { get; set; }
private DateTime LastLogTime { get; set; }
private DateTime ThisFightTime { get; set; }
private string LastUnitID { get; set; }
private List<Vector3> LoggedPositions { get; set; }
private int StuckCount { get; set; }
private DateTime LastStuckTime { get; set; }
public string Author { get { return "eax"; } }
public string Description { get { return "This is a modified version on Unstucker v1.8 from eax"; } }
public string Name { get { return "Unstucker2 v" + Version.ToString(); } }
public Version Version { get { return new Version(2, 0); } }
public Window DisplayWindow { get { return null; } }
private void Log(string message)
{
Logging.Write(string.Format("[{0}] {1}", Name, message));
}
private static float GetMaxDistanceTraveled(List<Vector3> positions)
{
float max = 0F;
for (int i = 0; i < positions.Count - 1; ++i)
for (int j = 1; j < positions.Count; ++j)
max = Math.Max(max, Math.Abs(positions[i].Distance(positions[j])));
return max;
}
public void OnInitialize()
{
StuckCount = 0;
IsRestarting = false;
IsChecking = false;
LastCheckTime = DateTime.Now;
LastLogTime = DateTime.Now;
LoggedPositions = new List<Vector3>();
}
public void OnPulse()
{
// if we're not in game and not in the process of restarting, do nothing
if (!ZetaDia.IsInGame || !ZetaDia.Me.IsValid || IsRestarting)
{
LastCheckTime = DateTime.Now;
LastLogTime = DateTime.Now;
LoggedPositions.Clear();
StuckCount = 0;
return;
}
// if it's been 3 seconds since we've logged a position, then we log a new position
if (DateTime.Now.Subtract(LastLogTime).TotalSeconds > PositionLoggingInterval)
{
LastLogTime = DateTime.Now;
LoggedPositions.Add(ZetaDia.Actors.Me.Position);
}
// if it's been 40 seconds since we've last evaluated the logged positions, evaluate the logged positions
if (!IsChecking && (LoggedPositions.Count > NeededLoggedPositions) && (DateTime.Now.Subtract(LastCheckTime).TotalSeconds > CheckTime))
{
// we want to prevent this section from being executed twice
IsChecking = true;
var rnd = new Random();
var algorithm = rnd.Next(0, 10);
// if our person has not traveled 10 yards or whatever in the last 40 seconds, we're stuck
if (GetMaxDistanceTraveled(LoggedPositions) < Distance)
{
/*if (CombatTargeting.Instance.FirstNpc.IsValid && (CombatTargeting.Instance.FirstNpc.Distance < 15f))
{
Log("Looks like we are fighting at this position");
IsChecking = false;
LastCheckTime = DateTime.Now;
LastLogTime = DateTime.Now;
LoggedPositions.Clear();
return;
}*/
IsRestarting = true;
StuckCount++;
Log("Your character has not moved "+Distance+" yards for "+CheckTime+" seconds - Trying unstuck routine. (" + StuckCount + "/"+ MaxStuckCount +")");
if (StuckCount > MaxStuckCount)
{ // Restart bot
Log("Looks like we cant unstuck ourselfs by moving randomly");
Log("Leaving Game");
while (ZetaDia.IsInGame)
{
ZetaDia.Service.Games.LeaveGame();
IsRestarting = false;
StuckCount = 0;
LastCheckTime = DateTime.Now;
LastLogTime = DateTime.Now;
LoggedPositions.Clear();
Thread.Sleep(10000);
}
}
else
{
// Thanks Nuls
var v = ZetaDia.Me.Position;
var oldPosition = v;
int i = 0;
do
{
i++;
if (i > MaxRandomMoves)
break;
v.X = (DateTime.Now.Millisecond % 2 == 0) ? v.X + rnd.Next(500, 6500) : v.X - rnd.Next(500, 6500);
v.Y = (DateTime.Now.Millisecond % 2 == 0) ? v.Y + rnd.Next(500, 6500) : v.Y - rnd.Next(500, 6500);
v.Z = (DateTime.Now.Millisecond % 2 == 0) ? v.Z + rnd.Next(500, 6500) : v.Z - rnd.Next(500, 6500);
Log("Moving Char randomly to: " + v.ToString() + " (" + i + "/" + MaxRandomMoves + ")");
ZetaDia.Me.UsePower(SNOPower.Walk, v, ZetaDia.Me.WorldDynamicId, 2, -1);
Thread.Sleep(rnd.Next(2000, 3000)); // HI DB Devs!
} while (ZetaDia.Me.Position == oldPosition);
}
IsRestarting = false;
} // if (GetMaxDistanceTraveled(LoggedPositions) < 10f)
else
{
// decrease stuck count by 1 on successful run
if (bDecreaseCount && StuckCount > 0)
{
StuckCount--;
Log("Decreasing StuckCount (" + StuckCount + "/" + MaxStuckCount + ") Looks like we are moving again");
}
else // reset our stuck counter
StuckCount = 0;
}
IsChecking = false;
LastCheckTime = DateTime.Now;
LastLogTime = DateTime.Now;
LoggedPositions.Clear();
}
}
public void OnShutdown()
{
}
public void OnEnabled()
{
Log("Enabled.");
}
public void OnDisabled()
{
Log("Disabled.");
}
public bool Equals(IPlugin other)
{
return (other.Name == Name) && (other.Version == Version);
}
}
}