Jump to content

Make player not hit during Attack cooldown


BliX5

Recommended Posts

I’ve made an event so the player can’t damage entities during an attack cooldown, but whenever the player hits during a cooldown, it resets. How can I stop this from happening and make it so the player can’t punch at all? 

Link to comment
Share on other sites

Here's my code so far:

    @SubscribeEvent
    public static void onPlayerHit(final AttackEntityEvent event) {
        if(event.getPlayer().getCooledAttackStrength(0) < 1.0F) {
            event.setCanceled(true);
        }
    }

I want to make it so while on cooldown, the player cannot hit at all. With this code, the player can still hit, but it doesn't do damage to entities. Is there any other event I can use to cancel the left click entirely?

Link to comment
Share on other sites

7 hours ago, diesieben07 said:

AttackEntityEvent.

However note that if you cancel this, the attack timer will still count on the client. To avoid this, you can additionally cancel InputEvent.ClickInputEvent on the client. That alone is not enough, because it could be easily bypassed using cheating.

I tried it, but it doesn't work about half of the time. Is there a way to add some sort of delay between the events so the a value is recorded before onClickEvent is put into action?

    public static float a = 1;

    @SubscribeEvent
    public static void onPlayerHit(final AttackEntityEvent event) {
        ModClientEvents.a = event.getPlayer().getCooledAttackStrength(0);
        if(ModClientEvents.a < 1) {
            event.setCanceled(true);
            ModClientEvents.a = 1;
        }
    }

    @SubscribeEvent
    public static void onClickEvent(final InputEvent.ClickInputEvent event) {
        if(ModClientEvents.a < 1) {
            event.setCanceled(true);
            ModClientEvents.a = 1;
        }
    }

 

Edited by BliX5
Link to comment
Share on other sites

I tried to fix more of the code, and I got it to work most of the time, but it's still incredibly buggy. 

 

ModServerEvents:

@Mod.EventBusSubscriber(modid = BotwMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ModServerEvents {

    public static float a;

    @SubscribeEvent
    public static void onPlayerHit(final AttackEntityEvent event) {
        ModServerEvents.a = event.getPlayer().getCooledAttackStrength(0);
        BotwMod.LOGGER.debug(String.valueOf(ModServerEvents.a) + " onPlayerHit");
        if(ModServerEvents.a < 1) {
            event.setCanceled(true);
        }
    }

    @SubscribeEvent
    public static void onClickEvent(final InputEvent.ClickInputEvent event) {
        BotwMod.LOGGER.debug(String.valueOf(ModServerEvents.a) + " onClickEvent");
        if(ModServerEvents.a < 1) {
            event.setCanceled(true);
        }
        ModServerEvents.a = 1;
    }

}

 

Main Class:

MinecraftForge.EVENT_BUS.register(this);
        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGHEST, ModServerEvents::onPlayerHit);
        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, ModServerEvents::onClickEvent);

 

Link to comment
Share on other sites

7 hours ago, diesieben07 said:

You cannot do this. There is more than one player, and this value would be shared between all of them. Additionally, in single player, this value would be shared between client and server thread, without proper synchronization.

 

Additionally, it seems you have not read my message in full. ClickInputEvent is a client-only event.

I've moved the ClickInputEvent to my client events and I've fixed the values. The problem now is that the method onClickEvent is running before onPlayerHit, which delays whether the hit is cancelled or not for the next left click, despite how I set the events' priority in my main class.

Link to comment
Share on other sites

Main Class:

@Mod("botw")
public class BotwMod
{
    public static final Logger LOGGER = LogManager.getLogger();
    public static final String MOD_ID = "botw";

    public BotwMod() {
        IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        bus.addListener(this::setup);

        ModBlocks.BLOCKS.register(bus);
        ModItems.ITEMS.register(bus);
        ModEntityTypes.ENTITY_TYPES.register(bus);

        MinecraftForge.EVENT_BUS.register(this);

        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGHEST, ModServerEvents::onPlayerHit);
        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, ModClientEvents::onClickEvent);
    }

    private void setup(final FMLCommonSetupEvent event) {
        DeferredWorkQueue.runLater(() -> { });
    }

    private void doClientStuff(final FMLClientSetupEvent event) { }

 

ModClientEvents:

@Mod.EventBusSubscriber(modid = BotwMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ModClientEvents {

    public static float a = 1;

    @SubscribeEvent
    public static void onClickEvent(InputEvent.ClickInputEvent event) {
        BotwMod.LOGGER.debug("ModClientEvents"); //used for debugging
        if(event.isAttack()) {
            if(ModClientEvents.a < 1) {
                ModClientEvents.a = 1;
                event.setCanceled(true);
            }
        }
    }

}

 

ModServerEvents:

@Mod.EventBusSubscriber(modid = BotwMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ModServerEvents {

    @SubscribeEvent
    public static void onPlayerHit(AttackEntityEvent event) {
        BotwMod.LOGGER.debug("ModServerEvents"); //used for debugging
        ModClientEvents.a = event.getPlayer().getCooledAttackStrength(0);
    }

}

 

Link to comment
Share on other sites

20 minutes ago, diesieben07 said:

The two events do not need to interact at all. Just cancel both of them when it is relevant.

I need the AttackEntityEvent to determine when the player is on attack cooldown or not, unless there is another way to access that.

Link to comment
Share on other sites

2 minutes ago, diesieben07 said:

How is the event relevant to how you call a method?

Before when I called getCooledAttackStrenght, I was using AttackEntityEvent to call it. 

@SubscribeEvent
    public static void onPlayerHit(AttackEntityEvent event) {
        if(event.getPlayer().getCooledAttackStrength(0) < 1.0F) {
            event.setCanceled(true);
        }
    }

I couldn't find a way to call this method again with ClickInputEvent without my game crashing.

Link to comment
Share on other sites

9 minutes ago, diesieben07 said:

Show what you tried that crashed the game.

@SubscribeEvent
public static void onClickEvent(InputEvent.ClickInputEvent event, Entity entityIn) {
    PlayerEntity player = (PlayerEntity)entityIn;
    if(event.isAttack()) {
        if(player.getCooledAttackStrength(0) < 1) {
            event.setCanceled(true);
        }
    }
}

Pretty sure this doesn't work because events shouldn't have any other parameters, but this is the only way I could think of calling it. 

Link to comment
Share on other sites

Thanks, it works now! Here's my final code:

@SubscribeEvent
public static void onClickEvent(InputEvent.ClickInputEvent event) {
    PlayerEntity player = Minecraft.getInstance().player;
    if(event.isAttack()) {
        if(player.getCooledAttackStrength(0) < 1) {
            event.setCanceled(true);
        }
    }
}
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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I have a structure, and sometimes several mobs spawn there. This is a boss and must spawn alone. Here is the code for spawning entities in the structure { "type": "minecraft:jigsaw", "start_pool": "egyptcraft:boss_pyramid/start_pool", "size": 5, "max_distance_from_center": 80, "biomes": "#egyptcraft:has_structure/boss_pyramid", "step": "surface_structures", "start_height": { "absolute": 0 }, "project_start_to_heightmap": "WORLD_SURFACE_WG", "use_expansion_hack": false, "spawn_overrides": { "monster": { "bounding_box": "full", "spawns": [ { "type": "egyptcraft:anubis", "maxCount": 1, "minCount": 1, "weight": 100 } ] } } } Maybe it's something else?
    • I have OreGenEvent.GenerateMinable event, I need to get a chance to spawn (generate) every ore that is processed in this event. Also e.getType().name().toString() is name this is the same block name by which it can be entered in the Block.getByID?  forge 1.12.2 59(recommended)
    • Hello everybody! Out of nowhere my minecraft doesn't allow me to play on forge 1.19.2 I tried to reinstall minecraft, doesn't have any mod right now on the forge version. Tried the newest version of forge, tried recommended version as well. I have the newest version of Java as well...   I dont know why it stopped working but it just stopped completly out of nowhere...   Thank you so much for your help guys ❤️
    • Hello, my world is crashing at 0% loaded and I don't know why. (Forge 43.2.14, 1.19.2) I have two worlds that I play on, and one works and the other doesn't, even with the same mod list. Here's the crash report: https://pastebin.com/AUbRwkGj
    • Minecraft 1.12.2 Very frustrating error. only ever occurs on one device. Started yesterday without prompting (maybe java updated or something?) Says things that have been imported actually arent when running client Reinstalled Intellij, cleared cache, cleaned and rebuilt gradle, redownloaded the entire file from git. Nothing works. (I believe I have the right plugins installed, dependencies OK, and am using corretto 1.8).   One thing I did for more of the below errors was just to explicitly import them, which was working up until this little guy who literally does not exist in forge to import. the class inhereting something inhereting it refers to import net.minecraftforge.registries.IForgeRegistryEntry.Impl, not net.minecraftforge.registries.IForgeRegistryEntry$Impl as the output implies. also I didn't even have to manually import these things for it to work on my other device. (which is just importing the minecraft package that contains them), but here I did have to just to get rid of a few errors--not even make anything work?? I dont know. (edited) here's the aforementioned "below error" (one of many like it): error: cannot access net.minecraftforge.registries.IForgeRegistryEntry.Impl public class BlockBase extends Block {        ^   class file for net.minecraftforge.registries.IForgeRegistryEntry$Impl not found Here's the class BlockBase:   package com.quantum.exodus.common.blocks; import com.quantum.exodus.ExodusMod; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraftforge.registries.IForgeRegistryEntry.Impl; public class BlockBase extends Block { protected String name; public BlockBase(Material material, String name) { super(material); this.name = name; setTranslationKey(name); setRegistryName(name); } public void registerItemModel(Item itemBlock) { ExodusMod.proxy.registerItemRenderer(itemBlock, 0, name); } public Item createItemBlock() { return new ItemBlock(this).setRegistryName(getRegistryName()); } @Override public BlockBase setCreativeTab(CreativeTabs tab) { super.setCreativeTab(tab); return this; } }
  • Topics

×
×
  • Create New...

Important Information

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