Yeah @betterSister thats what i am lookin for actually that would help a lot because my party members keep standing too long in it and i cant do anything against it besides of simple follow but he should choose the shortest way without aoe fields on the ground.
Maybe we can get a smart solution for that from droidz
Hello,
Sorry, I'll not add this.
But I planned to make a program that manages several sessions of WRobot (product change, profile change, restart) and Wow (launch, restart, relog,...)
Please send me your code/fightclass if you want best reply.
I have written this for help an member to create an heal fightclass (not tested, it is sample code):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using robotManager.Helpful;
using wManager.Wow.Class;
using wManager.Wow.Enums;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
public class Main : ICustomClass
{
private HolyPaladin _holyPaladin;
public float Range { get { return 29.0f; } }
public void Initialize()
{
_holyPaladin = new HolyPaladin();
_holyPaladin.Pulse();
}
public void Dispose()
{
_holyPaladin.Stop();
}
public void ShowConfiguration()
{
MessageBox.Show("No settings for this FightClass.");
}
}
class HolyPaladin
{
// Property:
private bool _isLaunched;
public bool IsLaunched
{
get { return _isLaunched; }
set { _isLaunched = value; }
}
// Spells:
private Spell _judgment;
private Spell _flashOfLight;
private Spell _lightOfDawn;
private Spell _avengingWrath;
private Spell _handOfProtection;
private Spell _divineShield;
private Spell _layOnHands;
private Spell _holyShock;
private Spell _holyRadiance;
public HolyPaladin()
{
// Init spells:
_judgment = new Spell("Judgment");
_flashOfLight = new Spell("Flash of Light");
_lightOfDawn = new Spell("Light of Dawn");
_avengingWrath = new Spell("Avenging Wrath");
_handOfProtection = new Spell("Hand of Protection");
_divineShield = new Spell("Divine Shield");
_layOnHands = new Spell("Lay On Hands");
_holyShock = new Spell("Holy Shock");
_holyRadiance = new Spell("Holy Radiance");
Logging.WriteFight("'Holy Paladin' by AudreyH loaded");
}
public void Pulse()
{
_isLaunched = true;
var thread = new Thread(RoutineThread) { Name = "HolyPaladin_FightClass" };
thread.Start();
}
public void Stop()
{
_isLaunched = false;
Logging.WriteFight("Stop 'Holy Paladin'");
}
void RoutineThread()
{
Logging.WriteFight("'Holy Paladin' Started");
while (_isLaunched)
{
Routine();
Thread.Sleep(10); // Temps d'attante pour éviter d'utiliser trop le processeurs
}
Logging.WriteFight("'Holy Paladin' Stopped");
}
void Routine()
{
if (!Conditions.InGameAndConnectedAndAlive)
return;
// Ranger par ordre de priorité
if (Judgment())
return;
if (HolyRadiance())
return;
if (FlashOfLight())
return;
if (LightOfDawn())
return;
if (AvengingWrath())
return;
if (HandOfProtection())
return;
if (DivineShield())
return;
if (LayOnHands())
return;
if (HolyShock())
return;
}
// Usefuls methods
List<WoWUnit> GetPartyTargets()
{
var partyMembers = Party.GetPartyHomeAndInstance();
var ret = new List<WoWUnit>();
foreach (var m in partyMembers)
{
if (m.IsValid && m.IsAlive && m.InCombat && m.Target.IsNotZero())
{
if (ret.All(u => u.Guid != m.Target)) // Evite doublon dans la liste retournée
{
var targetUnit = new WoWUnit(ObjectManager.GetObjectByGuid(m.Target).GetBaseAddress);
if (targetUnit.IsValid && targetUnit.IsAlive)
{
ret.Add(targetUnit);
}
}
}
}
return ret;
}
private List<WoWPlayer> GetPartyMembers(int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true)
{
return GetPartyMembers(ObjectManager.Me.Position, maxHealthPercent, maxDistance, orderByHealth);
}
private List<WoWPlayer> GetPartyMembers(Vector3 positionCenter, int maxHealthPercent = 100, float maxDistance = float.MaxValue, bool orderByHealth = true)
{
var partyMembers = Party.GetPartyHomeAndInstance();
var ret = new List<WoWPlayer>();
foreach (var m in partyMembers)
{
if (m.IsValid && m.IsAlive && m.HealthPercent < maxHealthPercent && m.Position.DistanceTo(positionCenter) <= maxDistance)
{
ret.Add(m);
}
}
if (orderByHealth)
ret = new List<WoWPlayer>(ret.OrderBy(p => p.HealthPercent));
return ret;
}
string GetTankPlayerName()
{
var lua = new[]
{
"partyTank = \"\";",
"for groupindex = 1,MAX_PARTY_MEMBERS do",
" if (UnitInParty(\"party\" .. groupindex)) then",
" local role = UnitGroupRolesAssigned(\"party\" .. groupindex);",
" if role == \"TANK\" then",
" local name, realm = UnitName(\"party\" .. groupindex);",
" partyTank = name;",
" return;",
" end",
" end",
"end",
};
return Lua.LuaDoString(lua, "partyTank");
}
WoWPlayer GetTankPlayer()
{
var p = new WoWPlayer(0);
var playerName = GetTankPlayerName();
if (!string.IsNullOrWhiteSpace(playerName))
{
playerName = playerName.ToLower().Trim();
var party = GetPartyMembers();
foreach (var woWPlayer in party)
{
if (woWPlayer.Name.ToLower() == playerName)
{
p = new WoWPlayer(woWPlayer.GetBaseAddress);
break;
}
}
}
return p;
}
// Spells methods
bool Judgment()
{
if (!_judgment.KnownSpell)
return false;
if (!_judgment.IsSpellUsable)
return false;
var partyTargets = GetPartyTargets(); // Recupère les cibles des joueurs du groupe.
foreach (var target in partyTargets) // On recherche dans la liste
{
if (target.IsValid && target.IsAlive) // Verif si target valid et en vie
{
if (target.GetDistance < _judgment.MaxRange) // Verif si bonne distance
{
if (!TraceLine.TraceLineGo(target.Position)) // TraceLine permet de vérifier un obstacle entre deux position (true si obstacle)
{
if (UnitCanAttack.CanAttack(target.GetBaseAddress)) // On peut attaquer la cible
{
Interact.InteractGameObject(target.GetBaseAddress, true); // sélectionne la cible in game
MovementManager.Face(target); // Faire face à la cible
_judgment.Launch(); // Lancer le sort
return true;
}
}
}
}
}
return false;
}
bool BaseHealSpell(Spell spell, int maxHealthPercent, float maxDistance)
{
if (!spell.KnownSpell)
return false;
if (!spell.IsSpellUsable)
return false;
var partyMembers = GetPartyMembers(maxHealthPercent, maxDistance);
foreach (var partyMember in partyMembers)
{
if (!TraceLine.TraceLineGo(partyMember.Position)) // TraceLine permet de vérifier un obstacle entre deux position (true si obstacle)
{
Interact.InteractGameObject(partyMember.GetBaseAddress, true); // sélectionne la cible in game
MovementManager.Face(partyMember); // Faire face à la cible
spell.Launch(); // Lancer le sort
return true;
}
}
return false;
}
bool FlashOfLight()
{
return BaseHealSpell(_flashOfLight, 90, 40);
}
bool LightOfDawn()
{
if (!_lightOfDawn.KnownSpell)
return false;
if (!_lightOfDawn.IsSpellUsable)
return false;
if (ObjectManager.Me.GetPowerByPowerType(PowerType.HolyPower) < 3)
return false;
var partyMembers = GetPartyMembers(90, 30);
if (partyMembers.Count >= 3) // Si minimum 3 alliés dans les 30 mètres avec moins de 90% de vie
{
_lightOfDawn.Launch(); // Lancer le sort
return true;
}
return false;
}
bool AvengingWrath()
{
if (!_avengingWrath.KnownSpell)
return false;
if (!_avengingWrath.IsSpellUsable)
return false;
var partyTargets = GetPartyTargets(); // Recupère les cibles des joueurs du groupe.
if (partyTargets.Count > 0 || ObjectManager.Me.InCombat) // Si un des joueurs ou moi en combat
{
_avengingWrath.Launch(); // Lancer le sort
return true;
}
return false;
}
bool HandOfProtection()
{
if (!_handOfProtection.KnownSpell)
return false;
if (!_handOfProtection.IsSpellUsable)
return false;
if (ObjectManager.Me.InCombat && ObjectManager.Me.HealthPercent <= 20) // Si en combat et moins de 20% de vie
{
_handOfProtection.Launch(false, true, false, true); // Lancer le sort OnSelf
return true;
}
return false;
}
bool DivineShield()
{
if (!_divineShield.KnownSpell)
return false;
if (!_divineShield.IsSpellUsable)
return false;
if (ObjectManager.Me.InCombat) // Si en combat
{
_divineShield.Launch(); // Lancer le sort
return true;
}
return false;
}
bool LayOnHands()
{
if (!_layOnHands.KnownSpell)
return false;
if (!_layOnHands.IsSpellUsable)
return false;
if (ObjectManager.Me.HealthPercent <= 20)// Si moins de 20% de vie
{
_layOnHands.Launch(false, true, false, true); // Lancer le sort OnSelf
return true;
}
return false;
}
bool HolyShock()
{
if (ObjectManager.Me.InCombat)
return BaseHealSpell(_holyShock, 95, 40);
return false;
}
bool HolyRadiance()
{
if (!_holyRadiance.KnownSpell)
return false;
if (!_holyRadiance.IsSpellUsable)
return false;
var partyMembers = GetPartyMembers(90, 40); // On recupere les membres du groupe avec moins de 90% de vie à 40 metres
var bestPlayer = new WoWPlayer(0); // Le meilleur joueur pour recevoir le sort
int bestHealthMissing = 0; // Score (plus le score est haut mieux c'est, ce score et le nombre de pourcentages de vie qui manque aux joueurs qui ce trouve dans les 10 metres du joueur bestPlayer)
foreach (var partyMember in partyMembers) // On va rechercher le meilleur joueur
{
if (partyMember.IsValid && partyMember.IsAlive && !TraceLine.TraceLineGo(partyMember.Position))
{
var partyMembersNearPartyPlayer = GetPartyMembers(partyMember.Position, 95, 10); // La on recherche les joueurs proches de partyMember qui ce trouve à 10 metres (porté du sort) (retourne également partyMember dans le résultat)
if (partyMembersNearPartyPlayer.Count > 2) // Si ils sont minimum 2 joueurs dans les 10 metres
{
int healthMissing = 0;
foreach (var p in partyMembersNearPartyPlayer)
{
if (p.IsValid && p.IsAlive)
{
healthMissing = healthMissing + (100 - (int)p.HealthPercent);
}
}
if (healthMissing > bestHealthMissing)
{ // Si il manque plus de vie ici alors on le désigne comme le meilleur choix
bestPlayer = new WoWPlayer(partyMember.GetBaseAddress);
bestHealthMissing = healthMissing;
}
}
}
}
// Si bestPlayer trouvé
if (bestHealthMissing > 0 && bestPlayer.IsValid)
{
Interact.InteractGameObject(bestPlayer.GetBaseAddress, true); // sélectionne la cible in game
MovementManager.Face(bestPlayer); // Faire face à la cible
_holyRadiance.Launch(); // Lancer le sort
return true;
}
return false;
}
}
var tank = getTanks();
WoWUnit target = ;
Interact.InteractGameObject(target.GetBaseAddress);
_wrath.Launch();
Thats why i said don't use var ^_-
// Get all available tanks
List<WoWPlayer> tankList = getTanks();
// Get the first tank in the list
WoWPlayer tank = tankList.First();
// Get the target of the tank
WoWUnit target = tank.TargetObject;
// Focus at target
Interact.InteractGameObject(target.GetBaseAddress, true);
// Use the skill
_wrath.Launch();
It is way essiert to read ^_-
// Get tank
WoWPlayer tank =
// Get target
WoWUnit target = tank.TargetObject;
// Select target
Interact.InteractGameObject(target.GetBaseAddress);
// Do Spell
This is a quick and dirty example. Hope it helps.
Here is a Idea to Improve Farming Herbs with a Druid
Bot checks if Class is Druid
Bot checks if Flight Form is available
Start flying to the Node above it (~10 yards)
Fly to the note Max distance (I dont know the exact max range to gather nodes but i guess its arround 3-5 yards)
If get hit Fly away
If that get implemented it improve the herbing of Druids alot.
As better said can make your own profiles I'm only going share quester as time allows me to work on that up to a certain point will share it and maybe share what ever grind path I can convert ok.
i didn't try to add prowl cuz i think it's waste of time for farming... but for mangle you need to add mangle 2 times. first with conditions buff mangle false so it uses it only when it's not there (before bleeds) and 2nd time after the bleeds are there with conditions combo points <= 4 and buff rake true.
but i think that if you really want to add prowl and pounce then add to first priority cat form (maybe mana percent check here too?), prowl (if buff cat form true, no combat), pounce (if buff prowl true, no combat)
and ofcourse remember to add check buff cat form for every cat attack or it'll spam them for no reason!
Sorry, I wanted to release quickly wrobot for 3.3.5a and I have not had time to test all the features before...
If you can wait next update and tell me if problem is resolved.
i can take vid about this tomorrow. i haven't tried flying with gatherer since i don't have a character yet that can fly and has mining/herb. It was my druid that has skinning. I could try lua to move tomorrow
There is a video Droidz made on youtube I watched it simply follow steps get all info u need to set it up going release Gnome and Dwarf 1 to 5 but need some love on last 4 quests. I mean it worked just unhappy with it.
In "Grinder" profile you can change zone only by level (when you record zone you need to setting min/max level). If you want more option you need to use "Quester" or "Custom Profile" profile.