Releases: Arcitectus/Timon
Releases · Arcitectus/Timon
release v16.02.21
sample script:
// This script searches for objects by color and attacks if the "Attack" action is offered when the mouse is moved over the object.
using System;
using SmartNet.Extension;
using Timon;
using Bib3.Geometrik;
var colorToAttackR = 37;
var colorToAttackG = 31;
var colorToAttackB = 18;
var colorToAttackTolerance = 5;
var viewportRect = new RectInt(26, 4, 520, 338);
var charSelfHealthBarRegion = RectInt.FromCenterAndSize(viewportRect.Center(), new Vektor2DInt(60, 60));
var findTextAttackTolerance = 0x40;
/// <summary>
/// The "Att" from "Attack" taken from a screenshot.
/// </summary>
static readonly string[] setPatternAttackGreySerial = new[] {
@"iVBORw0KGgoAAAANSUhEUgAAABUAAAALCAYAAACQy8Z9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOBs0TtgAAABuSURBVDhPlc1BDoBACENR7n9CbqOiA0Hsn8RFjXmtaO6eOVq6/06+3MfMjA4rQ68iDq6jalybZuhUTFMb9CpU5tGWPCC9ijiQ6RYj2KC/ioCVaWqDTsU0tUGnYpraoFOBtpIm/XlcH3/+trG9u51ieVj37ZfS5AAAAABJRU5ErkJggg==",
@"iVBORw0KGgoAAAANSUhEUgAAABUAAAALCAYAAACQy8Z9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOBs0TtgAAABxSURBVDhPxZDBDcAwCAPZf0K2oSIC5IJpn3lYig5zSiKqmjEI8jVmRnkejkxENjFjKR2zgi4MKStWB9hLirNtoTPW+ZeydClkSCHz+SEq5qWlM25aQejFSGesc+lPb0iLRQ4L6Zgd6MtN8MmSgxRmYg8fIF3+RpmKeAAAAABJRU5ErkJggg==",
@"iVBORw0KGgoAAAANSUhEUgAAABUAAAALCAYAAACQy8Z9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOBs0TtgAAABuSURBVDhP1c5BDoAwCARA/v9CfoPSAFkoVOPNw6btBFaJmT0CQScRSe8n98sqI6K22JZfe6AWWuk2iMswM3qL1T6XdulKIaOnL3nQdKj+kWfyhPep783qstrJW6z2u9Jwy+gLdbmUJoPlcE3vJBdUb2MFrXWxUgAAAABJRU5ErkJggg==",
};
var setPatternAttackRaster = setPatternAttackGreySerial.Select(serial => Convert.FromBase64String(serial).RasterORGBFromFile()).ToArray();
var setPatternAttackPredicate = setPatternAttackRaster.Select(raster => raster.Value.RasterMatchAtOffsetPredicateBinary(findTextAttackTolerance)).ToArray();
var findColorPredicate = RasterImagePatternMatch.ColorAtOffsetPredicateBinary(colorToAttackR, colorToAttackG, colorToAttackB, colorToAttackTolerance);
var smartSession = Timon.SmartSession;
var findTextAttack = new Func<KeyValuePair<UInt32[], int>, RectInt, IEnumerable<Vektor2DInt>>((raster, region) =>
setPatternAttackPredicate.Select(pattern => raster.FindSetMatchInRegion(pattern, region))
.ConcatNullable());
var healthBarPredicate = RasterImagePatternMatch.HealthBarAtOffsetPredicateBinary();
var getTime = new Func<Int64>(Host.GetTimeContinuousMilli);
int randomInt() => new Random((int)getTime()).Next();
Int64 healthBarLastSeenTime = 0;
for(;;)
{
try
{
var screenshot = smartSession.TakeImageRaster();
if (!screenshot.HasValue)
continue;
if (!screenshot.Value.FindSetMatchInRegion(healthBarPredicate, charSelfHealthBarRegion).IsNullOrEmpty())
healthBarLastSeenTime = getTime();
var healthBarLastSeenAge = (getTime() - healthBarLastSeenTime) / 1000;
Host.Log("health bar last seen age: " + healthBarLastSeenAge);
if (healthBarLastSeenAge < 5)
continue; // assume we are still in a fight, therefore just wait.
var colorSetMatchLocation =
screenshot.Value.FindSetMatchInRegion(findColorPredicate, viewportRect)?.ToArray();
if (!(0 < colorSetMatchLocation?.Length))
continue;
// pick a random pixel of the set of pixel matching the color.
var testLocation =
colorSetMatchLocation?.CastToNullable()
?.ElementAtOrDefault(randomInt() % colorSetMatchLocation.Length);
if (!testLocation.HasValue)
continue; // no pixel in the searched region matches the color description.
smartSession.MouseMove((int)testLocation.Value.A, (int)testLocation.Value.B);
Host.Delay(333);
screenshot = smartSession.TakeImageRaster();
if (!screenshot.HasValue)
continue;
// search for Attack text in the upper left.
var mouseOverAttackMatch =
findTextAttack(screenshot.Value, new RectInt(0, 0, 100, 80))
?.CastToNullable()
?.FirstOrDefault();
Host.Delay(333);
if (!mouseOverAttackMatch.HasValue)
continue; // no Attack text found.
smartSession.MouseClickRight((int)testLocation.Value.A, (int)testLocation.Value.B);
Host.Delay(333);
// now the menu for the object should be open.
screenshot = smartSession.TakeImageRaster();
if (!screenshot.HasValue)
continue;
// search for attack text
var attackMatch =
findTextAttack(screenshot.Value, viewportRect)
?.CastToNullable()
?.FirstOrDefault();
if (attackMatch.HasValue)
{
// assume the found text belongs to the context menu. Click on the menu entry.
smartSession.MouseClickLeft((int)attackMatch.Value.A + 10, (int)attackMatch.Value.B + 4);
Host.Delay(4444); // wait for char to arrive there.
}
}
finally
{
Host.Delay(1111);
}
}