Tutorials » Combat Rotation » Step 1: Template
- Copy the template below and paste it into a text editor of your choice.
- Save the template in your
Mayofolder under:/Utils/PlugIns/Rotations - It must have the
.csextension. Example:Test.cs
So we'll save our template under /Utils/PlugIns/Rotations/Test.cs
Template (Open and copy me!)
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Mayo.Core;
using Mayo.GameClient;
using Mayo.Manager.Movement;
using Mayo.Manager.Objects.Interface;
using Mayo.Manager.Rotations.Interface;
public class CustomRotation : ICustomRotation
{
// ######################################################################
// VARS
// ######################################################################
private Client GC { get; set; } = null!;
public double CombatDistance { get; } = 3.0;
// ######################################################################
// INITIALIZE
// —————————————————————————————————————————————————————————————————————
// Executed once when the task starts.
// ######################################################################
public void Initialize(Client GC)
{
this.GC = GC;
Log.Write("My custom rotation.", GC);
}
// ######################################################################
// BUFFS
// —————————————————————————————————————————————————————————————————————
// It is checked regularly and applied outside of combat.
// Can also be used for enchantments, conjurings or similar purposes.
// ######################################################################
public async Task<Dictionary<object, List<Func<bool>>>> Buffs()
{
// Example for custom purpose:
var MainHandWeapon = GC.OM.GetEquippedItem(Constants.EquipSlot.MainHand);
if (MainHandWeapon != null && !MainHandWeapon.HasPoison)
await GC.SM.CastMacroAsync(new()
{
"/use Deadly Poison IX",
"/use 16",
});
// Buffs:
var Buffs = new Dictionary<object, List<Func<bool>>>();
Buffs.Add("Spell Name", new() // By name
{
() => !GC.OM.Me.HasAura("Spell Name"),
});
Buffs.Add(12345, new() // By ID
{
() => !GC.OM.Me.HasAura(12345),
});
return Buffs;
}
// ######################################################################
// COMBAT APPROACH
// —————————————————————————————————————————————————————————————————————
// Everything that needs to be done on the way to the target.
// All actions are performed between 10-30 yds between player and target.
// ######################################################################
// ###################################
// APPROACHING NPC
// ———————————————————————————————————
// My behavior toward an NPC.
// ###################################
public async Task CombatApproach(IUnit Target)
{
var Distance = Target.Distance3D;
await GC.SM.TryCastAsync("Stealth", new()
{
() => Distance >= 20,
() => Distance <= 30,
() => !GC.OM.Me.IsInCombat,
() => !GC.OM.Me.IsInShapeshiftForm(Constants.ShapeshiftForm.Stealth),
});
}
// ###################################
// APPROACHING PLAYER
// ———————————————————————————————————
// My behavior toward a player.
// ###################################
public async Task CombatApproach(IPlayer Target)
{
}
// ######################################################################
// COMBAT ROTATION
// —————————————————————————————————————————————————————————————————————
// Repeated execution until target dies or the task has stopped.
// ######################################################################
// ###################################
// ME VS NPC
// ###################################
public async Task CombatRotation(IUnit Target)
{
if (Target.Distance3D > CombatDistance)
{
await GC.MM.FollowAsync(Target, new GroundPathConfig(GC)
{
StopFollowDistance = 2.0,
});
await GC.MM.InteractAsync(Target);
}
if (GC.OM.Me.CurrentPower < 40)
{
await GC.MM.InteractAsync(Target);
return;
}
await GC.SM.TryCastAsync("Sinister Strike", Target, new()
{
() => GC.OM.Me.ComboPoints <= 1,
});
await GC.SM.TryCastAsync("Eviscerate", Target, new()
{
() => GC.OM.Me.ComboPoints >= 2,
});
}
// ###################################
// ME VS PLAYER
// ###################################
public async Task CombatRotation(IPlayer Target)
{
if (Target.Distance3D > CombatDistance)
{
await GC.MM.FollowAsync(Target, new GroundPathConfig(GC)
{
StopFollowDistance = 2.0,
});
await GC.MM.InteractAsync(Target);
}
if (GC.OM.Me.CurrentPower < 40)
{
await GC.MM.InteractAsync(Target);
return;
}
await GC.SM.TryCastAsync("Sinister Strike", Target, new()
{
() => GC.OM.Me.ComboPoints <= 1,
});
await GC.SM.TryCastAsync("Eviscerate", Target, new()
{
() => GC.OM.Me.ComboPoints >= 2,
});
}
}
Don't let the content of the template confuse you. It contains a very simplified version of a rogue rotation and is intended only as an example to get you started.
In the following steps, we'll explain how to customize the template step by step.