Jump to content

1.12.1 healbot fightclass target-free LUA spellcast error


Recommended Posts

I'm amending a holy priest healBot fightclass profile for vanilla 1.12.1, and I'm stuck.  As it stands now, I am able to run the code as an non-compiled .cs fightclass.  I've even added a rudimentary decurse engine.  However, I am irritated that the bot needs to use Interact.InteractGameObject to actively target myself and other players in order to cast heals and other beneficial spells.  My goal is to cast spells on partymembers without having to switch targets.

I've searched the forums and found a few promising avenues:

1) Focus frame method: [Holy - Paladin] The Holy Grail 17.06.22b
Built for 3.3.5a/2.4.3.  Source link.  This healbot uses the focus frame to cast spells on the intended target.  Unfortunately, since I am building for 1.12.1 client, there is no focus.Guid functionality.  There are addons that provide /focus functionality, but AFAIK those are not addressable from wrobot.  Dead end for now.

2) Execute LUA code: 5006-cast-spell-without-targeting
User iMod points out that this is possible, but didn't specifically state whether he's tested this in 1.12.1.  I tried the following code snippet:

(I altered the LUA string to not rely on string interpolation as in iMod's example, since I am running .cs source and not compiling to .DLL)

if (target.Guid == ObjectManager.Me.Guid)
{
    // Cast on self
    Lua.LuaDoString("CastSpellByID (2061, \"player\")");
}

That returned the following error in the wow console:

ERROR: [string "Yofewupyo.lua"]:13: attempt to call global 'CastSpellByID' (a nil value)

I get the same error in the wow console when using c# code instead, as Droidz suggests

wManager.Wow.Helpers.SpellManager.CastSpellByIdLUA(2061, "player");

I also got rid of all addons, still no joy:

[string "esurut.lua"]:13: attempt to call global 'CastSellByID' (a nil value)

Any idea why I'm getting this error?  Thanks for your time! ?

Link to comment
Share on other sites

3 minutes ago, srazdokunebil said:

I'm amending a holy priest healBot fightclass profile for vanilla 1.12.1, and I'm stuck.  As it stands now, I am able to run the code as an non-compiled .cs fightclass.  I've even added a rudimentary decurse engine.  However, I am irritated that the bot needs to use Interact.InteractGameObject to actively target myself and other players in order to cast heals and other beneficial spells.  My goal is to cast spells on partymembers without having to switch targets.

I've searched the forums and found a few promising avenues:

1) Focus frame method: [Holy - Paladin] The Holy Grail 17.06.22b
Built for 3.3.5a/2.4.3.  Source link.  This healbot uses the focus frame to cast spells on the intended target.  Unfortunately, since I am building for 1.12.1 client, there is no focus.Guid functionality.  There are addons that provide /focus functionality, but AFAIK those are not addressable from wrobot.  Dead end for now.

2) Execute LUA code: 5006-cast-spell-without-targeting
User iMod points out that this is possible, but didn't specifically state whether he's tested this in 1.12.1.  I tried the following code snippet:

(I altered the LUA string to not rely on string interpolation as in iMod's example, since I am running .cs source and not compiling to .DLL)


if (target.Guid == ObjectManager.Me.Guid)
{
    // Cast on self
    Lua.LuaDoString("CastSpellByID (2061, \"player\")");
}

That returned the following error in the wow console:


ERROR: [string "Yofewupyo.lua"]:13: attempt to call global 'CastSpellByID' (a nil value)

I get the same error in the wow console when using c# code instead, as Droidz suggests


wManager.Wow.Helpers.SpellManager.CastSpellByIdLUA(2061, "player");

I also got rid of all addons, still no joy:


[string "esurut.lua"]:13: attempt to call global 'CastSellByID' (a nil value)

Any idea why I'm getting this error?  Thanks for your time! ?

There is no such thing as "CastSpellByID" in vanilla. ?

Link to comment
Share on other sites

1 hour ago, srazdokunebil said:

Thanks for the quick reply!  It's too bad that the unoffical API docs don't have version specificity.  Is it possible at all to cast spells onto a friendly unit without targeting them in vanilla?

This is not a wrobot thing. This is a wow thing. ?
You can always check the wow wiki and use the "history" button to see if stuff is in Vanilla or not.
I don't think it's possible, been a while since i did healing stuff for vanilla though. ?

There are workarounds to cast spells using "id" by using GetSpellInfo()

https://wowwiki.fandom.com/wiki/API_GetSpellInfo?oldid=1291791

Using this you can use CastSpellByName(GetSpellInfo(551)) replace 551 with any spell ID
HOWEVER CastSpellByName only has an "on self" argument, which means you can either cast it on yourself or on your target. It's useful for stuff like selfbuffing, dispelling, decursing etc. since you won't need to relieve your target.

Next thing:
You can use TargetLastTarget to achieve "Healing target without targeting them". In a sense, you will be targeting your party member, casting your spell then targeting whatever you targeted before this. (This will look like you never changed target). ?
https://wowwiki.fandom.com/wiki/API_TargetLastTarget?oldid=21935

Link to comment
Share on other sites

On 5/28/2019 at 4:28 PM, Ordush said:

There are workarounds to cast spells using "id" by using GetSpellInfo()
https://wowwiki.fandom.com/wiki/API_GetSpellInfo?oldid=1291791

Using this you can use CastSpellByName(GetSpellInfo(551)) replace 551 with any spell ID
HOWEVER CastSpellByName only has an "on self" argument, which means you can either cast it on yourself or on your target. It's useful for stuff like selfbuffing, dispelling, decursing etc. since you won't need to relieve your target.
 

It Works!

Unfortunately, none of those LUA functions worked from the 1.12.1 client.  Several functions including GetSpellInfo(), invoked in the game client from a /script macro (not from the c# scrript) returns a LUA error complaining that the function doesn't exist.  Maybe it's me making a mistake, or I have a Frankenstein copy of 1.12.1.  Who knows.

I was, however, able to get CastSpellByName() to play ball:

public static void SetMouseoverUnit(WoWUnit unit)
{
    wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(
        (uint)wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, unit.Guid);
}

public static void CastOn(WoWUnit unit, Spell spell)
{
    float i = spell.CastTime;
    i = i * 1000 + 1500;
    int myint = Convert.ToInt32(i);
    
    Logging.WriteDebug("Casting " + spell.Name + " on " + unit.Name + " ..Cast time == " + i + " Type = " + myint);

    SetMouseoverUnit(unit);
    //WORKED: string cast = (@"TargetUnit(""mouseover""); CastSpellByName(""Flash Heal""); TargetLastTarget();");
    string cast1 = (@"TargetUnit(""mouseover""); CastSpellByName(""");
    string cast2 = (@"""); TargetLastTarget();");
    Lua.LuaDoString(cast1 + spell.Name + cast2);
    
    Thread.Sleep(myint);
}

The bad:

  • Yep, this code is ugly.  But it gets the job done. *shrug*
  • wRobot's cs parser version doesn't do '@' verbatim strings, and I'm not yet inclined to make a whole .csproj of this thing, so please excuse the string fuckery at the bottom.
  • I've found *no* c# or LUA method that could derive whether I am casting.  I've gone through the forums, pored over code and determined that, while using 1.12.1 + wRobot:
    • ObjectManager.Me.IsCast always returns false
    • every possible LUA function capable of determining my casting state returns an error
    • ..so that why I'm using a Thread.Sleep here.

The Good:

  • It works, casting heals on myself and partymembers without switching targets.
  • The mouseover workaround was pointed out by reapler & Matenia in the following thread.

Thank you so much for your help!

 

 

 

Link to comment
Share on other sites

2 minutes ago, srazdokunebil said:

It Works!

Unfortunately, none of those LUA functions worked from the 1.12.1 client.  Several functions including GetSpellInfo(), invoked in the game client from a /script macro (not from the c# scrript) returns a LUA error complaining that the function doesn't exist.  Maybe it's me making a mistake, or I have a Frankenstein copy of 1.12.1.  Who knows.

I was, however, able to get CastSpellByName() to play ball:


public static void SetMouseoverUnit(WoWUnit unit)
{
    wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(
        (uint)wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, unit.Guid);
}

public static void CastOn(WoWUnit unit, Spell spell)
{
    float i = spell.CastTime;
    i = i * 1000 + 1500;
    int myint = Convert.ToInt32(i);
    
    Logging.WriteDebug("Casting " + spell.Name + " on " + unit.Name + " ..Cast time == " + i + " Type = " + myint);

    SetMouseoverUnit(unit);
    //WORKED: string cast = (@"TargetUnit(""mouseover""); CastSpellByName(""Flash Heal""); TargetLastTarget();");
    string cast1 = (@"TargetUnit(""mouseover""); CastSpellByName(""");
    string cast2 = (@"""); TargetLastTarget();");
    Lua.LuaDoString(cast1 + spell.Name + cast2);
    
    Thread.Sleep(myint);
}

The bad:

  • Yep, this code is ugly.  But it gets the job done. *shrug*
  • wRobot's cs parser version doesn't do '@' verbatim strings, and I'm not yet inclined to make a whole .csproj of this thing, so please excuse the string fuckery at the bottom.
  • I've found *no* c# or LUA method that could derive whether I am casting.  I've gone through the forums, pored over code and determined that, while using 1.12.1 + wRobot:
    • ObjectManager.Me.IsCast always returns false
    • every possible LUA function capable of determining my casting state returns an error
    • ..so that why I'm using a Thread.Sleep here.

The Good:

  • It works, casting heals on myself and partymembers without switching targets.
  • The mouseover workaround was pointed out by reapler & Matenia in the following thread.

Thank you so much for your help!

 

 

 

Again use the wiki to see what works for Vanilla.
I just noticed my link was from 2008 (TBC) so no GetSpellInfo does not work. ?

Link to comment
Share on other sites

37 minutes ago, Matenia said:

Fyi, you can use ObjectManager.Me.CastingSpell to check for a name in vanilla.
https://github.com/Schaka/VanillaFightclassFramework already has everything you could need to determine casts, switching targets, etc.
 

Oho!  That's a game changer..  I might have to setup Visual Studio to compile this into a DLL now.  Thanks for the heads up, Matenia.

Link to comment
Share on other sites

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...