Seminko 40 Posted November 2, 2017 Share Posted November 2, 2017 Right, so based on my previous experience with moving after frostnova I now know tha for something like this I will need FightEvents.OnFightLoop. The idea is simple, however with my limited knowledge of CSharp I was not able to make this work reliably and/or as smooth as I would like to. The scripting language I'm familiar with is AutoIt and if I was using that I would grab the attacking units, put them into an array, polymorph the second, make the script remember which mob index I polymorphed and go back to any other index. Or grab all the mobs attacking me into an array, polymorph any of them really, probably the one that I have targetted to make it simple, and then do a for loop to loop through them all and check for unit.HaveBuff("Polymorph"), find the first that doesn't have it and attack. I have tried several versions but I always hit a brick wall due to my CSharp ignorance. Here's my total pseudo code (don't laugh too hard, or do :-D ) that works but only somewhat. It correctly casts poly, switches target but unfortunately once the target is dead the bot doesn't start fighting with the polymorphed mob. Despite being in combat it considers itself not fighting and tries to move on. The worst scenario is when I have 'Pause if player nearby' selected, once I kill the non-poly mob and player is nearby, it stops, sits there and takes the punishment from the recently unpolymorphed mob. Spoiler var unitsAffectingMyCombat = ObjectManager.GetUnitAttackPlayer(); if (unitsAffectingMyCombat.Count == 2) // if there are two attackers then do... { Logging.Write("START COMBAT ROTATION FIRST IF STATEMENT"); SpellManager.CastSpellByNameLUA("Polymorph"); // cast poly // wait until one mob has poly and set it as var unitsWithPoly var unitsWithPoly = unitsAffectingMyCombat.Where(u => u != null && u.IsValid && u.HaveBuff("Polymorph")).ToList(); var unitToAttackPoly = unitsWithPoly.OrderBy(unitLow => unitLow.HealthPercent).FirstOrDefault(); while (unitsWithPoly.Count == 0) { unitsWithPoly = unitsAffectingMyCombat.Where(u => u != null && u.IsValid && u.HaveBuff("Polymorph")).ToList(); unitToAttackPoly = unitsWithPoly.OrderBy(unitLow => unitLow.HealthPercent).FirstOrDefault(); Thread.Sleep(1000); Logging.Write("WAITING FOR POLY"); } int countWithPoly = unitsWithPoly.Count; string countWithPolyString = countWithPoly.ToString(); Logging.Write("unitsWithPoly = " + countWithPolyString); // check how many mobs DO NOT have poly and pick one with lower HP var unitsAttackMe = unitsAffectingMyCombat.Where(u => u != null && u.IsValid && !u.HaveBuff("Polymorph")).ToList(); var unitToAttack = unitsAttackMe.OrderBy(unitLow => unitLow.HealthPercent).FirstOrDefault(); int countOrigo = unitsAttackMe.Count; string countOrigoString = countOrigo.ToString(); Logging.Write("unitsAttackMe = " + countOrigoString); // at this point there is one mob with poly and one mob without poly FightEvents.OnFightLoop += (unit, cancelable) => { Logging.Write("LOOP"); if (unitToAttack != null && unitToAttack.IsValid && unitToAttack.IsAlive && !unitToAttack.IsMyTarget) // if the mob without poly is not my target, switch to it { Interact.InteractGameObject(unitToAttack.GetBaseAddress, !ObjectManager.Me.GetMove); cancelable.Cancel = true; } else if ((unitToAttack == null || !unitToAttack.IsValid || !unitToAttack.IsAlive) && unitToAttackPoly != null && unitToAttackPoly.IsValid && unitToAttackPoly.IsAlive && !unitToAttackPoly.IsMyTarget) // if the mob without poly is dead and the mob with poly is alive start fighting with it. { Interact.InteractGameObject(unitToAttackPoly.GetBaseAddress, !ObjectManager.Me.GetMove); Fight.StartFight(unitToAttackPoly.GetBaseAddress); cancelable.Cancel = true; } }; } There must be a clean way to do this. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/ Share on other sites More sharing options...
Marsbar 228 Posted November 2, 2017 Share Posted November 2, 2017 You don't need to use onfightloop. This could be an if in your rotation. Once again, I can't test right now but I don't see why the below couldn't do the trick (there are probably cleaner ways to do it): List<WoWUnit> attackers = ObjectManager.GetUnitAttackPlayer(); if (attackers.Count > 1) { WoWUnit mainTarget = attackers.Where(u => u.HealthPercent == attackers.Min(x => x.HealthPercent)).FirstOrDefault(); WoWUnit polyTarget = attackers.Where(u => u.HealthPercent == attackers.Max(x => x.HealthPercent)).FirstOrDefault(); if (!polyTarget.HaveBuff("Polymorph") && polyTarget != mainTarget) { Interact.InteractGameObject(polyTarget.GetBaseAddress); SpellManager.CastSpellByNameLUA("Polymorph"); Thread.Sleep(500); Interact.InteractGameObject(mainTarget.GetBaseAddress); } } ~edit: you'd probably want to add some more conditions to make sure polymorph is known etc. benben 1 Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34405 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 That will most likely result in the bot just throwing around random targeting. You absolutely NEED to do this during on the OnFightLoop and cancel all other events. As for polymorphs not being valid targets - it's because they don't target you. That's why the bot doesn't know it's being attacked. You need to actively start a fight with them again (build this into your fightclass). I had the same problem in TBC. To avoid the bot trying to polymorph another target when pulling more mobs, you can sort them by Guid + HP + Level + Entry, that should result in always the same target being selected. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34406 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 3 minutes ago, Matenia said: That will most likely result in the bot just throwing around random targeting. You absolutely NEED to do this during on the OnFightLoop and cancel all other events. That's true Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34407 Share on other sites More sharing options...
Marsbar 228 Posted November 2, 2017 Share Posted November 2, 2017 45 minutes ago, Matenia said: That will most likely result in the bot just throwing around random targeting. Can you explain to me why that would be? We have a defined poly target and a main target? The only issue I could think of is that the polytarget could change because there could be multiple mobs at 100% hp. You could get around that though with another condition Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34408 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 Well the way I understand it is that if you don't use OnFightLoop and you call InteractGameObject and it instantly switches back to the original target, the one bot decided to target. I can polymorph a mob but it will keep it targetted until it dies despite InteractGameObject switching to a different target. So if the bot targets MOB1 and you InteractGameObject with MOB2 and cast Poly, it might work. But if the bot targets MOB1 and you poly MOB1, it will keep switching between MOB2 and MOB1. I guess it could work if polytarget was NOT my original target. Marsbar 1 Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34410 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 1 hour ago, Matenia said: You absolutely NEED to do this during on the OnFightLoop and cancel all other events. How do I cancel all other events? I tried cancelable.Cancel = true within my OnFightLoop and I'm not 100% convinced it cancelled my main fight loop. God damn, I'm totally lost :-D EDIT: the thing is, if we do this (WoWUnit mainTarget = attackers.Where(u => u.HealthPercent == attackers.Min(x => x.HealthPercent)).FirstOrDefault();) inside an OnFightLoop it will "forget" the poly target, won't it? Because it will get redefined everytime it loops... Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34411 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 1 hour ago, Seminko said: Well the way I understand it is that if you don't use OnFightLoop and you call InteractGameObject and it instantly switches back to the original target, the one bot decided to target. I can polymorph a mob but it will keep it targetted until it dies despite InteractGameObject switching to a different target. So if the bot targets MOB1 and you InteractGameObject with MOB2 and cast Poly, it might work. But if the bot targets MOB1 and you poly MOB1, it will keep switching between MOB2 and MOB1. I guess it could work if polytarget was NOT my original target. Pretty much this. Plus, since the bot runs on another thread, sometimes it switches your target back BEFORE your poly cast even starts. Then you end up polying 2 targets back and forth and looking like a retard. Basically why Jasabi could never get polymorph to work correctly, I believe. cancelable.Cancel = true is correct. However, I recommend NOT breaking the OnFightLoop event handler UNTIL your target has been successfully polymorphed. You can solve this with a while loop (Thread.Sleep inside) until poly is on another target. Marsbar 1 Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34412 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 1 hour ago, Matenia said: cancelable.Cancel = true is correct. However, I recommend NOT breaking the OnFightLoop event handler UNTIL your target has been successfully polymorphed. You can solve this with a while loop (Thread.Sleep inside) until poly is on another target. Just so I understand... From my testing today I found out that if I have OnFightLoop it combines my BAU rotation with the OnFightLoop rotation. It doesn't really seem it superseeds the BAU rotation. So if I go cancelable.Cancel = true; what will it cancel? The OnFightLoop rotation or everything else except the OnFightLoop rotation? Can Cancel be used from within the OnFightLoop? Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34417 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 You're cancelling the fight loop, which is like re-targeting enemies and such. Rather, one interation on the loop. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34418 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 Sorry, I don't follow. My understanding is the OnFightLoop "loop" is acting like a while loop everytime I'm in combat, doing its thing continuously. Let's say, if I have the code below and the first argument would be true, cancelable.Cancel would be set to true, what would happen? It would skip the second if argument in the OnFightLoop and start right from the start? FightEvents.OnFightLoop += (unit, cancelable) => { if (ObjectManager.Target.GetDistance <= 8 && (!ObjectManager.Target.HaveBuff("Frost Nova") || !ObjectManager.Target.HaveBuff("Frostbite")) && (_timerFrostNova == null || _timerFrostNova.IsReady) && ObjectManager.Target.HealthPercent >= 20) { Move.StrafeRight(Move.MoveAction.PressKey, 1250); cancelable.Cancel = true; } if (ObjectManager.Target.GetDistance <= 10 && (!ObjectManager.Target.HaveBuff("Frost Nova") || !ObjectManager.Target.HaveBuff("Frostbite")) && (_timerFrostNova == null || _timerFrostNova.IsReady) && ObjectManager.Target.HealthPercent >= 20) { Move.StrafeLeft(Move.MoveAction.PressKey, 1250); } }; If that is the case can I disable OnFightLoop? I'm looking at the += and thinking if I did -= it would somehow remove things from the OnFightLoop? If so, how? Btw guys, this is great, this is how I like to learn, not sitting in books, that doesn't work for me at all. I have to dive right in and figure things out on real life examples. ;) Thanks for being so helpful! Nireves 1 Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34419 Share on other sites More sharing options...
Marsbar 228 Posted November 2, 2017 Share Posted November 2, 2017 8 minutes ago, Seminko said: Btw guys, this is great, this is how I like to learn, not sitting in books, that doesn't work for me at all. I have to dive right in and figure things out on real life examples. ;) Thanks for being so helpful! 100% agree Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34420 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 You are actually subscribing to an event (hence the term event handler).https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events So your entire code ALWAYS gets executed - but whatever follows this event (the original fighting code by wRobot) can be stopped by setting cancelable.Cancel to true. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34421 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 4 minutes ago, Matenia said: You are actually subscribing to an event (hence the term event handler).https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events So your entire code ALWAYS gets executed - but whatever follows this event (the original fighting code by wRobot) can be stopped by setting cancelable.Cancel to true. So both the OnFightLoop and my FightClass code will get executed, the only thing we are cancelling is wrobot's "default built in" fighting code / behavior? That's strange, kind of. If that is so, what would happen if I did: FightEvents.OnFightLoop += (unit, cancelable) => { cancelable.Cancel = true; }; Well, time to experiment... Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34423 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 The easiest way to test this is subscribing to OnFightStart. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34424 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 Absolutely noob question. Inside the OnFightLoop I have WoWUnit currentTarget = etc.etc. What the heck do I need to do to be able to use it in an IF statement outside of the OnFightLoop? I want to test using it in my main rotation "if polyTarget.IsValid" (now gives an error) and if that is true I want to do "Interact.InteractGameObject(polyTarget.GetBaseAddress);" which also gives an error, saying it doesn't exist in the current context. Do I need to define it at the start? What type do I define it as? Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34430 Share on other sites More sharing options...
Matenia 628 Posted November 2, 2017 Share Posted November 2, 2017 You need to define the variable outside of the scope of the event handler (onfightloop eventhandler) and then assign it inside the event handler. I'm not sure why you need that to achieve it? Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34431 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 I'm trying to save the polyTarget but I guess i can grab it manually after the fact. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34432 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 Well no luck, as I was saying the OnFightLoop and my BAU rotation are being combined together. So instead of casting polymorph, it tries to cast Frostbolt all the time... Dang it... Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34433 Share on other sites More sharing options...
Seminko 40 Posted November 2, 2017 Author Share Posted November 2, 2017 So I made it work. I basically used a bool inside the OnFightLoop and set it to true when there are more than 1 mob attacking me. While true my BAU combat rotation won't trigger... once the Poly is applied, the bool is set to false and normal combat continues. To wake the sheep just CastSpellByNameLUA. Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-34436 Share on other sites More sharing options...
TheSmokie 242 Posted July 20, 2019 Share Posted July 20, 2019 List<WoWUnit> attackers = ObjectManager.GetUnitAttackPlayer(); FightEvents.OnFightLoop += (unit, cancelable) => { if (attackers.Count > 1 && Polymorph.KnownSpell && Polymorph.IsSpellUsable && ObjectManager.Target.GetDistance <= 25 && presence.KnownSpell && presence.IsSpellUsable) { WoWUnit mainTarget = attackers.Where(u => u.HealthPercent == attackers.Min(x => x.HealthPercent)).FirstOrDefault(); WoWUnit polyTarget = attackers.Where(u => u.HealthPercent == attackers.Max(x => x.HealthPercent)).FirstOrDefault(); if (!polyTarget.HaveBuff("Polymorph") && polyTarget != mainTarget) { SpellManager.CastSpellByNameOn("Polymorph", polyTarget.Name); Usefuls.WaitIsCasting(); return; } } }; (non tested) Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-55145 Share on other sites More sharing options...
Grogy 2 Posted June 18, 2020 Share Posted June 18, 2020 Hello, for any1 who needs, I have implemented working polymorph offtarget with attacking poly after mainTarget is dead. Its quite reliable unsless there are 2 polyTargets - 2 mobs with same name and level pulled after mainTarget. If you guys could make a workaround, please share, but I will deffinitelly try to overcome it too (mby just run from them is a solution). List<WoWUnit> attackers = ObjectManager.GetUnitAttackPlayer(); if (attackers.Count >= 2 && PolyMorph.KnownSpell) { FightEvents.OnFightLoop += (unit, cancelable) => { WoWUnit mainTarget = attackers.Where(u => u.HealthPercent == attackers.Min(x => x.HealthPercent)).FirstOrDefault(); WoWUnit polyTarget = attackers.Where(u => u.HealthPercent == attackers.Max(x => x.HealthPercent)).FirstOrDefault(); if (!polyTarget.HaveBuff("Polymorph") && polyTarget != mainTarget && !ObjectManager.Me.IsDeadMe && !mainTarget.IsDead && !polyTarget.IsDead) { Interact.InteractGameObject(polyTarget.GetBaseAddress); SpellManager.CastSpellByNameLUA("Polymorph"); Usefuls.WaitIsCasting(); Interact.InteractGameObject(mainTarget.GetBaseAddress); } else if (mainTarget.IsDead && !polyTarget.IsDead && !ObjectManager.Me.IsDeadMe) { Interact.InteractGameObject(polyTarget.GetBaseAddress); SpellManager.CastSpellByIdLUA(116); Thread.Sleep(500); } }; return; } Link to comment https://wrobot.eu/forums/topic/7541-switch-target-polymorph-switch-to-original-target/#findComment-58878 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now