Jump to content

[1.9] How to make an item attack automatically when you hold the attack button?


Recommended Posts

Posted

Hi! I'm fairly new to Java and Forge, but I've managed to make two simple mods-- so I'm not a TOTAL newbie.

 

But, uh, I'm making a third one, and I'm wondering if there's a way to make an item not require the player to click repeatedly, instead just attacking for them when they hold the attack key. (And have it not create a 1.9 combat cool-down timer thing, but that's not the point of this thread.)

 

Now I'd rather not be spoon-fed information/code just like that, and bear in mind that's definitely not what I'm asking for. But if any of you could... fairly vividly point me in the right direction, that'd be much appreciated. Thank you!

 

PS: Yes, it's a chainsaw ;)

-wolfboyft

Posted

If you were using MCP, and not forge, you could rewrite the attacking classes.

But what you can do, is to check if an entity is on your cross in the middle of the screen, and if its in range.

Then go ahead and damage that entity through the player as the "DamageSource" and there you go.

Posted

ñaaa

two thing come two mind

and alredy do the two of

 

if its an left clcik atack

// ############################################################################################3

@Override
public boolean onEntitySwing(EntityLivingBase shootingEntity, ItemStack stack) {

	World worldIn = shootingEntity.worldObj;

	if (!worldIn.isRemote)
	{
	entidadDisparo ed = new entidadDisparo(worldIn, shootingEntity);
	worldIn.spawnEntityInWorld(ed);
	}

//###

	boolean dissable = false;
	if (dissable && !worldIn.isRemote)
	{

		byte adatick = 4;

    		
    		switch(adatick)
    		{
    		case   4:
    		case   7:
    		case  10:
    		case  13:
    		case  16:
    		case  19: 
    			
    			
    			ItemStack offfhand = shootingEntity.getHeldItemOffhand();
    			
    			if (offfhand != null && offfhand.getItem() instanceof pistolaDual){
    			
    			byte municion = util.getBytetag(offfhand, "municion");
    			
    			if (municion > 0){    			
    			
    			diparo(offfhand, shootingEntity, adatick);
    				
    			util.setInttag(offfhand, "ticksmax", 10);
    			util.setBooleantag(offfhand, "ejecutar", true);

    			util.setLongtag(offfhand, "currenttime", 0);
    			util.setLongtag(offfhand, "currenttimed", System.currentTimeMillis());

    			util.setBytetag(offfhand, "accion", 1);
   			
    			
    			}
    			}
    			//onPlayerStoppedUsing(offfhand, shootingEntity, adatick);
    			
    			break;
    		}


	//desAtascar(stack);
	}

	return true;
}

here is two things im working on the first, also the working one create an entity that makes the dirty work for the player atack every two ticks and live only for 20ticks the dieded and desapear but has a trouble and os that itis acumulative soo id you prees fast left click you end whith tree or more atackind entityes at same time 

 

if it is an onItemRigthClick you should put your atack code inside

 

// ############################################################################################3

@Override

public void onUsingTick(ItemStack stack, EntityLivingBase player, int count) {

// World worldIn = player.worldObj;

int conteo = 10000 - count;

 

if ( (conteo %2) == 0)

{

attack();

}

 

 

}

 

 

 

[/code]

Posted

If you were using MCP, and not forge, you could rewrite the attacking classes.

 

This totally goes against your profile quote and also this whole forum.

 

Anyway - attacking works like this:

Client performs raytrace (on right click, honouring client-side attack speed), if it hits entity, a packet is sent, server then check if attack was valid/possible (checks distance to entity and probably also attack speed and other stuff) and if it was - entity gets damaged on server and whole hurting mechanisms are fired.

 

Now - to make "attack-bot" you will need to 1st of all - fulfill same requirements as normal attacks and then basically just send attacking packet to server (yeah, vanilla one).

 

To do all that there a quite few approaches (I will mention one, maybe two):

 

1. Do it from client input:

@SubscribeEvent to ClientTickEvent.

Check against event.phase (run only once).

Make client-sided integer counter (can be static and @SideOnly(Side.CLIENT), since there is always only one client player).

On click: (KeyInputEvent or KeyBindingEvent or something else, like mouse/keyboard event) set counter to 0.

On hold: increment counter from ClientTickEvent (check if attack keybinding is pressed) and check if (counter % Minecraft#thePlayer#attackSpeed == 0).

If passes - perform attack (simulate what vanilla does) - send attack packet.

 

2. Do it somehow from Item class - it has on start, tick, and finish using - you could utilize that to re-attack when item is being used.

This is probably better approach but also needs some work.

 

Note: Attacking can be simulated on client (point 1 or 2), or on server (only 2).

1.7.10 is no longer supported by forge, you are on your own.

Posted

If you were using MCP, and not forge, you could rewrite the attacking classes.

But what you can do, is to check if an entity is on your cross in the middle of the screen, and if its in range.

Then go ahead and damage that entity through the player as the "DamageSource" and there you go.

 

I'll look through the documentation for those two "is-the-entity-targeted" methods, thanks.

 

Also, how would this be implemented client-server wise? Packets? Y'see, I'm intending for [secondary action] (right click) to turn the chainsaw on and off, and [attack] (left click) to-- when it is on-- do the continuous attack thing, and when it's off act like a sword, and it would seem that should have a client-server "conversation" for each player. Correct me if I'm wrong on that, please.

 

Or should I make a new thread for this...?

 

ta muchly

-wolfboyft

Posted

 

ernio is given you more wise tips and surely gonna get more easy than mine

i could get video from mi old chaing saw but the saw in this old prototipe gun uses the same system than mi old chainsaw

 

 

i this case when left click it creates a invisible entity that exist both client and server side this invisible entity has an instance of playerEntity and sync the player id it to client side via datawacher

the entity client side checks every tick if players hold left click it is soo then sens pakage to itself in the server side to enter in atack mode when player client side release left click entity send package stop

 

if entity is in atack mode it ray trace based on player pitch and yaw if fount mob and this mob is close at less than 3meters

entity shoot chainsaw bullet  also based of player rotation and traslation this bullet deals only 1D of damage and i do it like a bullet sooo it would'n damage mobs througth walls and things

 

well ithink i lost the point a little here not even know if you wanna atack on right or left click

 

 

Posted

If you were using MCP, and not forge, you could rewrite the attacking classes.

 

This totally goes against your profile quote and also this whole forum.

 

Anyway - attacking works like this:

Client performs raytrace (on right click, honouring client-side attack speed), if it hits entity, a packet is sent, server then check if attack was valid/possible (checks distance to entity and probably also attack speed and other stuff) and if it was - entity gets damaged on server and whole hurting mechanisms are fired.

 

Now - to make "attack-bot" you will need to 1st of all - fulfill same requirements as normal attacks and then basically just send attacking packet to server (yeah, vanilla one).

 

To do all that there a quite few approaches (I will mention one, maybe two):

 

1. Do it from client input:

@SubscribeEvent to ClientTickEvent.

Check against event.phase (run only once).

Make client-sided integer counter (can be static and @SideOnly(Side.CLIENT), since there is always only one client player).

On click: (KeyInputEvent or KeyBindingEvent or something else, like mouse/keyboard event) set counter to 0.

On hold: increment counter from ClientTickEvent (check if attack keybinding is pressed) and check if (counter % Minecraft#thePlayer#attackSpeed == 0).

If passes - perform attack (simulate what vanilla does) - send attack packet.

 

2. Do it somehow from Item class - it has on start, tick, and finish using - you could utilize that to re-attack when item is being used.

This is probably better approach but also needs some work.

 

Note: Attacking can be simulated on client (point 1 or 2), or on server (only 2).

 

Got any pseudo-code ideas for number 2? Not very good with certain types of logic. Lemme just look at those methods, tho

-wolfboyft

Posted

TickEvents are fires twice per tick - at START and END. You need to pick one phase, otherwise code runs twice.

if (event.phase == Phase.END) ...

1.7.10 is no longer supported by forge, you are on your own.

Posted

TickEvents are fires twice per tick - at START and END. You need to pick one phase, otherwise code runs twice.

if (event.phase == Phase.END) ...

 

I understand that now, and as such, deleted the post as it was just clutter.

 

I'll be sure to ask you any more necessary question on this matter :P

-wolfboyft

Posted

What do you mean by the whole "on click" thing, Ernio? So far I made myself

 

public class BlamBlamEventHandler {
   @SideOnly(Side.CLIENT)
   static int Counter;
   
   @SubscribeEvent
   public void onClientTickEvent(ClientTickEvent event){
      if (event.phase == Phase.START) {
         //What now?
       }
   }
}

 

plus the relevant imports and package, but I got kinda stuck.

 

I hate to ask for spoon-fed information, but... I don't understand! Should I go away and learn some more Java, or... is this just a case of me not quite knowing the relevant Forge techniques?

-wolfboyft

Posted

To me it is rather lack of experience. When writing stuff (any) you gather techniques which can be applied in future. In this case my idea (which again - is one of many) was to have counter.

 

Describing it a bit more:

Say that 0 means that you just started and anything above means you are doing it.

Logically - if you would take "click" as start and "hold" as doing it you would end up with "onPress -> set to 0" and "onHold -> increment by 1".

 

Now you can just apply it by 1st catching attack button press and attack button hold.

As of now I don't quite remember the deal with KeyBindings, so that I'll leave for you, but since attacking (default left-mouse-button) can be bound to other KeyBinding you will simply have to check when KeyBinding is pressed and then using ClientTickEvent check if same KeyBinding is being down.

Points of interest:

KeyBinding

ClientTickEvent

Other tools like Keyboard.isKeyDown - which is basically normal Java stuff.

 

Note that this approach can be client-only mod and is based on "client orders->packet sent->server acts", rather than using Item class to do it for you somehow (which could be just "server acts"). Also note that there is a difference between "attacking" (swing) with item and "using" it.

I highly recommend digging into sources to find out where you can do what you want :)

 

P.S/edit:

 

About thoseother approaches - you could for example catch pressing and unpressing.

Pressing = send packet to server setting server's per-player (@Capability) boolean to true.

UnPressing = send packet setting said value to false.

Then you could use PlayerTickEvent with !world.isRemote (server-side) to check against given boolean and simulate attack server-side only.

 

The biggest problem here is that you probably want to have attack animation on client so doing it only on server would require you to send packet back I think (idk really), that's why I proposed doing it from client only and treat continuous attacking as kinda like attack-bot.

1.7.10 is no longer supported by forge, you are on your own.

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.