Jump to content

Preventing an istant spell to be casted (UNIT_SPELLCAST_SENT)


Recommended Posts

Hello, I was messing around with the even handler in lua and I was wondering if there is a way to cancel the spell after you pressed it.

The best result i've achieved is when I try to cast a certain spell (for example: Bloodlust), and the script will SpellStopCasting(), blocking immediately the cast as soon as it starts. basically making me unable to cast it. But when the spell is not a cast, and it's an istant spell (for example: Riptide), the script freeze the game for a second, then unfreeze with the spell casted. Which is not what I wanted.

In few words, can I stop an istant spell fired with UNIT_SPELLCAST_SENT? Or when that event starts, it's too late to block it?

Thanks for reading :)

Modify your event listener to check to see if the spell that is being casted has a cast time  less than or equal  0. I have no idea what SpellStopCasting() does, but the below should work.

    private void watchForCast()
    {

        EventsLuaWithArgs.OnEventsLuaWithArgs += (LuaEventsId id, List<string> args) =>
        {

            if (id == wManager.Wow.Enums.LuaEventsId.UNIT_SPELLCAST_SENT)
            {
                if (instantCast(new Spell(args[1])) == false)
                {
                    SpellStopCasting();
                }
            }

        };

    }

    private bool instantCast(Spell spell)
    {

        return (spell.CastTime <= 0);

    }

I forgot to mention I was writing that entirely on LUA and using pqr, so I can't put C code in it (at least i think). Also I'm not skilled enough on C language so I can't understand that code 100%.

The reason of my question is because I came across a guy who claimed he has some pqr scripts that do certain things which seemed weird to me, and I wanted to try by myself if that could been done for real, I never thought about that:

" [Hammer of Justice]: Will not be used if [Cloak of Shadows]/[Ice Block]/[Bladestorm]/[Spell Reflection] or any other spell that prevents you from landing it is up.
This script will stop you from casting [Hammer of Justice] if any of the spells stated above are up."


This is what he wrote. I mean I can understand a SpellStopCasting() when there is Spell Reflection up and you are casting so you avoid being reflected, it's not hard its like 2 rows of code... but how can a script prevent you from casting an istant spell, like Hammer of Justice?

So there are two ways:
1) The script has an automatic Hammer of Justice cast (which is completely idiot imho, what's the point?), and before casting it, it checks target's buffs.
2) The script blocks you from manually casting Hammer of Justice by mistake, like target with Cloak of Shadows.

If its the first option well it's the worst script ever for sure and I don't see how can people find that useful, if it's the second, that would be actually a good script for pvp (even if it's not hard to check target buffs before using a certain spell on it..) but it's still interesting code talking.

6 hours ago, scripterx said:

I forgot to mention I was writing that entirely on LUA and using pqr, so I can't put C code in it (at least i think). Also I'm not skilled enough on C language so I can't understand that code 100%.

The reason of my question is because I came across a guy who claimed he has some pqr scripts that do certain things which seemed weird to me, and I wanted to try by myself if that could been done for real, I never thought about that:

" [Hammer of Justice]: Will not be used if [Cloak of Shadows]/[Ice Block]/[Bladestorm]/[Spell Reflection] or any other spell that prevents you from landing it is up.
This script will stop you from casting [Hammer of Justice] if any of the spells stated above are up."


This is what he wrote. I mean I can understand a SpellStopCasting() when there is Spell Reflection up and you are casting so you avoid being reflected, it's not hard its like 2 rows of code... but how can a script prevent you from casting an istant spell, like Hammer of Justice?

So there are two ways:
1) The script has an automatic Hammer of Justice cast (which is completely idiot imho, what's the point?), and before casting it, it checks target's buffs.
2) The script blocks you from manually casting Hammer of Justice by mistake, like target with Cloak of Shadows.

If its the first option well it's the worst script ever for sure and I don't see how can people find that useful, if it's the second, that would be actually a good script for pvp (even if it's not hard to check target buffs before using a certain spell on it..) but it's still interesting code talking.

check the casttime of all spells before they are casted. If the cast time is greater than 0, then stop casting. If it's 0, then cast.

 

And I'm the opposite :D. I can read LUA, but it's definitely not my forte.

2 hours ago, avvi said:

check the casttime of all spells before they are casted. If the cast time is greater than 0, then stop casting. If it's 0, then cast.

 

And I'm the opposite :D. I can read LUA, but it's definitely not my forte.

I think you meant if cast time < or = 0 then stop casting (you said: cast). But that's not the point I think..Because as already said, I tried with random spell casts and it successfuly stops them at like 0,01 sec of cast time, preventing them from landing. But when it's an istant spell, it can't cancel it, it's like i'm trying to stop a ball after it gets kicked really hard.

Like in reality, I can stop the football player running towards the ball from distance and charging his feet, but once he kicks the ball there's nothing I can do to freeze the ball on the ground. What I'm trying to do is make the ball attached to the ground so it can't move despite being kicked.

12 minutes ago, scripterx said:

I think you meant if cast time < or = 0 then stop casting (you said: cast).

In my C# example, it would be Cast.. because the event triggers based upon the spell beginning to cast. So, once the bot sees that it's a spell that has a cast time, it will stop the cast.

If your goal is to stop casting based on some sort of 'event'/'trigger', then I agree that checking to see if it's an instant cast/not one is irrelevant. I re-read your message, and I see that i completely glossed over your actual question. My mistake. 

Quote

And more than likely,  "can I stop an istant spell fired with UNIT_SPELLCAST_SENT? Or when that event starts, it's too late to block it?"

I think it is too late to block the spell.  I think the best thing to do is to check your condition before casting anything.

Oh i see, I was thinking in a lua way ;)

Well idk how to explain.. basically the "UNIT_SPELLCAST_SENT" is the request you send to the server to launch a spell, and assuming conditions are true (target is in line of sight, in range...) then it triggers immediately SPELL_CAST_START (means the server accepted your request and the spell is going to land). So when this happens, the istant spell lands succesfully in a matter of milliseconds, while the spell with a cast time instead, begins to cast, and that's why I can stop this and not the other one.

So I want to have the request denied from the server, blocking me from doing that spell. Like having a message "is out of range" "not in the line of sight", something like this.

It's just curiosity, since that guy wrote that thing about the hammer of justice I was curious how it could even work.

 

20 minutes ago, scripterx said:

Oh i see, I was thinking in a lua way ;)

Well idk how to explain.. basically the "UNIT_SPELLCAST_SENT" is the request you send to the server to launch a spell, and assuming conditions are true (target is in line of sight, in range...) then it triggers immediately SPELL_CAST_START (means the server accepted your request and the spell is going to land). So when this happens, the istant spell lands succesfully in a matter of milliseconds, while the spell with a cast time instead, begins to cast, and that's why I can stop this and not the other one.

So I want to have the request denied from the server, blocking me from doing that spell. Like having a message "is out of range" "not in the line of sight", something like this.

It's just curiosity, since that guy wrote that thing about the hammer of justice I was curious how it could even work.

 

It may be possible. I may even be wrong about something i said above. Hopefully someone else can chime in on this.

I would pay his stupid script just to see how he wrote that HoJ thing, really. His "rotations" are really bad and cheap but that function bothers me so much ahah :)

Makes me think that the HoJ is automated (like target: low health) but won't be casted in certain conditions (ice block)..which is a joke to script honestly.

It's easy enough. All spells the client casts through the interface inevidbly go through CastSpellByName() (in Lua).
Therefore, you can overwrite CastSpellByName with your own function, do a condition for HoJ and just make it do nothing if target has CoS etc.

Do I think that guy is actually doing it that way? Probably not. He's likely just boasting/lying about something he has done in a way more simplistic way.

3 minutes ago, Matenia said:

It's easy enough. All spells the client casts through the interface inevidbly go through CastSpellByName() (in Lua).
Therefore, you can overwrite CastSpellByName with your own function, do a condition for HoJ and just make it do nothing if target has CoS etc.

Do I think that guy is actually doing it that way? Probably not. He's likely just boasting/lying about something he has done in a way more simplistic way.

That's exactly my thoughts. doing the override just makes more sense here.

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.

  • 2 weeks later...

Alright I'm very close to the solution (even if I realize it's kinda useless)..I'm glad that I can made it work, and yes thanks to your support and suggestions obviously. Basically there is a command "hooksecurefunc" which pretty much does the job. I redirect the CastSpellByName and also CastSpellByID (just in case) with a function and it's ok, the weird part is:

I tested with a Priest just the istant spells, it blocks for example the Shadowform, Dispersion, almost everything. But doesn't block Holy Nova, Prayer of Mending. So I said, maybe it doesnt block Holy spells, but guess what, Power Word: Shield is blocked..I mean what's the difference between PW:S and Holy Nova? I don't get it. if the command stop almost every istant spell why does it let me cast Holy nova and not PW:S?

Talking about spell with cast time, it doesn't block them at all. I don't know why?

Not a big deal, but the thing that blocks only some spell and other not its really really weird I can't understand

Actionbuttons use the function "UseAction" as far as I'm aware.
Could try hooking that. I'm not entirely sure how buttons cast the spell internally, but I know it goes through that function at some point.

1 hour ago, scripterx said:

Alright I'm very close to the solution (even if I realize it's kinda useless)..I'm glad that I can made it work, and yes thanks to your support and suggestions obviously. Basically there is a command "hooksecurefunc" which pretty much does the job. I redirect the CastSpellByName and also CastSpellByID (just in case) with a function and it's ok, the weird part is:

I tested with a Priest just the istant spells, it blocks for example the Shadowform, Dispersion, almost everything. But doesn't block Holy Nova, Prayer of Mending. So I said, maybe it doesnt block Holy spells, but guess what, Power Word: Shield is blocked..I mean what's the difference between PW:S and Holy Nova? I don't get it. if the command stop almost every istant spell why does it let me cast Holy nova and not PW:S?

Talking about spell with cast time, it doesn't block them at all. I don't know why?

Not a big deal, but the thing that blocks only some spell and other not its really really weird I can't understand

Technically Holy Nova is a Holy spell and PW:S is a discipline spell :) SO THERE'S A DIFFERENCE!!!

51 minutes ago, Matenia said:

Actionbuttons use the function "UseAction" as far as I'm aware.
Could try hooking that. I'm not entirely sure how buttons cast the spell internally, but I know it goes through that function at some point.

Will try this ! :)

 

8 minutes ago, avvi said:

Technically Holy Nova is a Holy spell and PW:S is a discipline spell :) SO THERE'S A DIFFERENCE!!!

Ya actually there is :P

7 minutes ago, avvi said:

Can you post your code here so that others can see? (myself included :))

Sure (this is the basic code just for test, there are no conditions added so it blocks every kind of action, even using trinkets.

 

hooksecurefunc("UseAction", function(...)
    return true
end)

UseAction = function(...)
   print("UseAction Stopped")
end

 

 

The "hooksecurefunc" is not necessary in that case I think, since every action is replaced by a simple "print" (just for test).

I need to add conditions like for example, block spell cast if spell = "Deep Freeze" and target has buff = "Icebound Fortitude", something like that..That posted code it's a very cheap base to start working on. Maybe I will complete it, will update in case :)

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...