wolfboyft Posted June 19, 2016 Posted June 19, 2016 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 Quote -wolfboyft
deerangle Posted June 19, 2016 Posted June 19, 2016 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. Quote
perromercenary00 Posted June 19, 2016 Posted June 19, 2016 ñ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] Quote
Ernio Posted June 19, 2016 Posted June 19, 2016 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). Quote 1.7.10 is no longer supported by forge, you are on your own.
wolfboyft Posted June 19, 2016 Author Posted June 19, 2016 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 Quote -wolfboyft
perromercenary00 Posted June 19, 2016 Posted June 19, 2016 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 Quote
wolfboyft Posted June 19, 2016 Author Posted June 19, 2016 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 Quote -wolfboyft
Ernio Posted June 22, 2016 Posted June 22, 2016 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) ... Quote 1.7.10 is no longer supported by forge, you are on your own.
wolfboyft Posted June 22, 2016 Author Posted June 22, 2016 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 Quote -wolfboyft
wolfboyft Posted June 22, 2016 Author Posted June 22, 2016 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? Quote -wolfboyft
Ernio Posted June 22, 2016 Posted June 22, 2016 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. Quote 1.7.10 is no longer supported by forge, you are on your own.
Recommended Posts
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.