kpreisser / MouseClickSimulator

Mouse Click Simulator for Toontown Rewritten and Corporate Clash
MIT License
24 stars 17 forks source link

Ca we create a new action? #24

Closed Derooms closed 2 years ago

Derooms commented 7 years ago

I'm trying to write a script for fully automated gardening (moving and all). I tried to create a "pick flower" action but when i try to load it into the simulator (ofc I'm loading a .xml file with the action in it) the simulator says "Pick Flower could not be recognized as an action type". The file is Saved as .cs The file is in the Gardening folder inside the core The path to it is correct (I believe) The .xml file isn't the problem, I loaded quitfishing and it worked fine

Here's the code:

using System; using System.Text; using System.Threading.Tasks; using TTMouseclickSimulator.Core.Actions; using TTMouseclickSimulator.Core.Environment;

namespace TTMouseclickSimulator.Core.ToontownRewritten.Actions.Gardening

{ public class PickFlowerAction : AbstractAction { public override sealed async Task RunAsync(IInteractionProvider provider) { // Click on the "Pick Flower" button. await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(46, 210), VerticalScaleAlignment.Left); await provider.WaitAsync(200);

        // Click on the "Yes" button.
        await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(718, 598));
    }   

    public override string ToString() => "Pick Flower";
}

}

kpreisser commented 7 years ago

Hi @Derooms,

after creating a new class for the Action (PickFlowerAction), the second step is to allow the XML Project Deserializer to recognize the new action type. You can do this by adding the green line in the following diff for XmlProjectDeserializer.cs, so that a new entry for PickFlower in the actionTypes dictionary is added:

@@ -53,6 +53,8 @@ namespace TTMouseclickSimulator.Project

             actionTypes.Add("Speedchat", typeof(SpeedchatAction));

+            actionTypes.Add("PickFlower", typeof(PickFlowerAction));
+
             actionTypes.Add("Pause", typeof(PauseAction));
         }

After this, you will be able to use the new action in a XML project file:

  <PickFlower />

Please note about mouse coordinates: When calling MouseHelpers.DoSimpleMouseClickAsync(...) and specifying x/y coordinates, these are interpreted for a TT Window with a inner size of 1600x1151, with a 4:3 aspect ratio which the original Toontown had (this "reference size" is defined in class MouseHelpers).

In order to get the correct x/y values to click a button in TT Rewritten, you can set a 4:3 resolution in the TT Rewritten options, like 640x480, 800x600 or 1024x768; then get the x/y coordinates in that window, and calculating them like this (for 800x600):

simulatorX = screenshotX / 800 * 1600
simulatorY = screenshotY / 600 * 1151

For example, in the following screenshot that was taken with 640x480, it shows the "Pick Flower" button and the "Yes" button: ttr1_m3

The "Pick Flower" button here has the coordinates (31, 110) and the "Yes" button has coordinates (293, 321) (marked with a black cross). For the Mouse Click Simulator, these coordinates can now be calculated as follows: Pick Flower Button: (31 / 640 * 1600, 110 / 480 * 1151) = (78, 264) Yes Button: (293 / 640 * 1600, 321 / 480 * 1151) = (733, 770)

The next step is to identify if the alignment of the buttons is left, centered or right (in your sample code, this is already done correctly), because TT Rewritten does a scaling of the window so that its content has the correct aspect ratio, even if the window size doesn't have a 4:3 ratio. We can see this if we reduce the window height (but don't modify the window width): ttr2_m3

As the "Pick Flower" stays on the left hand side, we need to specify HorizontalScaleAlignment.Left for it in the DoSimpleMouseClickAsync call. The "Yes" button however is aligned towards the center, so we do not need to specify an alignment here (as Center is the default).

So, you can use the following code for the action:

        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Click on the "Pick Flower" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(78, 264),
                HorizontalScaleAlignment.Left);
            await provider.WaitAsync(200);

            // Click on the "Yes" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(733, 770));
        }

Edit: Please note that the new PickFlowerAction.cs file also needs to be part of the C# project file in order to be recognized by the compiler. If you're using an IDE like Visual Studio, it will do this automatically when adding a new C# class. Otherwise, when you are editing the files manually, you would need to add the green line to TTMouseclickSimulator.csproj:

@@ -69,6 +69,7 @@
     <Compile Include="Core\Actions\AbstractAction.cs" />
     <Compile Include="Core\Actions\AbstractActionContainer.cs" />
     <Compile Include="Core\Actions\IActionContainer.cs" />
+    <Compile Include="Core\ToontownRewritten\Actions\Gardening\PickFlowerAction.cs" />
     <Compile Include="Core\ToontownRewritten\Actions\Gardening\PlantFlowerAction.cs" />
     <Compile Include="Project\SimulatorProject.cs" />
     <Compile Include="Utils\TaskDialog.cs" />

Hope this helps!

Derooms commented 7 years ago

Helps a lot, unfortunately I don't have time during the week to work on it, but I'll try to get it done over the next weekend and post it here when it is

Keedros commented 1 year ago

Hey I'm trying to implement this fix into the .proj file, but I seem to keep running into an error when trying to add '< Compile Include="Core\ToontownRewritten\Actions\Gardening\PickFlowerAction.cs" / >' manually into the file.

It keeps coming back with a conflict that the .cs file is overriding the .proj file's inclusion. I was hoping it might just be a false positive, & tried running a test script for "PickFlowerAction", except it still doesn't recognize it as an action unfortunately.

I'm assuming it may have do with the streamlines to the code in the .proj file after this was posted, however I'm not too experienced in C# & have been having trouble finding a solution within the old .proj code compared to the newer streamlined version, so it seemed like asking you directly might be the best/only way to find a relative solution.