LaurentOutang Posted March 26, 2018 Author Posted March 26, 2018 Do you have any idea how I should use the classes that i created ? The problem is that the MentalTemperature have not the same value in the two events... Quote
jhdoran Posted March 26, 2018 Posted March 26, 2018 I think a Git repository is in order. Right now its a piece of code here, a piece of code there. I'm not sure what you are trying to do. Nor do I know what events you are talking about. Quote
LexManos Posted March 27, 2018 Posted March 27, 2018 public static final Capability<IMentalTemperature> MentalTemperature_CAP = null; private IMentalTemperature instance = MentalTemperature_CAP.getDefaultInstance(); That code turns into this: public static final Capability<IMentalTemperature> MentalTemperature_CAP; private IMentalTemperature instance; static { MentalTemperature_CAP = null; instance = MentalTemperature_CAP.getDefaultInstance(); } Now, when you see that, isn't the issue OBVIOUS!?! MentalTemprature_CAP WILL ALWAYS BE NULL when you try to call it to set instance. (Also resisting urge to yell at you about code style) @CapabilityHolders are only populated when someone registers a capability. That's the entire freaking point. It's a soft dependency on that class. 1st) You're trying to make a soft dependacy so making a field of that exist type is not recommended. So instance should be Object. 2nd) You should delay creating that instance until it's needed, Or until you are told that that capability exists. You can annotate a method with @CapabilityInject and a single argument of a CapabilityHolder and it'll be called whenever that apropriate cap is registered. Quote I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
LexManos Posted March 27, 2018 Posted March 27, 2018 Eah, still the case if this object is instantiated before the capability is registered. It's still the same problem. As the same issues I specified. Quote I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
LaurentOutang Posted March 27, 2018 Author Posted March 27, 2018 (edited) IMentalTemperature package com.laurentoutang.hardmod.capabilities; public interface IMentalTemperature { public void consumeMental(float points); public void fillMental(float points); public void setMental(float points); public float getMental(); public void consumeTemperature(float points); public void fillTemperature(float points); public void setTemperature(float points); public float getTemperature(); } MentalTemperature package com.laurentoutang.hardmod.capabilities; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class MentalTemperature implements IMentalTemperature{ private float mental = 100.f; private float temperature = 100.f; public MentalTemperature(float mental, float temperature) { this.mental = mental; this.temperature = temperature; } public MentalTemperature() { } @Override public void consumeMental(float points) { if(mental-points < 0) mental = 0; else mental -= points; } @Override public void fillMental(float points) { if(mental + points > 100) mental = 100; else mental += points; } @Override public void setMental(float points) { mental = points; } @Override public float getMental() { return mental; } public void consumeTemperature(float points) { if(temperature-points < 0) temperature = 0; else temperature -= points; } public void fillTemperature(float points) { if(temperature + points > 100) temperature = 100; else temperature += points; } public void setTemperature(float points) { temperature = points; } public float getTemperature() { return temperature; } } MentalTemperatureProvider package com.laurentoutang.hardmod.capabilities; import java.util.concurrent.Callable; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTPrimitive; import net.minecraft.nbt.NBTTagFloat; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.Capability.IStorage; public class MentalTemperatureProvider implements ICapabilitySerializable<NBTBase>{ @CapabilityInject(IMentalTemperature.class) public static final Capability<IMentalTemperature> MentalTemperature_CAP = null; private IMentalTemperature instance = MentalTemperature_CAP.getDefaultInstance(); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == MentalTemperature_CAP; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (MentalTemperature_CAP != null && capability == MentalTemperature_CAP) return MentalTemperature_CAP.<T> cast(this.instance); return null; } @Override public NBTBase serializeNBT() { return MentalTemperature_CAP.getStorage().writeNBT(MentalTemperature_CAP, this.instance, null); } @Override public void deserializeNBT(NBTBase nbt) { MentalTemperature_CAP.getStorage().readNBT(MentalTemperature_CAP, this.instance, null, nbt); } } MentalTemperatureStorage package com.laurentoutang.hardmod.capabilities; import net.minecraft.inventory.ItemStackHelper; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTPrimitive; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagFloat; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability.IStorage; import net.minecraftforge.common.capabilities.CapabilityManager; public class MentalTemperatureStorage implements IStorage<IMentalTemperature>{ @Override public NBTBase writeNBT(Capability<IMentalTemperature> capability, IMentalTemperature instance, EnumFacing side) { NBTTagCompound tag = new NBTTagCompound(); tag.setFloat("Mental", instance.getMental()); tag.setFloat("Temperature", instance.getTemperature()); return tag; } @Override public void readNBT(Capability<IMentalTemperature> capability, IMentalTemperature instance, EnumFacing side, NBTBase nbt) { NBTTagCompound tag = ((NBTTagCompound)nbt); instance.setMental(tag.getFloat("Mental")); instance.setTemperature(tag.getFloat("Temperature")); } } ClientProxy package com.laurentoutang.hardmod.proxy; import com.laurentoutang.hardmod.capabilities.IMentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperatureStorage; import com.laurentoutang.hardmod.util.handlers.CapabilityHandler; import com.laurentoutang.hardmod.util.handlers.MessageCapabilitiesHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.util.IThreadListener; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.relauncher.Side; public class ClientProxy extends CommonProxy { public void init() { MinecraftForge.EVENT_BUS.register(new MessageCapabilitiesHandler()); } public IThreadListener getListener(MessageContext ctx) { return ctx.side == Side.CLIENT ? Minecraft.getMinecraft() : super.getListener(ctx); } public EntityPlayer getPlayer(MessageContext ctx) { return ctx.side == Side.CLIENT ? Minecraft.getMinecraft().player : super.getPlayer(ctx); } public void registerItemRenderer(Item item, int meta, String id) { ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName(), id)); } } CommonProxy package com.laurentoutang.hardmod.proxy; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.util.IThreadListener; import net.minecraft.world.WorldServer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class CommonProxy { public void init() { } public IThreadListener getListener(MessageContext ctx) { return (WorldServer) ctx.getServerHandler().player.getServerWorld(); } public EntityPlayer getPlayer(MessageContext ctx) { return ctx.getServerHandler().player; } public void registerItemRenderer(Item item, int meta, String id) { } } CapabilityHandler package com.laurentoutang.hardmod.util.handlers; import com.laurentoutang.hardmod.capabilities.MentalTemperatureProvider; import com.laurentoutang.hardmod.util.Reference; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; @EventBusSubscriber public class CapabilityHandler { public static final ResourceLocation MentalTemperature_CAP = new ResourceLocation(Reference.MOD_ID, "mentaltemperature"); @SubscribeEvent public static void attachCapability(AttachCapabilitiesEvent<Entity> event) { if (event.getObject() instanceof EntityPlayer) { event.addCapability(MentalTemperature_CAP, new MentalTemperatureProvider()); } } } EventHandler package com.laurentoutang.hardmod.util.handlers; import com.laurentoutang.hardmod.capabilities.IMentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperatureProvider; import com.laurentoutang.hardmod.util.Reference; import Network.MessageCapabilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.EnumHand; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.fml.relauncher.Side; @EventBusSubscriber public class EventHandler { @SubscribeEvent public static void onPlayerLogsIn(PlayerLoggedInEvent event) { EntityPlayer player = event.player; IMentalTemperature capabilities = player.getCapability(MentalTemperatureProvider.MentalTemperature_CAP, null); if(capabilities != null) { capabilities.consumeMental(2.f); String message = String.format("Logged in : mental = " + capabilities.getMental()); player.sendMessage(new TextComponentString(message)); } } @SubscribeEvent public static void onPlayerInteract(PlayerInteractEvent event) { EntityPlayer player = event.getEntityPlayer(); if(event.getHand() == EnumHand.MAIN_HAND) { IMentalTemperature capabilities = player.getCapability(MentalTemperatureProvider.MentalTemperature_CAP, null); if(capabilities != null) { capabilities.consumeMental(1.f); String message = String.format("Player interact mental = " + capabilities.getMental()); player.sendMessage(new TextComponentString(message)); } } } } MessageCapabilityHandler package com.laurentoutang.hardmod.util.handlers; import java.util.List; import com.laurentoutang.hardmod.capabilities.IMentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperatureProvider; import Network.MessageCapabilities; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.IThreadListener; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.relauncher.Side; @EventBusSubscriber(value = Side.CLIENT) public class MessageCapabilitiesHandler implements IMessageHandler<MessageCapabilities, IMessage>{ @Override public IMessage onMessage(MessageCapabilities message, MessageContext ctx) { final float mental = message.getMental(); final float temperature = message.getTemperature(); Minecraft minecraft = Minecraft.getMinecraft(); final WorldClient worldClient = minecraft.world; minecraft.addScheduledTask(new Runnable() { public void run() { processMessage(worldClient, message); } }); return null; } void processMessage(WorldClient worldClient, MessageCapabilities message) { List<EntityPlayer> players = worldClient.playerEntities; for(int i = 0; i < players.size(); i++) { players.get(i).sendMessage(new TextComponentString("You have " + message.getMental() + " mental left and " + message.getTemperature() + " temperature left")); } return; } } PacketHandler package com.laurentoutang.hardmod.util.handlers; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; public class PacketHandler { public static final SimpleNetworkWrapper NETWORK = NetworkRegistry.INSTANCE.newSimpleChannel("hm"); } MessageCapability package Network; import io.netty.buffer.ByteBuf; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class MessageCapabilities implements IMessage{ private float mentalToSend, temperatureToSend; public MessageCapabilities() {} public MessageCapabilities(float mentalToSend, float temperatureToSend) { this.mentalToSend = mentalToSend; this.temperatureToSend = temperatureToSend; } @Override public void fromBytes(ByteBuf buf) { this.mentalToSend = buf.readFloat(); this.temperatureToSend = buf.readFloat(); } @Override public void toBytes(ByteBuf buf) { buf.writeFloat(this.mentalToSend); buf.writeFloat(this.temperatureToSend); } public float getMental() { return mentalToSend; } public float getTemperature() { return temperatureToSend; } } Main package com.laurentoutang.hardmod; import org.apache.logging.log4j.core.jmx.Server; import com.laurentoutang.hardmod.capabilities.IMentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperatureStorage; import com.laurentoutang.hardmod.proxy.CommonProxy; import com.laurentoutang.hardmod.util.Reference; import com.laurentoutang.hardmod.util.handlers.MessageCapabilitiesHandler; import com.laurentoutang.hardmod.util.handlers.PacketHandler; import Network.MessageCapabilities; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.server.MinecraftServer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; @Mod(modid = Reference.MOD_ID, name = Reference.NAME, version = Reference.VERSION) public class Main { @Instance public static Main instance; @SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.COMMON_PROXY_CLASS) public static CommonProxy proxy; @EventHandler public static void PreInit(FMLPreInitializationEvent event) { CapabilityManager.INSTANCE.register(IMentalTemperature.class, new MentalTemperatureStorage(), MentalTemperature::new); PacketHandler.NETWORK.registerMessage(MessageCapabilitiesHandler.class, MessageCapabilities.class, 0, Side.SERVER); } @EventHandler public static void init(FMLInitializationEvent event) { } @EventHandler public static void PostInit(FMLPostInitializationEvent event) { } } Here is the code. The problem is that in EventHandler class the two events do not give the same value for mental. When I connect i see a value that is modified at each connection (fine) but when i click, it starts from 100 everytime. So I created packets (thanks to tutorials) but I do not know how to sync capabilities with it ? public static final Capability<IMentalTemperature> MentalTemperature_CAP = null; private IMentalTemperature instance = MentalTemperature_CAP.getDefaultInstance(); for these lines I found it on 2 different tutorials. I dont't know how I should instantiate the MentalTemperature_CAP otherwise. Thank you for you help and your attention Edited March 27, 2018 by LaurentOutang Quote
LaurentOutang Posted March 28, 2018 Author Posted March 28, 2018 I found a trick i modified the EventHandler class like that package com.laurentoutang.hardmod.util.handlers; import com.laurentoutang.hardmod.capabilities.IMentalTemperature; import com.laurentoutang.hardmod.capabilities.MentalTemperatureProvider; import com.laurentoutang.hardmod.util.Reference; import Network.MessageCapabilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.EnumHand; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.fml.relauncher.Side; @EventBusSubscriber public class EventHandler { static IMentalTemperature capabilities; @SubscribeEvent public static void onPlayerLogsIn(PlayerLoggedInEvent event) { EntityPlayer player = event.player; capabilities = player.getCapability(MentalTemperatureProvider.MentalTemperature_CAP, null); if(capabilities != null) { capabilities.consumeMental(2.f); String message = String.format("Logged in : mental = " + capabilities.getMental()); player.sendMessage(new TextComponentString(message)); } } @SubscribeEvent public static void onPlayerInteract(PlayerInteractEvent event) { EntityPlayer player = event.getEntityPlayer(); if(event.getHand() == EnumHand.MAIN_HAND) { if(capabilities != null) { capabilities.consumeMental(1.f); String message = String.format("Player interact mental = " + capabilities.getMental()); player.sendMessage(new TextComponentString(message)); } } } } Because the log player event is the first that is called for what I need, it works. But I'm pretty sure there is a better way to do it... Quote
LaurentOutang Posted March 29, 2018 Author Posted March 29, 2018 (edited) The problem now is that when I play alone on the server the capability works. But when another player comes, it is reset to the initial values... What should I do to attach one capability for each player ? Thank you Edited March 29, 2018 by LaurentOutang Quote
LaurentOutang Posted March 31, 2018 Author Posted March 31, 2018 I think I've found a nice example of what I want to do rigth here https://github.com/RickyvdBerg/MC_School_Of_Mages/tree/master/src Thank's everyone for the help ! 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.