Jump to content

[1.8.0]Perform/Simulate Mouse Click


JB4546

Recommended Posts

Hello,

 

I'm trying to create a mod that can simulate clicks. I've used the swingItem() method, however this simply plays an animation (i believe).

I need the click to be able to interact as a normal mouse click, damage/kill mobs as an example.

 

I figured there would be some kind of PerformClick method I could call, but can't seem to find one.

 

Any help is appreciated, thanks.

Link to comment
Share on other sites

Simulate a click for whom? You can't just 'click' a mouse without a player to perform the action - what's your specific scenario, and why can't the player click the mouse themselves?

 

I'm wanting to create a mod that fully automates the killing of mobs. To do this the mod would need to continuously swing the sword/item (which is why I figured simply simulating the mouse click would be a good idea).

 

Link to comment
Share on other sites

Simulate a click for whom? You can't just 'click' a mouse without a player to perform the action - what's your specific scenario, and why can't the player click the mouse themselves?

 

I'm wanting to create a mod that fully automates the killing of mobs. To do this the mod would need to continuously swing the sword/item (which is why I figured simply simulating the mouse click would be a good idea).

That seems very manual for something you're trying to automate. Why not just set the mobs' health to 0?

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

Ok, look in the Minecraft class and search for something like PlayerControllerMP or something. You should eventually find the method that interacts mouse input with the game's player controller. You can just copy/paste the code in their and simulate that whenever and wherever you feel like it.

 

Just don't forget to use a sledgehammer  8)

"you seem to be THE best modder I've seen imo."

~spynathan

 

ლ(́◉◞౪◟◉‵ლ

Link to comment
Share on other sites

As long as you have both the player (which, being client-side, you can get from the Minecraft class) and the target entity, you can perform the same action as left-click using the player controller:

Minecraft.getMinecraft().playerController.attackEntity(player, targetEntity);

Note that it will still check distance server-side, so the player must be close enough to hit the mob.

Link to comment
Share on other sites

As long as you have both the player (which, being client-side, you can get from the Minecraft class) and the target entity, you can perform the same action as left-click using the player controller:

Minecraft.getMinecraft().playerController.attackEntity(player, targetEntity);

Note that it will still check distance server-side, so the player must be close enough to hit the mob.

 

Yes, cheers I have looked at this method.

So for example, i'd use:

 

Minecraft.getMinecraft().playerController.attackEntity(thePlayer, targetEntity);

 

and the target entity being pulled from something like a raytrace?

 

 

Link to comment
Share on other sites

Just use mc.objectMouseOver to get the entity - you're client side already anyway, and ray tracing is only used to find block collisions. If you look in EntityRenderer#getMouseOver, you'll see how it's done, but you don't need to copy that code when you can already use the result of it directly.

I've been trying something similar to that, however it just crashes my minecraft whenever I toggle my mod.

 

@SubscribeEvent

public void onPlayerTick(TickEvent.PlayerTickEvent e) {

if (AutoClickerKeyBind.isOn == true) {

//FMLClientHandler.instance().getClient().playerController.attackEntity(thePlayer, objectMouseOver.entityHit);

mc.getMinecraft().playerController.attackEntity(mc.thePlayer, mc.objectMouseOver.entityHit);

}

}

Link to comment
Share on other sites

Just use mc.objectMouseOver to get the entity - you're client side already anyway, and ray tracing is only used to find block collisions. If you look in EntityRenderer#getMouseOver, you'll see how it's done, but you don't need to copy that code when you can already use the result of it directly.

I've been trying something similar to that, however it just crashes my minecraft whenever I toggle my mod.

 

@SubscribeEvent

public void onPlayerTick(TickEvent.PlayerTickEvent e) {

if (AutoClickerKeyBind.isOn == true) {

//FMLClientHandler.instance().getClient().playerController.attackEntity(thePlayer, objectMouseOver.entityHit);

mc.getMinecraft().playerController.attackEntity(mc.thePlayer, mc.objectMouseOver.entityHit);

}

}

 

In future, post crash reports if your code is crashing. Knowing what the error is makes it much easier to find the solution.

 

In this case,

TickEvent.PlayerTickEvent

is fired on both the client and server threads. You should check

world.isRemote

to make sure you're only attacking from the client thread.

 

The event is also fired twice per tick, so check the event's

phase

field and only attack in one phase.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Just use mc.objectMouseOver to get the entity - you're client side already anyway, and ray tracing is only used to find block collisions. If you look in EntityRenderer#getMouseOver, you'll see how it's done, but you don't need to copy that code when you can already use the result of it directly.

I've been trying something similar to that, however it just crashes my minecraft whenever I toggle my mod.

 

@SubscribeEvent

  public void onPlayerTick(TickEvent.PlayerTickEvent e) {

      if (AutoClickerKeyBind.isOn == true) {

        //FMLClientHandler.instance().getClient().playerController.attackEntity(thePlayer, objectMouseOver.entityHit);

        mc.getMinecraft().playerController.attackEntity(mc.thePlayer, mc.objectMouseOver.entityHit);

      }

  }

 

In future, post crash reports if your code is crashing. Knowing what the error is makes it much easier to find the solution.

 

In this case,

TickEvent.PlayerTickEvent

is fired on both the client and server threads. You should check

world.isRemote

to make sure you're only attacking from the client thread.

 

The event is also fired twice per tick, so check the event's

phase

field and only attack in one phase.

 

I'm really struggling with this. Thank you for your help however, I really appreciate it.

 

 

---- Minecraft Crash Report ----
// Ouch. That hurt 


Time: 18/12/15 00:33
Description: Unexpected error


java.lang.NullPointerException: Unexpected error
at com.bond.tech.AutoClickerTickEvent.onClientTick(AutoClickerTickEvent.java:50)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_8_AutoClickerTickEvent_onClientTick_ClientTickEvent.invoke(.dynamic)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:55)
at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:138)
at net.minecraftforge.fml.common.FMLCommonHandler.onPreClientTick(FMLCommonHandler.java:366)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1707)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1087)
at net.minecraft.client.Minecraft.run(Minecraft.java:376)
at net.minecraft.client.main.Main.main(Main.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
at GradleStart.main(Unknown Source)




A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------


-- System Details --
Details:
Minecraft Version: 1.8
Operating System: Windows 8.1 (amd64) version 6.3
Java Version: 1.7.0_79, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 827033816 bytes (788 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
FML: MCP v9.10 FML v8.0.99.99 Minecraft Forge 11.14.3.1450 4 mods loaded, 4 mods active
States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
UCHIJA	mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) 
UCHIJA	FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.8-11.14.3.1450.jar) 
UCHIJA	Forge{11.14.3.1450} [Minecraft Forge] (forgeSrc-1.8-11.14.3.1450.jar) 
UCHIJA	bondtech{1.0} [bondTech - Autoclicker] (bin) 
Loaded coremods (and transformers): 
GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 353.82' Renderer: 'GeForce GTX 750 Ti/PCIe/SSE2'
Launched Version: 1.8
LWJGL: 2.9.1
OpenGL: GeForce GTX 750 Ti/PCIe/SSE2 GL version 4.5.0 NVIDIA 353.82, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.


Using VBOs: No
Is Modded: Definitely; Client brand changed to 'fml,forge'
Type: Client (map_client.txt)
Resource Packs: []
Current Language: English (US)
Profiler Position: N/A (disabled)

 

The code the error is coming from.

@SubscribeEvent
public void onClientTick(TickEvent.ClientTickEvent event) {
	if(event.phase == TickEvent.Phase.START) {
		if(theWorld.isRemote) {
			if (AutoClickerKeyBind.isOn == true) {
				mc.getMinecraft().thePlayer.swingItem();
				mc.getMinecraft().playerController.attackEntity(mc.thePlayer, mc.objectMouseOver.entityHit);
			}
		}
	}
}
Link to comment
Share on other sites

Or you could just check for null in the code you have... I don't think calling Minecraft's clickMouse() function constantly would be a good idea.

 

My mod revolves around simulating the mouse click though. It has a toggle on and off, so it'd only be calling it when it is supposed to.

I'm going to go ahead and try the check for null anyway.

Link to comment
Share on other sites

Or you could just check for null in the code you have... I don't think calling Minecraft's clickMouse() function constantly would be a good idea.

 

How this looking? Still crashes but a bit closer?

 

@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onClientTick(TickEvent.ClientTickEvent event) {
	if(event.phase == TickEvent.Phase.START) {
		if (AutoClickerKeyBind.isOn == true) {
			mc.getMinecraft().thePlayer.swingItem();
			if(mc.getMinecraft().objectMouseOver == null) {
				//Do nothing extra
			} else {
				if(mc.getMinecraft().objectMouseOver != null) {
					if(mc.getMinecraft().objectMouseOver.typeOfHit.ordinal() == 1) {
						mc.getMinecraft().playerController.attackEntity(mc.thePlayer, mc.getMinecraft().objectMouseOver.entityHit);
					}
					if(mc.getMinecraft().objectMouseOver.typeOfHit.ordinal() == 0) {
						BlockPos blockpos = mc.getMinecraft().objectMouseOver.getBlockPos();
						if (mc.getMinecraft().theWorld.getBlockState(blockpos).getBlock().getMaterial() != Material.air) {
							mc.getMinecraft().playerController.func_180511_b(blockpos, mc.getMinecraft().objectMouseOver.sideHit);
						}
					}

				}
			}
		}
	}
}

Link to comment
Share on other sites

You need to provide the crash report.

 

Aside from that, you have some minor issues in your code:

 

You don't need to check if the world is remote when you are using the ClientTickEvent - it's already guaranteed to be client side.

 

You should compare the type of hit with a type of hit, not using the ordinal:

// No
mc.getMinecraft().objectMouseOver.typeOfHit.ordinal() == 1
// Yes
mc.getMinecraft().objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY

 

You also have an unnecessary if statement:

if(mc.getMinecraft().objectMouseOver == null) {
//Do nothing extra
} else {
// mouse over cannot be null here, because this is the else statement for the previous null check
if(mc.getMinecraft().objectMouseOver != null) { // unnecessary...

[/code]

Link to comment
Share on other sites

You need to provide the crash report.

 

Aside from that, you have some minor issues in your code:

 

You don't need to check if the world is remote when you are using the ClientTickEvent - it's already guaranteed to be client side.

 

You should compare the type of hit with a type of hit, not using the ordinal:

// No
mc.getMinecraft().objectMouseOver.typeOfHit.ordinal() == 1
// Yes
mc.getMinecraft().objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY

 

You also have an unnecessary if statement:

if(mc.getMinecraft().objectMouseOver == null) {
//Do nothing extra
} else {
// mouse over cannot be null here, because this is the else statement for the previous null check
if(mc.getMinecraft().objectMouseOver != null) { // unnecessary...

[/code]

 

Thank you, My error was surrounding

 

attackEntity(mc.thePlayer, ****)

 

I needed to call mc.getMinecraft().thePlayer instead, which was causing the crash.

 

Thank you very much for the help though, you and Choonster. Really appreciated.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.