Laike_Endaril Posted January 27, 2019 Posted January 27, 2019 (edited) I've been delving into the potion-related code in MC and it *seems* like custom potion effects on the player should automatically sync to the client, but for some reason my potion effect only exists server-side. The potion itself works, and the particle effect is spawned, but I must be missing something to allow the existing synchronization system to sync my potion effect, because iterating through + printing the potion effects shows the effect server-side, but not client-side. Potion: Reveal hidden contents package com.fantasticsource.dynamicstealth.common.potions; import com.fantasticsource.dynamicstealth.common.DynamicStealth; import com.fantasticsource.dynamicstealth.server.senses.EntityVisionData; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.attributes.AbstractAttributeMap; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class PotionSoulSight extends Potion { private final ResourceLocation iconTexture; public PotionSoulSight() { super(false, 0xFFFF55); setPotionName(DynamicStealth.MODID + ".soulSight"); setRegistryName(DynamicStealth.MODID, "soulSight"); iconTexture = new ResourceLocation(DynamicStealth.MODID, "potions/soulsight.png"); } @Override public boolean isInstant() { return false; } @Override public void applyAttributesModifiersToEntity(EntityLivingBase entityLivingBaseIn, AbstractAttributeMap attributeMapIn, int amplifier) { //Should be called "onPotionStart" EntityVisionData.potionSoulSightEntities.add(entityLivingBaseIn); } @Override public void removeAttributesModifiersFromEntity(EntityLivingBase entityLivingBaseIn, AbstractAttributeMap attributeMapIn, int amplifier) { //Should be called "onPotionEnd" EntityVisionData.potionSoulSightEntities.remove(entityLivingBaseIn); } @SideOnly(Side.CLIENT) @Override public void renderInventoryEffect(int x, int y, PotionEffect effect, Minecraft mc) { if (mc.currentScreen != null) { mc.getTextureManager().bindTexture(iconTexture); Gui.drawModalRectWithCustomSizedTexture(x + 6, y + 7, 0, 0, 18, 18, 18, 18); } } @SideOnly(Side.CLIENT) @Override public void renderHUDEffect(int x, int y, PotionEffect effect, Minecraft mc, float alpha) { mc.getTextureManager().bindTexture(iconTexture); Gui.drawModalRectWithCustomSizedTexture(x + 3, y + 3, 0, 0, 18, 18, 18, 18); } } Registration (added to event bus in main mod class constructor): Reveal hidden contents package com.fantasticsource.dynamicstealth.common.potions; import com.fantasticsource.dynamicstealth.common.DynamicStealth; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionType; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class Potions { @SubscribeEvent public static void registerPotions(RegistryEvent.Register<Potion> event) { event.getRegistry().register(new PotionSoulSight()); } @SubscribeEvent public static void registerPotionTypes(RegistryEvent.Register<PotionType> event) { event.getRegistry().register(new PotionType(DynamicStealth.MODID + ".soulSight", new PotionEffect(new PotionSoulSight(), 200)).setRegistryName(DynamicStealth.MODID, "soulSight")); } } Test (For vanilla potions, both debug messages print. For my own potion, only the server message prints): Reveal hidden contents @SubscribeEvent public static void test(TickEvent.PlayerTickEvent event) { if (MCTools.isClient(event.player.world)) { for (PotionEffect effect : event.player.getActivePotionEffects()) { System.out.println("Client: " + effect.getEffectName()); } } else { for (PotionEffect effect : event.player.getActivePotionEffects()) { System.out.println("Server: " + effect.getEffectName()); } } } Edited January 29, 2019 by Laike_Endaril Solved Quote
V0idWa1k3r Posted January 28, 2019 Posted January 28, 2019 On 1/27/2019 at 9:01 PM, Laike_Endaril said: event.getRegistry().register(new PotionSoulSight()); Expand On 1/27/2019 at 9:01 PM, Laike_Endaril said: event.getRegistry().register(new PotionType(DynamicStealth.MODID + ".soulSight", new PotionEffect(new PotionSoulSight(), 200)).setRegistryName(DynamicStealth.MODID, "soulSight")); Expand You can't just instantinate your potion twice and call it good. The potion type needs a reference to an existing potion. To get a reference you can use @ObjectHolder. I don't know how you are applying your potion but if it is through a bottle then this is your issue. On 1/27/2019 at 9:01 PM, Laike_Endaril said: if (MCTools.isClient(event.player.world)) Expand Why do you need this helper? World.isRemote is enough and shorter. The reason I am wary of this is you might have implemented it incorrectly and are mixing the client and the server which would be the cause of your problem(although I don't know how you are adding the potion itself). Fix these two, they are big culprits and if that didn't help proceed with the debugging: Place a breakpoint in EntityPlayerMP#onNewPotionEffect to see if it is triggered for your potion and one in NetHandlerPlayClient#handleEntityEffect to see if the client is receiving the packet for your potion effect. Quote
Laike_Endaril Posted January 29, 2019 Author Posted January 29, 2019 On 1/28/2019 at 5:56 AM, V0idWa1k3r said: You can't just instantiate your potion twice and call it good. The potion type needs a reference to an existing potion. To get a reference you can use @ObjectHolder. I don't know how you are applying your potion but if it is through a bottle then this is your issue. Expand Ah, thank you. This is most likely my issue. At the time, for whatever reason, I was thinking it would do an equivalency check using the `ResourceLocation`s, which was a bad line of thinking on my part since a `PotionType` can contain multiple `Potion`s. On 1/28/2019 at 5:56 AM, V0idWa1k3r said: Why do you need this helper? World.isRemote is enough and shorter. Expand The internals of that method simply return world.isRemote. The only reason I made that method is because I kept mixing up whether "isRemote" is true on client or server, and got tired of going back to look at it every time (though I realize my extra method call makes it a bit less efficient; I don't think the compiler is optimizing it out). I'll try fixing my registries and post the results. Quote
Laike_Endaril Posted January 29, 2019 Author Posted January 29, 2019 (edited) Yes, that was the issue. The potion is synchronizing to the client now, and all I did was make sure the same Potion instance was used in both registration events. My new, working Potions class (which handles the registrations): Reveal hidden contents package com.fantasticsource.dynamicstealth.common.potions; import com.fantasticsource.dynamicstealth.common.DynamicStealth; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionType; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class Potions { public static final Potion POTION_SOULSIGHT = new PotionSoulSight(); public static final PotionType POTIONTYPE_SOULSIGHT_NORMAL = new PotionType(DynamicStealth.MODID + ".soulSight", new PotionEffect(POTION_SOULSIGHT, 200)).setRegistryName(DynamicStealth.MODID, "soulSight"); @SubscribeEvent public static void registerPotions(RegistryEvent.Register<Potion> event) { event.getRegistry().register(POTION_SOULSIGHT); } @SubscribeEvent public static void registerPotionTypes(RegistryEvent.Register<PotionType> event) { event.getRegistry().register(POTIONTYPE_SOULSIGHT_NORMAL); } } I have a couple minor changes to make on it still (such as changing it from a debuff to a buff, so milk doesn't remove it), but it works, and both of my icons are displaying. Edit: Forgot that milk removes buffs as well. W/e. Edited January 29, 2019 by Laike_Endaril Quote
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.