Findeh
-
Posts
365 -
Joined
-
Last visited
Reputation Activity
-
Findeh reacted to Apexx in Alot of questions about FightClass and API
// Return Number of Hostile Units Attacking in Specified Range private int HostileUnitsInRange(float range) { int hostileUnitsInRange = ObjectManager.GetUnitAttackPlayer().Count(u => u.GetDistance <= range); return hostileUnitsInRange; } Try something like the following (Will check if no unit is attacking you within 30 yards):
wManager.Events.FightEvents.OnFightEnd += delegate { if (HostileUnitsInRange(30) == 0) Buff(); };
-
Findeh reacted to reapler in Alot of questions about FightClass and API
@Findeh
private bool CanBleed(WoWUnit unit) { return unit.CreatureTypeTarget != "Elemental" && unit.CreatureTypeTarget != "Mechanical"; } Usage:
if (CanBleed(ObjectManager.Me.TargetObject)) { new Spell("Rend").Launch(); }
-
Findeh reacted to reapler in Alot of questions about FightClass and API
@apexx Namespace System.Linq is not referenced. So you need to copy this on the top of your code:
using System.Linq; Both .Where() & .Count() are included in Linq, that's the reason why .Count() couldn't work because it doesn't had an overload available.
So in the end you can use this:
if (ObjectManager.GetUnitAttackPlayer().Count(u => u.GetDistance <= 6) > 2) { } Or use other Linq methods.
-
Findeh reacted to reapler in Alot of questions about FightClass and API
Yes, that's right but with my snippet you get a string from your spell with lua in this case: "Shadow Word: Pain".
I made a simple method:
public Spell Spell_(string name) => new Spell(name) { Icon = Lua.LuaDoString<string>( "name, rank, icon, castTime, minRange, maxRange = GetSpellInfo(\"" + name + "\")", "rank") }; This overrides "Icon" to spell's rank. I guess it's not added in vanilla, because it was forgotten as it was backported :)
Usage:
public void Initialize() { wManager.Wow.Class.Spell eviscerate = Spell_("Eviscerate"); robotManager.Helpful.Logging.Write("Get information of spell: " + eviscerate.Name); robotManager.Helpful.Logging.Write("Spell rank: "+eviscerate.Icon);//now field ".Icon" returns the rank if you use "public Spell Spell_(string name) => new Spell(name)" robotManager.Helpful.Logging.Write("Spell id: "+eviscerate.Id); }
-
Findeh reacted to iMod in Alot of questions about FightClass and API
Some event samples
#region Events // Listen to events EventsLuaWithArgs.OnEventsLuaWithArgs += delegate (LuaEventsId id, List<string> args) { #region PLAYER_REGEN_ENABLED if (id == LuaEventsId.PLAYER_REGEN_ENABLED) { Functions.InCombat = false; } if (id == LuaEventsId.PLAYER_REGEN_DISABLED) { Functions.InCombat = true; } #endregion #region MODIFIER_STATE_CHANGED if (id == LuaEventsId.MODIFIER_STATE_CHANGED && args.Count == 2) { // Possible values are LSHIFT, RSHIFT, LCTRL, RCTRL, LALT, and RALT string key = args[0]; // 1 means that the the key has been pressed. 0 means that the key has been released int state = int.Parse(args[1]); // AOE mode if (key == "LALT" && state == 0) { // Set status rotation.AoeMode = !rotation.AoeMode; // Write to chat string message = $"iRotation AoeModes: {(rotation.AoeMode ? "|cFF00FF00On.|r" : "|cFFFF0000Off.|r")}"; Lua.LuaDoString($"print(\"{message}\")"); } // Burst mode if (key == "LCTRL" && state == 0) { // Set status rotation.BurstMode = !rotation.BurstMode; // Write to chat string message = $"iRotation BurstMode: {(rotation.BurstMode ? "|cFF00FF00On.|r" : "|cFFFF0000Off.|r")}"; Lua.LuaDoString($"print(\"{message}\")"); } } #endregion }; #endregion
-
Findeh reacted to reapler in Alot of questions about FightClass and API
Welcome @Findeh to WRobot, you can find details & templates about fightclasses here.
To get a detailed documentation, you can decompile WRobot's libraries here explained.
For this task you could use "wManager.Events.FightEvents.OnFightEnd"
A plugin already exists here
"wManager.Wow.ObjectManager.ObjectManager.Me.TargetObject.Health" for futures requests you may search in your decompiler by looking for "health" for example
Unfortunately no event exists. But you can check it on a loop: "wManager.Wow.Bot.States.ToTown.GoToTownInProgress"
-
Findeh reacted to Avvi in Trinket Cooldown Time Left
I'm not the greatest with lua, so here is my answer but in C#.
int itemID = 123; var itemCooldown = wManager.Wow.Helpers.Bag.GetContainerItemCooldown(itemID); var itemTimer = new robotManager.Helpful.Timer(itemCooldown); itemIsReady.ForceReady(); if (itemTimer.IsReady) { ItemsManager.UseItem((uint)itemID); itemTimer.Reset(); } Also, i'm not really sure about what this does:
Bag.GetContainerItemCooldown(itemID) This may actually return the remaining time. I haven't tested. If it DOES return the remaining time, then you can pretty much skip the whole timer thing :). Anyway, let me know!
I found an example that does it very similarly to my above snippet:
-
Findeh got a reaction from krlitoz in Teleport question
If your continent was changed, if i did get the question right.
Every continent got the name. To see your current continent go: Tools / Development Tool / Me & Target position
For example, if you were at the Azeroth and then wManager.Wow.Helpers.Usefuls.ContinentId != (int)wManager.Wow.Enums.ContinentId.Azeroth, then you have been teleported.
-
Findeh reacted to reapler in Heals Casting Twice With Timer
Hello, i've created a small example for this, everything else is explained in the comments:
using System; using System.Collections.Generic; using System.Threading; using wManager.Plugin; using wManager.Wow.Class; using wManager.Wow.Enums; using wManager.Wow.Helpers; using wManager.Wow.ObjectManager; using static robotManager.Helpful.Logging; public class Main : IPlugin { #region Variables private bool _isLaunched; private int _msDelay = 200; private DateTime _unlockTime = DateTime.Now; private readonly HashSet<string> _noGcdSpells = new HashSet<string> { "Counterspell", //... //http://wowwiki.wikia.com/wiki/Cooldown => Abilities noted for not affecting nor being affected by the global cooldown: }; #endregion #region Properties public bool GcdActive => DateTime.Now < _unlockTime; #endregion #region WRobot Interface public void Initialize() { var pGuid = ToWoWGuid(ObjectManager.Me.Guid); EventsLuaWithArgs.OnEventsLuaWithArgs += delegate(LuaEventsId id, List<string> args) { if ( id == LuaEventsId.COMBAT_LOG_EVENT_UNFILTERED && args[2] == pGuid && !_noGcdSpells.Contains(args[9]) && ( args[1] == "SPELL_CAST_SUCCESS" || args[1] == "SPELL_HEAL" || args[1] == "SPELL_DAMAGE" ) ) { Write("lock"); _unlockTime = DateTime.Now.AddMilliseconds(_msDelay); } }; _isLaunched = true; Write("Loaded"); while (_isLaunched) { try { if (Conditions.ProductIsStartedNotInPause) { Pulse(); } } catch (Exception e) { WriteError(e.ToString()); } Thread.Sleep(30); } } public void Dispose() { _isLaunched = false; } public void Settings() { } #endregion #region Pulse public void Pulse() { var spell = new Spell("Lesser Heal"); if (!GcdActive && spell.IsSpellUsable && !ObjectManager.Me.IsCast && ObjectManager.Me.TargetObject.HealthPercent <= 90 ) { spell.Launch(false, false); //will cast the heal if "_msDelay" was passed } /* if (spell.IsSpellUsable && !ObjectManager.Me.IsCast && ObjectManager.Me.TargetObject.HealthPercent <= 90) { spell.Launch(false, false); //.IsSpellUsable is true after gcd was passed but the heal itself can delay //and cause double heal cast if no additional delay is added like above //so ObjectManager.Me.TargetObject.HealthPercent <= 90 would be true for a short time }*/ } #endregion #region Methods public string ToWoWGuid(ulong guid) { var wowGuid = ObjectManager.Me.Guid.ToString("x").ToUpper(); var c = 16 - wowGuid.Length; for (var i = 0; i < c; i++) { wowGuid = "0" + wowGuid; } return "0x" + wowGuid; } #endregion } if you are going to lower the tickspeed this will rarer happens, but it can still happen. Instant spells aren't included.
-
Findeh reacted to Droidz in Bot is spinning at one place, going forward then back again
Hello, can you share position (from/to) , continent name and the log file
-
Findeh reacted to Apexx in Heals Casting Twice With Timer
Timer Declaration
public static Timer waitTime = new Timer(); Asynchronous Task UseCombatSpell
public static async Task<bool> UseCombatSpell(Spell spell, bool stopMoving, bool faceTarget = false, float rangeCheck = float.MaxValue, int castWait = 0) { // Spell validation if (Methods.IsValid(MyTarget, spell)) { // Launch the spell if (!Me.IsCast && waitTime.IsReady) { // Face the target if (faceTarget) MovementManager.Face(Me.TargetObject); Interact.InteractGameObject(MyTarget.GetBaseAddress, stopMoving); SpellManager.CastSpellByNameLUA(spell.Name); // Wait for cooldown + latency await Task.Delay(SpellManager.GetSpellCooldownTimeLeft(spell.Id) + Usefuls.Latency); // Create a new timer for the desired wait time between casts. waitTime = new Timer(castWait); Methods.LogFight("Wait time = " + waitTime.TimeLeft()); return true; } return false; } return false; } Please note, that I removed the rangeCheck portion of code from the above method.
Usage:
if (await Abilities.LesserHeal()) return true; // Lesser Heal
Methods.IsValid is basically making sure that the player knowns the spell, that the spell is usable and in good distance,
that the player is not eating or drinking, or is mounted..
That the target is attackable and alive, in distance, and in line of sight etc..
Abilities.Spellname is from a custom class of loading and declaring the class spells.
-
Findeh got a reaction from eeny in Suggestion: Add option to set vendor for profile
So if i need like 200 grinding profiles (i really do) i will have to write 200 quest profiles by hand or make 200 different npc bases? Am i getting it right? And why then do we have NPC option inside the grinding profile creator?
-
Findeh reacted to Droidz in Offmesh Connections
Hello,
Sometime, WRobot cannot create path (navigation files are created from default maps, some quests/events open the doors, remove/add the stones,..., this can happen also if it's narrow, or sometime without reason).
By sample, it is a narrow staircase, you get error like (navigation file tell at WRobot than he cannot walk in the staircase) (to get full pathfinding logs, in advanced general settings tab 'Path...' activate option "Server Logs")
(to get detailed log, you need to activate option "Show server logs" in advanced general settings tab "Path-finding").
Now, we will add offmesh connection (we will add staircase path):
And we will try again to generate path:
ref: http://www.pathengine.com/Contents/Overview/AdditionalFeaturesOverview/Off-MeshConnections/page.php https://docs.unity3d.com/Manual/class-OffMeshLink.html
-
Findeh reacted to reapler in Alot of questions about FightClass and API
Logging.Write(Lua.LuaDoString<string>("name, rank, icon, castTime, minRange, maxRange = GetSpellInfo(\"Shadow Word: Pain\")", "rank")); Can be used. But i guess you could also need "desc = GetSpellDescription(spellId)" but unfortunately for me it doesn't return any string to parse the damage values.
Ok let's take FightEvents. I linked a fightclass which has "internal void BuffRotation()" on a loop. Once "public void Initialize()" is called from the interface(start bot), it will loop this method till you stop the bot.
So that means the buffrotation aswell the other methods in your fightclass having no impact / affiliation on "FightEvents".
The "FightEvents" or the other events in WRobot are triggered from the bot behavior itself (you can imagine like a guy reporting you what he's doing).
So this "guy" tells you:
I attack now this npc = "wManager.Events.FightEvents.OnFightStart"
While fighting i also report whats going on every ~30ms = "wManager.Events.FightEvents.OnFightLoop"
the fight is over = "wManager.Events.FightEvents.OnFightEnd"
This is useful for plugins for example but if you are going to write a fightclass, you wouldn't really need it.
If you want to write a plugin which uses an item or do other action after a fight end, you could subscribe it like this:
wManager.Events.FightEvents.OnFightEnd += delegate { wManager.Wow.Helpers.SpellManager.CastSpellByIdLUA(8690); //cast hearthstone };
If you write an plugin you could use your snippet on a loop or by subscribing it to "wManager.Events.MovementEvents.OnMoveToPulse".
But i guess you are writing a fightclass anyway, so you can put this snippet to buffrotation or directly to while loop:
internal void BuffRotation() { if (ObjectManager.Me.IsMounted) return; //if not mounted cast sprint var spelltocast = new Spell("Sprint"); if (wManager.Wow.Bot.States.ToTown.GoToTownInProgress && spelltocast.IsSpellUsable) { spelltocast.Launch(); } } or directly in while loop:
internal void Rotation() { Logging.Write("[My fightclass] Is started."); while (_isLaunched) { try { if (!Products.InPause) { if (!ObjectManager.Me.IsDeadMe) { BuffRotation(); var spelltocast = new Spell("Sprint"); if (wManager.Wow.Bot.States.ToTown.GoToTownInProgress && spelltocast.IsSpellUsable && !ObjectManager.Me.IsMounted) { spelltocast.Launch(); } if (Fight.InFight && ObjectManager.Me.Target > 0) { Pull(); CombatRotation(); } } } } catch (Exception e) { Logging.WriteError("[My fightclass] ERROR: " + e); } Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage. } Logging.Write("[My fightclass] Is now stopped."); } So you can see in the end it doesn't really matter. It's just for a better structure & readability.