Posted May 23, 20196 yr Hey there, I have a capability with a boolean (active status) and an integer value (a charge value). I want to check this data for many effects and events. Here are my current cases: BreakSpeed and Jump Height (but planning to add more later on, such as attack damage or mob behaviour) I want to make it so that when the boolean is active, the player's block breaking speed is doubled or jump height increased. This works fine. However, I also want to reduce the charge value while doing this. When simply using the code further down, a desync in the values known by the client and by the server starts to manifest after prolonged usage, from both the block breaking and jump height. The debug chat line also appears twice per side for some reason, with the second time showing the already incremented charge value. This makes me wonder: What is the best way to handle capability data like this? Since some data is handled by the server and other data by the client (such as movement), the data would have to be present on both, but considering that the charge is modified so highly frequently, sending a packet every frame surely can't be the right way to handle it? @SubscribeEvent public void breakingSpeed(net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed event) { if (getBioData(player).getMaskActive()) { Item mask = player.inventory.armorItemInSlot(3).getItem(); if (mask == ItemInit.KANOHI_PAKARI) { event.setNewSpeed(event.getNewSpeed() * 2); getBioData(player).modifyMaskCharge(-5); if (player.ticksExisted % 20 == 0) { player.sendStatusMessage(new TextComponentString(TextFormatting.DARK_GRAY + "Speeds: New: " + event.getNewSpeed() + " Old: " + event.getOriginalSpeed()), false); } } } } @SubscribeEvent public void jumpEffect(LivingEvent.LivingJumpEvent event) { if (event.getEntity() instanceof EntityPlayer) { EntityPlayer evPlayer = (EntityPlayer)event.getEntity(); if (getBioData(evPlayer).getMaskActive() && evPlayer.inventory.armorItemInSlot(3).getItem() == ItemInit.KANOHI_MIRU && getBioData(evPlayer).getMaskCharge() >= 1000) { evPlayer.motionY += 0.7D; evPlayer.motionX *= 4.0D; evPlayer.motionZ *= 4.0D; getBioData(evPlayer).modifyMaskCharge(-1000); } } } @SubscribeEvent public void playerTick(TickEvent.PlayerTickEvent event) { if (!(player.inventory.armorItemInSlot(3).getItem() instanceof Kanohi) && getBioData(player).getMaskActive() == true) { getBioData(player).setMaskActive(false); player.sendStatusMessage(new TextComponentString(TextFormatting.RED + event.side.name() + " Mask unequipped, setting to: " + (getBioData(player).getMaskActive() ? "On" : "Off")), false); } if (getBioData(player).getMaskActive()) { Item mask = player.inventory.armorItemInSlot(3).getItem(); if (mask == ItemInit.KANOHI_MIRU) { player.fallDistance = 0; } } else { getBioData(player).modifyMaskCharge(+10); //Increasing charge with mask deactivated } if (player.ticksExisted % 100 == 0) { player.sendStatusMessage(new TextComponentString(TextFormatting.DARK_RED + event.side.name() + " Mask: " + (getBioData(player).getMaskActive() ? "On" : "Off") + " Charge: " + getBioData(player).getMaskCharge()), false); } } public class DefaultBioPlayerDataHandler implements IBioPlayerDataHandler { private BioElements element; private Boolean maskActive = false; private int maskCharge = 10000; private final int maxCharge = 10000; @Override public BioElements getElement() { return element; } @Override public void setElement(BioElements element) { this.element = element; } @Override public void removeElement() { this.element = BioElements.NONE; } @Override public Boolean getMaskActive() { return maskActive; } @Override public void setMaskActive(Boolean status) { this.maskActive = status; } @Override public int getMaskCharge() { return this.maskCharge; } @Override public void setMaskCharge(int charge) { this.maskCharge = charge; } @Override public void modifyMaskCharge(int modifier) { if (maskCharge + modifier >= 0) { if (maskCharge + modifier <= maxCharge) { maskCharge = maskCharge + modifier; } else { maskCharge = maxCharge; } } else { maskCharge = 0; maskActive = false; } } } Edited May 23, 20196 yr by Alekseyev
May 30, 20196 yr Author I thought about the following: Instead of checking the charge value and being updated on it, the client just has a boolean for "1000 or higher". The server then only sends an update packet whenever the charge value crosses this treshold. However, there is a problem: I also want the charge to be displayed on the HUD later (in the form of a bar of varying size), and to calculate that size, you'd need the value again...
May 30, 20196 yr Just send the value as you change it. I doubt sending 4 bytes per tick is much overhead.
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.