yangyuan/hearthrock

Battlecry targeting minions do not work as expected

Opened this issue · 6 comments

The code reports that it told it to target the correct target.
This has been discussed in #9 but imo needs its own issue.

What usually happens is it will:

  1. Say 'Shattered Sun Cleric > Friendly Minion'
  2. Click the battlecry minion
  3. Play the battlecry minion
  4. Not click who it was told to target with it
  5. Attempt to continue playing, usually results in the battlecry being used on the next friendly minion to attack, for example. Sometimes it just spasms out at this stage, constantly playing and canceling until it targets a random minion.

I saw you say in another thread that this could be caused by me? I am using the most up to date client, have based my bot off of the Python base example, and the command is properly "popped up" in game.

@lanhin Said that this is caused by: "playing the battlecry" is a targeted action [cleric, minion], but once it is placed (and not yet battlecried), it becomes a different PlayOption halfway through, similar to that of an attack. So now it is [cleric], [cleric, minion] if you want to play a battlecry minion.

This can probably be solved on the bot end by recognizing when a battlecry minion is asking for a target and thus choosing one.

I have exactly the same problem,
I looked in the debugger, and saw that both click method work as usual
sometimes, in the one game, it's can work one time(no matter first or not) then not work right after it

@lanhin Said that this is caused by: "playing the battlecry" is a targeted action [cleric, minion], but once it is placed (and not yet battlecried), it becomes a different PlayOption halfway through, similar to that of an attack.

After the bot give [cleric, minion], the engine should click/drop cleric, then minion. And during this time, the engine will not check PlayOption.

  1. Not click who it was told to target with it

I think the problem is the 4th step. I believe that the bot tried to do that but failed.

By default, the delay between actions is 1 sec. And if the state is RockPegasusGameState.Blocking, also delay 1 sec. There might be some special cases when the state should be RockPegasusGameState.Blocking but it isn't. Thus the game tried to click the target in a bad time and failed.

One way to debug is to increase the delays to see if the problem is gone. Another way is to trace RockEngineAction.Apply() to make sure the engine does try to click the target.
I don't have much time this week so someone is interested you can try first.

References:

https://github.com/yangyuan/hearthrock/blob/master/src/Hearthrock/Pegasus/Internal/RockPegasus.cs
GetPegasusGameState()

https://github.com/yangyuan/hearthrock/blob/master/src/Hearthrock/Engine/RockEngine.cs
OnRockGamePlay()
OnRockAction() (return 1)

https://github.com/yangyuan/hearthrock/blob/master/src/Hearthrock/Engine/RockEngineAction.cs

Another way is to trace RockEngineAction.Apply() to make sure the engine does try to click the target.

It works, just like I said, I saw it in a debugger

One way to debug is to increase the delays to see if the problem is gone.

I tried with bigger and smaller delay, but it's not help

We notice that it works fine, if we add this.pegasus.DropObject(); in this method:

`

    public void Apply()
    {
        RockGameHooks.PlayZoneSlotMousedOverValue = this.slot;
        RockGameHooks.EnablePlayZoneSlotMousedOver = true;

        // Pick source card
        if (this.step == 0)
        {
            this.pegasus.ClickObject(this.actions[0]);
        }
        else if (this.step == 1 && this.actions.Count == 1)
        {
            this.pegasus.DropObject();
        }
        else if (this.actions.Count > this.step)
        {
            // I add this line
            this.pegasus.DropObject();
            this.pegasus.ClickObject(this.actions[this.step]);
        }
        else
        {
            this.pegasus.DropObject();
        }

        this.step++;

        RockGameHooks.EnablePlayZoneSlotMousedOver = false;
        RockGameHooks.PlayZoneSlotMousedOverValue = -1;

        return;
    }

`

we tested battlecrys, target spells and attack

while we're waiting for hearthrock update, I add this patched assembly, so you can test battlecry

Assembly-CSharp.zip

  • extract Assembly-CSharp.dll to "~\Hearthstone\Hearthstone_Data\Managed" with replace
  • if you need change Hearthrock settings - run Hearthrock.Client, change settings (like bot type, game type) and click sync settings. Do not click the "patch" button.
  • also I added mine version of hearthrock.json (you can extract it to "~\Hearthstone\Hearthstone_Data\Managed" as well) if, for some reason, Hearthrock.Client will not sync your settings. You can open the file in notepad and change text manually

@AiSatan thanks for the suggestion, I've already included it in the current code. Next time you can directly create a pull request no matter how small the change is.

The fix doesn't seem to be perfect but it could be a temp solution as long as it works.

@ALL sorry for my absence during the discussion. I have a few interviews on-going so I pretty much give priorities to preparing the interviews. I will be back as soon as I get them done.