Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Hi all,

I'm new to modding (although not to java) and I'm trying to make a player who holds a certain item be able to fly in survival mode. I've done my best to look this issue up, but everything I'm finding, even on this forum, seems to be outdated, except for the way I've done it, which doesn't seem to be working. The player is not able to fly even when holding the item. I even took a look at the source for the curseforge Angel Ring mod and It seems to use the same method to enable flight.

Here's the event listener I'm using:

@SubscribeEvent
    public static void honorbladePowers(TickEvent.PlayerTickEvent e) {

        if (e.player.getItemInHand(InteractionHand.MAIN_HAND).getItem() instanceof ShardbladeItem) {
            e.player.getAbilities().mayfly = true;
            e.player.onUpdateAbilities();

        } else {
            e.player.getAbilities().mayfly = false;
            e.player.onUpdateAbilities();

        }
    }

 

 

 

Any help as to why enabling mayfly and then calling onUpdateAbilities() isn't working would be awesome! Thanks y'all!

 

Edited by JFuller
Remove accidental dox lol

That way of doing it is very inefficient. The PlayerTick event is called on the client and server at both the start and end of each tick.

You should be checking event.side and event.phase to limit when you do things.

The onUpdateAbilities() sends a network packet to the other side.

So, your code would be sending 4 network packets per player per tick.

 

Here's a more efficient way:

@Mod.EventBusSubscriber(modid = MODID)
public class Events {

    @SubscribeEvent
    public static void equipmentChange(LivingEquipmentChangeEvent event) {
        if (event.getEntity() instanceof Player player && event.getSlot() == EquipmentSlot.OFFHAND) {
            // WARNING: Proof of concept code not the correct logic
            player.getAbilities().mayfly = event.getTo().is(Items.DIAMOND);
            player.onUpdateAbilities();
        }
    }
}

That event only happens on the server and only when the equipment actually changes.

The above works for me, using diamonds in the shield slot as my trigger.

 

WARNING. The above logic is not complete.

One example is, it would remove flight from creative mode players when they remove the diamond. 

Another is it doesn't set flying=false when the diamonds are removed.

Edited by warjort

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

  • Author
3 hours ago, warjort said:

That way of doing it is very inefficient. The PlayerTick event is called on the client and server at both the start and end of each tick.

You should be checking event.side and event.phase to limit when you do things.

The onUpdateAbilities() sends a network packet to the other side.

So, your code would be sending 4 network packets per player per tick.

 

Here's a more efficient way:

@Mod.EventBusSubscriber(modid = MODID)
public class Events {

    @SubscribeEvent
    public static void equipmentChange(LivingEquipmentChangeEvent event) {
        if (event.getEntity() instanceof Player player && event.getSlot() == EquipmentSlot.OFFHAND) {
            // WARNING: Proof of concept code not the correct logic
            player.getAbilities().mayfly = event.getTo().is(Items.DIAMOND);
            player.onUpdateAbilities();
        }
    }
}

That event only happens on the server and only when the equipment actually changes.

The above works for me, using diamonds in the shield slot as my trigger.

 

WARNING. The above logic is not complete.

One example is, it would remove flight from creative mode players when they remove the diamond. 

Another is it doesn't set flying=false when the diamonds are removed.

Thank you so much! I spent a long time on google initially and for some reason I couldn't find the event that triggers when you swap equipment lol. That will make this much easier!

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.