-
Posts
288 -
Joined
-
Last visited
Content Type
Forums
Articles
Bug Tracker
Downloads
Store
Posts posted by reapler
-
-
39 minutes ago, Apexx said:
#region Properties public bool GcdActive => DateTime.Now < _unlockTime; #endregion
Error 1 ; expected
Error 2 Invalid token ';' in class, struct, or interface member declaration
Error 3 Syntax error, '>' expected
Error 4 'Main._unlockTime' is a 'field' but is used like a 'type'
Error 5 'System.DateTime.Now' is a 'property' but is used like a 'type'I forgot to mention that i compiled it with a newer C# version in Vs. For example in C#6 you can import static type members into namespace.
This version should also work with the older version as ".cs" file:
Spoilerusing System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using wManager.Plugin; using wManager.Wow.Class; using wManager.Wow.Enums; using wManager.Wow.Helpers; using wManager.Wow.ObjectManager; using robotManager.Helpful; public class Main : IPlugin { #region Variables private bool _isLaunched; private int _msDelay = 150; 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 { get { return 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" ) ) { Logging.Write("lock"); _unlockTime = DateTime.Now.AddMilliseconds(_msDelay); } }; _isLaunched = true; Logging.Write("Loaded"); while (_isLaunched) { try { if (Conditions.ProductIsStartedNotInPause) { Pulse(); } } catch (Exception e) { Logging.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 <= 95 ) { spell.Launch(false, false); //will cast the heal if "_msDelay" was passed } /* if (spell.IsSpellUsable && !ObjectManager.Me.IsCast && ObjectManager.Me.TargetObject.HealthPercent <= 95) { 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 }
-
17 minutes ago, Apexx said:
That's wild! Thank you for the exuberant example. I will need to look this over a few times to try and wrap my head around it. Why is this sort of thing not already implemented into WRobot? Also, you defined _msDelay. Where does this number come from?
It's the wait time after each cast. You may set this to 50ms - 200ms. But i think 50ms should still be ok on low tick speed.
-
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.
-
-
Hello, since you are using vanilla i assume the method doesn't work correctly but i'm not sure("DoString" is obfuscated).
You also can't use the "/use <item>" it wasn't implemented on vanilla. So you need to iterate the items in your bag with lua.
I tried this on 3.3.5a but since the used api functions is also present on vanilla, it should also work:
public void UseItemByName(string name, bool lootItem = true) { if (lootItem) { Task.Run(async delegate { robotManager.Helpful.Keyboard.DownKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle, System.Windows.Forms.Keys.ShiftKey); await Task.Delay(2000); robotManager.Helpful.Keyboard.UpKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle, System.Windows.Forms.Keys.ShiftKey); }); } wManager.Wow.Helpers.Lua.LuaDoString( @" for b=0,4 do for s=1,GetContainerNumSlots(b) do if (string.find(tostring(GetContainerItemLink(b,s) or """"), """+wManager.Wow.Helpers.ItemsManager.GetIdByName(name)+@""" )) then UseContainerItem(b,s, onSelf); end end end " ); }
Usage:
UseItemByName("Hearthstone", false);
or
UseItemByName("Heavy Crate", true);
-
-
-
-
A small update from me:
Since i'm almost done with the database, i can continue working on my editor again. But my first design wasn't really good.
I'm thinking to use a more simpler solution which doesn't require to assign a "Action parameter" at the sorted quests.
In the end each action define a step which are selectable on the bar like this:
SpoilerBy the way, if you have a custom pulse like "KillAndLoot", "Gatherer" or something else which is often used, you are welcome to post it and i can create a seperate setting gui for it.
-
59 minutes ago, lonellywolf said:
When I use this with C sharp, it give me errors on Wrobot...
Hello, i've created a small example how to use the c# code: heal.xml
Because reactions are ordered you can use it like this:
wManager.Wow.ObjectManager.ObjectManager.Me.TargetObject.Reaction > Reaction.Neutral
- Photogenic and Pudge
- 1
- 1
-
Hello, @scripterx i really recommend to use c#. Pqr / only lua is limited in many ways.
According to your posts, i guess you only want to cast specific spells by a button press only if x condition is met.
So in this case you could do it like this in a plugin(i know it could be better > copy-pasta from my other posts):
using System; using wManager.Plugin; using wManager.Wow.Class; using wManager.Wow.ObjectManager; public class Main : IPlugin { public void Initialize() { robotManager.Helpful.Logging.Write("Register OnEventsLuaWithArgs"); wManager.Wow.Helpers.EventsLuaWithArgs.OnEventsLuaWithArgs += delegate (wManager.Wow.Enums.LuaEventsId id, System.Collections.Generic.List<string> args) { if (id != wManager.Wow.Enums.LuaEventsId.EXECUTE_CHAT_LINE || ObjectManager.Me.IsStunned) return; var toCast = new Spell("Riptide"); if (args[0].ToUpper().Equals(("/cast @target " + toCast.Name).ToUpper()) && ObjectManager.Me.TargetObject.HealthPercent <= 90) { toCast.Launch(false, false, false, "target"); } if (args[0].ToUpper().Equals(("/cast @player " + toCast.Name).ToUpper()) && ObjectManager.Me.HealthPercent <= 95) { toCast.Launch(false, false, false, true); } }; } public void Dispose() { } public void Settings() { } }
In-game you can just create a macro like this:
#showtooltip Riptide /cast @target riptide
So it will only cast the spell, if target is under 95% health. More related stuff can be found here.
Otherwise you can do it on an automatic way in a rotation:
using System; using System.Threading; using System.Windows.Forms; using robotManager.Helpful; using robotManager.Products; using wManager.Wow.Class; using wManager.Wow.Helpers; using wManager.Wow.ObjectManager; public class Main : ICustomClass { public float Range => 30f; private bool _isLaunched; public Spell Riptide = new Spell("Riptide"); public void Initialize() // When product started, initialize and launch Fightclass { _isLaunched = true; Logging.Write("[My fightclass] Is initialized."); while (_isLaunched) { try { if (!Products.InPause && !ObjectManager.Me.IsDeadMe) { Pulse(); } } catch (Exception e) { Logging.WriteError("[My fightclass] ERROR: " + e); } Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage. } } public void Dispose() // When product stopped { _isLaunched = false; Logging.Write("[My fightclass] Stop in progress."); } public void ShowConfiguration() // When use click on Fight class settings { MessageBox.Show("[My fightclass] No setting for this Fight Class."); } public void Pulse() { if (ObjectManager.Me.Target != 0 && Riptide.IsSpellUsable && Riptide.IsDistanceGood && Riptide.KnownSpell && ObjectManager.Me.TargetObject.HealthPercent <= 95) { Riptide.Launch(); } } }
You can also combine them & use settings for automatic / manual usage and do whatever you want: The possibilities are endless. Using a state engine is also possible.
More informations can be found here.
If you need help, feel free to ask.
-
Hello, you can decompile WRobot's libraries to get the needed informations: https://wrobot.eu/forums/topic/6103-frost-dk-rotation-help-needed/?tab=comments#comment-27890
You might consider to do a search first, before you creating another thread.
-
I've looked over the spell class again and found this constructor:
public Spell(string spellNameEnglish, bool showLog)
So you need to add "false" on every instance of "Spell":
public Spell GetActiveStance() { return new Spell(Lua.LuaDoString<List<string>>(@"local r = {} for i=1,10 do local _, n, a = GetShapeshiftFormInfo(i); if a then table.insert(r, tostring(n)); end end return unpack(r);").FirstOrDefault() ?? "", false); } public Spell BattleShout = new Spell("Battle Shout", false); //...
This should hopefully stop the spam.
-
15 minutes ago, LilleCarl said:
2.4.3 DBC (fightclass will create DBC folder in bot root)
https://mega.nz/#!Fl1nVRyC!w6szGtAhEGUvho1Du5n1ZMB834L28Fg08oFYgOcjU6UFightClass that loads Spell DBC files and a child class to Spell where you easily can access this spelldata from https://github.com/Lillecarl/FightClass1
That's all i've got for now, thanks for your help reapler! :)
It looks excellent Carl. I'm looking forward that this will be added soon to the WRobot's lib ;)
-
Hello @LilleCarl, i don't think that's the actual behavior of "new Spell("Regrowth", false).Id" to get the first rank and ".KnownSpell" shouldn't return always true. Maybe @Droidz can look into it.
On 3.3.5a i have only experienced the second issue.
But you may try this:
public List<uint> GetKnownSpellIds(string name) { return new Spell(name).Ids.Where(SpellManager.KnowSpell).OrderBy(i => i).Distinct().ToList(); } public uint GetHighestKnownSpell(string name) { return new Spell(name).Ids.Where(SpellManager.KnowSpell).OrderByDescending(i => i).FirstOrDefault(); }
Usage:
var s = GetKnownSpellIds("Regrowth"); for (var i = 0; i < s.Count; i++) { robotManager.Helpful.Logging.Write("\nId: "+s[i] +" Rank: "+(i+1)); } robotManager.Helpful.Logging.Write("Id: "+GetHighestKnownSpell("Regrowth"));
-
16 minutes ago, LilleCarl said:
I've already implemented a C# dbc reader from https://github.com/TrinityCore/SpellWork/tree/0.12/ into my fightclass that reads all the spell DBC, it'll be OpenSource once i've cleaned it up to a non embarrassing level.
I have already thought about this option at my current project (https://wrobot.eu/forums/topic/6681-extension-wowdb/) but i wanted to be more compact and converted it to SqLite.
In the end no client actions are needed and i can customize struct definitions (https://github.com/barncastle/WDBXEditor), load it to database and alter it.
I guess i also need to add spell retrieve methods to my manager aswell more client data to db :)
But i'm thinking now it's better to use the reader, because all WRobot libraries already have it.
And by the way welcome to WRobot.
-
@Asoter Everything looks fine, checked names and values. For me it works: doesn't matter in "RunCode" or in plugin.
You may try this snippet:
using System; using System.Linq; using robotManager.Helpful; using wManager.Plugin; public class Main : IPlugin { public bool readyIntoDungeon { get { Logging.Write(this.GetType().GetProperties().FirstOrDefault().Name); return Var.GetVar<bool>(this.GetType().GetProperties().FirstOrDefault().Name); } set { Logging.Write(this.GetType().GetProperties().FirstOrDefault().Name); Var.SetVar(this.GetType().GetProperties().FirstOrDefault().Name, value); } } public void Initialize() { Logging.Write(""+readyIntoDungeon); } public void Dispose() { } public void Settings() { readyIntoDungeon = true; } }
Click on settings button then start bot. If it's not printing "true", then something else could be wrong with your plugin. But without an insight into your code, i can't really define the problem.
-
@Asoter In your plugin, "using System.Linq;" must be defined at the top of your code. If not ".FirstOrDefault()" will not work.
-
So far i can see it correctly detects the debuff. You may need to look-over if you have somewhere else used ".Launch()" for your "Demoralizing Shout",
because in the snippet it must log "not active" before "[Spell] Cast Demoralizing Shout (Demoralizing Shout)" can appear(it can a bit delay).
I guess you may also alter the ".Launch()" method aswell the conditions for the spell, since "waitIsCast" has an impact of your rotation:
var spell = new Spell("Demoralizing Shout"); if (!ObjectManager.Me.TargetObject.HaveBuff(spell.Ids) && spell.IsSpellUsable && spell.IsDistanceGood) { Logging.Write("not active\n=> cast"+spell.Name); spell.Launch(false, false); } else { Logging.Write(spell.Name+" active"); }
-
@Asoter Hello, in order to make a variable changeable by quester, you can transform your current variable into an property.
Let's say you have an quest counter in your plugin defined as int:
public int QuestCounter = 0;
So you need to change this into this:
public int QuestCounter { get { return robotManager.Helpful.Var.GetVar<int>(this.GetType().GetProperties().FirstOrDefault()?.Name); } set { robotManager.Helpful.Var.SetVar(this.GetType().GetProperties().FirstOrDefault()?.Name, value); } }
You can still treat as an normal variable.
And in Quester it looks like this:
robotManager.Helpful.Var.SetVar("QuestCounter", 12);
-
1 hour ago, Apexx said:
Thanks for the replies. I am still not quite sure how I can check each different id to whichever spell id the player currently has (as per rank and level of training).
Lower level warriors use spell id 1160, while rank 2 of Demoralizing shout uses 6190. If I run a for loop through each demoralizing shout id that each mob
might have, I am wondering if this will be very efficient?It's pretty fast. For a few ids, there's no need to care about (as i benchmarked, it took about 0,01789ms).
But if you are going to iterate through thousands of entries, then another solution must be considered.
You can read more about the performance of .net collections here.
You might also try this:
var spell = new Spell("Demoralizing Shout"); if (!ObjectManager.Me.TargetObject.HaveBuff(spell.Ids)) { Logging.Write("not active"); spell.Launch(); } else { Logging.Write("debuff active"); }
-
Hello, i can't directly test it, but you can try:
var target = ObjectManager.Me.TargetObject; var spell = new Spell("Demoralizing Shout"); if (!spell.TargetHaveBuff) { spell.Launch(); }
or you can find the problem by yourself if you lookup spell / target:
//copy this in your fightclass, and run this with opening settings public void ShowConfiguration() { //effects are also included var spellName = "Demoralizing Shout"; Logging.Write("Get all ids of spell: "+spellName); foreach (var id in new Spell(spellName).Ids.Distinct()) { Logging.Write("\n"+id); } Logging.Write("Done."); Logging.Write("Get all buffs from current target:"); foreach (var id in ObjectManager.Me.TargetObject.GetAllBuff()) { Logging.Write("\nid: "+id.SpellId+" name: "+id.GetSpell.Name); } Logging.Write("Done."); }
You can also search for the "HaveBuff()" method with a decompiler, you'll see that some checking are different.
Usage(with demonstration video) of my prefered decompiler can be found here
-
Since with the .xml it's difficult to do it particular for this purpose(you might need to block some behaviors & add additional c#) you may port it to c# or wait for someone that could change the behavior.
So far i know there's no really clean workaround for this on xml fightclasses.
-
Hello, you could try to change "Calculate interact/combat distance by target size" at "General Settings" under tab "Class/Fights Class".
sending a shift+right-click to an inventory-item
in WRobot for Wow Vanilla - Help and support
Posted · Edited by reapler
I've changed the keys to press & the string to search. It should work now. The requirements to use it successfully are:
Wow.exe on foreground(it can reset the key on window switch) and the item must be in cache.