March 26, 20187 yr Author 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...
March 26, 20187 yr 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.
March 27, 20187 yr 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. I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
March 27, 20187 yr 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. I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
March 27, 20187 yr Author 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, 20187 yr by LaurentOutang
March 28, 20187 yr Author 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...
March 29, 20187 yr Author 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, 20187 yr by LaurentOutang
March 31, 20187 yr Author 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 !
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.