Melonslise
Members-
Posts
183 -
Joined
-
Last visited
Everything posted by Melonslise
-
Oh so in that case have I attached it to both in my handler? Because I'm not sure at all.
-
1. Done Actually I do understand the concept of server and client thing. But tbh I thought that IEEP exists only the server side so I thought I would need to create new values for the client side, but apparently not anymore. So basically the IEEP side is determined by the class from which you get it's values? (client/server class) And btw I do learn Pascal in school. But pascal is is totally different to this Java.
-
You are already doing that in your GUI... So if I'm already doing it then why isn't it working? I just thought of something. If I were to create two variables in the GUI class and let the handler assign the received packet data to those two variables and then set these variables into drawString, would that work (multiplayer too)?
-
6. Fixed 7. Fixed 8. So how would I get the player's client-side properties?
-
1. Fixed 2. The additional reference is required in the gui registry MinecraftForge.EVENT_BUS.register(new GUIManaBar(Minecraft.getMinecraft())); 3. Fixed 4. Ok, I got rid of the HandlerGUI event (I don't even know what I added it for) 5. Fixed 6. Ok I added this in the common proxy: public abstract Side getSide(); This in the client proxy: public Side getSide() { return Side.CLIENT; } And this in the server proxy: public Side getSide() { return Side.SERVER; } and this is the new event registry: if (proxy.getSide() == Side.CLIENT) { MinecraftForge.EVENT_BUS.register(new GUIManaBar(Minecraft.getMinecraft())); } 7. If I don't add the return type then it will give me an error over the method 8. I still can't quite grasp how these packets work. So what is this setMana() method? btw here's my repo for convenience https://github.com/Melonslise/Runic-Inscription/tree/master/Java/melonslise/runicinscription
-
Sorry for my retardedness, but here all my code so far and the GUI is still not being updated: Here's my IEEP: package melonslise.runicinscription.Network; import melonslise.runicinscription.RunicInscription; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; import net.minecraftforge.common.util.Constants; public class ManaProperties implements IExtendedEntityProperties { public final static String EXT_PROP_MANA = RunicInscription.MODID + "_Mana"; private final EntityPlayer player; private int currentMana; private int maxMana; public ManaProperties(EntityPlayer player) { this.player = player; this.currentMana = 30; this.maxMana = 30; } public static final void register(EntityPlayer player) { player.registerExtendedProperties(ManaProperties.EXT_PROP_MANA, new ManaProperties(player)); } public static final ManaProperties get(EntityPlayer player) { return (ManaProperties) player.getExtendedProperties(EXT_PROP_MANA); } @Override public void saveNBTData(NBTTagCompound compound) { NBTTagCompound properties = new NBTTagCompound(); properties.setInteger("CurrentMana", this.currentMana); properties.setInteger("MaxMana", this.maxMana); compound.setTag(EXT_PROP_MANA, properties); } @Override public void loadNBTData(NBTTagCompound compound) { if(compound.hasKey(EXT_PROP_MANA, Constants.NBT.TAG_COMPOUND)) { NBTTagCompound properties = compound.getCompoundTag(EXT_PROP_MANA); this.currentMana = properties.getInteger("CurrentMana"); this.maxMana = properties.getInteger("MaxMana"); } } @Override public void init(Entity entity, World world) { } public boolean consumeMana(int amount) { if(this.currentMana >= amount) { currentMana = currentMana - amount; return true; } this.syncMana(); return false; } public void replenishMana() { this.currentMana = this.maxMana; this.syncMana(); } public int getMaxMana() { return this.maxMana; } public int getCurrentMana() { return this.maxMana; } public final void syncMana() { RunicInscription.network.sendTo(new MaxManaMessage(this.maxMana), (EntityPlayerMP) player); RunicInscription.network.sendTo(new CurrentManaMessage(this.currentMana), (EntityPlayerMP) player); } } and it's handler: package melonslise.runicinscription.Handler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import melonslise.runicinscription.Network.ManaProperties; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.player.PlayerEvent.Clone; public class HandlerManaEvents { @SubscribeEvent public void onEntityConstructing(EntityConstructing event) { if (event.entity instanceof EntityPlayer) { event.entity.registerExtendedProperties(ManaProperties.EXT_PROP_MANA, new ManaProperties((EntityPlayer) event.entity)); } } @SubscribeEvent public void onClonePlayer(Clone event) { if(event.wasDeath) { NBTTagCompound compound = new NBTTagCompound(); ManaProperties.get(event.original).saveNBTData(compound); ManaProperties.get(event.entityPlayer).loadNBTData(compound); } } @SubscribeEvent public void onEntityJoinWorld(EntityJoinWorldEvent event) { if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) ManaProperties.get((EntityPlayer) event.entity).syncMana(); } } which is registered in the main mod class: @EventHandler public void init(FMLInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new HandlerManaEvents()); and here's the GUI: package melonslise.runicinscription.GUI; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import melonslise.runicinscription.Network.ManaProperties; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; public class GUIManaBar extends Gui { private Minecraft mc; public GUIManaBar(Minecraft mc) { super(); this.mc = mc; } @SubscribeEvent public void OnRender(RenderGameOverlayEvent event) { if (event.isCancelable() || event.type != ElementType.EXPERIENCE) { return; } ManaProperties props = ManaProperties.get(this.mc.thePlayer); if (props == null) { return; } System.out.print("Drawn"); mc.fontRenderer.drawStringWithShadow("§1" + props.getCurrentMana() + "/" + props.getMaxMana(), 2, 2, 1); } } and here's it's handler: package melonslise.runicinscription.Handler; import cpw.mods.fml.client.GuiNotification; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import melonslise.runicinscription.GUI.GUIManaBar; import net.minecraft.client.Minecraft; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; public class HandlerGUI { @SubscribeEvent public void onRenderGUI(RenderGameOverlayEvent.Post event) { } } And here's the handler and the GUI in the main class: @EventHandler public void init(FMLInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new HandlerGUI()); } @EventHandler public void postInit(FMLPostInitializationEvent event) { { if (FMLCommonHandler.instance().getEffectiveSide().isClient()) MinecraftForge.EVENT_BUS.register(new GUIManaBar(Minecraft.getMinecraft())); } } And here's a packet for the players' max mana package melonslise.runicinscription.Network; import cpw.mods.fml.common.network.simpleimpl.IMessage; import io.netty.buffer.ByteBuf; public class MaxManaMessage implements IMessage { private int maxMana; public MaxManaMessage() { } public MaxManaMessage(int maxMana) { this.maxMana = maxMana; } @Override public void toBytes(ByteBuf buf) { buf.writeInt(maxMana); } @Override public void fromBytes(ByteBuf buf) { maxMana = buf.readInt(); } public int getMaxMana() { return maxMana; } } and it's handler: package melonslise.runicinscription.Handler; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import melonslise.runicinscription.RunicInscription; import melonslise.runicinscription.Network.CurrentManaMessage; import melonslise.runicinscription.Proxy.CommonProxy; import net.minecraft.entity.player.EntityPlayer; public class HandlerCurrentManaMessage implements IMessageHandler<CurrentManaMessage, IMessage> { @Override public IMessage onMessage(CurrentManaMessage message, MessageContext ctx) { EntityPlayer player = RunicInscription.proxy.getClientPlayer(); int currentMana = message.getCurrentMana(); return null; } } and here's the packet for the players' current mana: package melonslise.runicinscription.Network; import cpw.mods.fml.common.network.simpleimpl.IMessage; import io.netty.buffer.ByteBuf; public class CurrentManaMessage implements IMessage { private int currentMana; public CurrentManaMessage() { } public CurrentManaMessage(int currentMana) { this.currentMana = currentMana; } @Override public void toBytes(ByteBuf buf) { buf.writeInt(currentMana); } @Override public void fromBytes(ByteBuf buf) { currentMana = buf.readInt(); } public int getCurrentMana() { return currentMana; } } and it's handler: package melonslise.runicinscription.Handler; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import melonslise.runicinscription.RunicInscription; import melonslise.runicinscription.Network.MaxManaMessage; import net.minecraft.entity.player.EntityPlayer; public class HandlerMaxManaMessage implements IMessageHandler<MaxManaMessage, IMessage> { @Override public IMessage onMessage(MaxManaMessage message, MessageContext ctx) { EntityPlayer player = RunicInscription.proxy.getClientPlayer(); int amount = message.getMaxMana(); return null; } } And both are registered in the main class: public static SimpleNetworkWrapper network;[/p] network = NetworkRegistry.INSTANCE.newSimpleChannel("RunicInscription"); network.registerMessage(HandlerCurrentManaMessage.class, CurrentManaMessage.class, 1, Side.CLIENT); network.registerMessage(HandlerMaxManaMessage.class, MaxManaMessage.class, 2, Side.CLIENT); And there's a method in the client proxy and server proxy which return either the player(for clients) or null(for servers) which is used in the packet handlers: ClientProxy public EntityClientPlayerMP getClientPlayer() { return Minecraft.getMinecraft().thePlayer; } ServerProxy public EntityClientPlayerMP getClientPlayer() { return null; } And here's a snippet of code from an item which decreases the player's mana: if (props.consumeMana(15)) { System.out.println("Player had enough mana. Do something awesome!"); } else { System.out.println("Player ran out of mana. Sad face."); props.replenishMana(); }
-
Because I'm supposed to have a mana regen which is handled after every tick
-
SO would this be the correct way of sending the packet? (this is located in my IEEP) public final void syncCurrentMana() { RunicInscription.network.sendTo(new CurrentManaMessage(this.currentMana), (EntityPlayerMP) player); } The method is being called in the IEEP's handler @SubscribeEvent public void onUpdatePlayer(LivingUpdateEvent event) { ManaProperties.get((EntityPlayer) event.entity).syncCurrentMana(); }
-
Ok, now we got that out of the way. Now how would I go about sending packets to the client? Would I need to create a LivingUpdateEvent in my IEEP handler and send packets from there?
-
Ahh, I see now. Wow, sometimes I am suprised at my stupidness
-
Ahahah. Dat meme. In the common proxy it's telling me to change getClientPlayer to void which I cannot do. I also can't change client proxy's getClientPlayer to abstract (I don't think). And I had registered the proxies in the main mod class a long time ago. EDIT: Where did the meme go? ;(
-
There's still one thing that I don't understand. What do I return in my common proxy? public EntityClientPlayerMP getClientPlayer() { return ; }
-
Alright I found the solution, but I did google around a little and found this: EntityPlayer thePlayer = (ctx.side.isClient() ? Minecraft.getMinecraft().thePlayer : ctx.getServerHandler().playerEntity); wouldn't this be better than calling methods from the proxies?
-
I started off creating getClientPlayer() in the client proxy, but now it's telling me that it cannot create a static reference to a non-static field /:
-
So how exactly would I make this proxy? As in a new class? How would the getter look like? A small snippet of code would help me understand better.
-
This is correct, I just pointed that out since i didn't see you register it. (missed it or you didn't provide code). Anyway - handler is the receiver so it is logical that if receiver is client you can (should) use client-only stuff, in this case - use client player. EDIT In case you would want to update client's data about entity that is NOT Minecraft#thePlayer, you will need to send Entity#entityId (via packet) and use Minecraft#theWorld#getEntityById(entityId) to retrieve it. But I did change to this: EntityPlayer player = ctx.getClientHandler().playerEntity; and it's saying that playerEntity cannot be resolved
-
I though the receiving end was registered here: network.registerMessage(HandlerCurrentManaMessage.class, CurrentManaMessage.class, 1, Side.CLIENT); But I did change to this: EntityPlayer player = ctx.getClientHandler().playerEntity; and it's saying that playerEntity cannot be resolved
-
They are supposed to be sent to the client to update the GUI with the player's current and max mana
-
No, I won't ask. But I will say: stop. Never have code in your mod (or any other programming project) that you don't understand. You should simply register your IEEP. Nothing more. You put it in the identifier. Like I said. Not in the constructor. I don't know, I don't keep track of 1.7.10 tutorials. Alright, So I created two messages and two handlers for them: Message about current mana: and it's handler Message about max mana: and it's handler: So how do I integrate these into my GUI and IEEP?
-
I am making a mod for 1.7.10. (Just incase you ask, I will be updating it to 1.8 and don't ask why I am using 1.7.10) I don't know why. I was following coolAlias' tutorial on this thing. What should I have in the handler then? Where do I put my mod id then? (As I said I was following coolAlias' tutorial on IEEP) Ok I'll change that How should I draw it then? I followed this tutorial : https://emxtutorials.wordpress.com/simple-in-game-gui-overlay/ Where can I find a good and detailed tutorial on packets in 1.7.10?
-
I created a class extending IExtendedEntityProperties: And here's it's handler: And here's the GUI And it's hander: And both are registered in the mod class Here's an item's onItemRightClick code: And when right clicked the gui values don't change
-
Just one last question. When I only have one of those items and I use it, the particles don't spawn. I understand why, but have 0 ideas on how to fix that. Would be great if there was a solution.
-
What do you mean I don't need your help? Of course I do. I will try this, but wouldn't NBT cause problems (as stated above, if a player uses the item and immediately throws it away then the whole particle spawning thing would be screwed over)? EDIT: Your code works (except for those enum thingies which I had to remove)! thanks a lot. You will be N1 in my credits list. Cheers But still wouldn't NBT cause problems as stated above? This solution is also good though. Here's the code if someone is interested: Don't forget to wrap it in !(world.isRemote)
-
2. Because you can wrap all of your "if (tick == 10)" to "if (tick <= 60 && tick % 10 == 0)". - Generally - if code appears more than once, it should be in loop or private method (with exceptions, obviously). 3. Precisely because above and the fact that you are doing stuff like this: NBTTagCompound nbt; if (itemStack.hasTagCompound()) { nbt = itemStack.getTagCompound(); } else { nbt = new NBTTagCompound(); } nbt.setBoolean("cast", true); nbt.setInteger("ticks", 0); if (!player.capabilities.isCreativeMode) { --itemStack.stackSize; } itemStack.setTagCompound(nbt); if (!player.capabilities.isCreativeMode) { --itemStack.stackSize; } * Notice you are doing "--itemStack.stackSize;" twice. * How about removing double and triple blank lines? * The way you operate on NBT is NOT == to the one coolAlias proposed and yes - yours is worse (Mainly because it calls "itemStack.setTagCompound(nbt);" no matter what and is longer). * You are using "--itemStack.stackSize;" without checking if stack size <= 0. Whenever stack size is reduced to 0 you need to take care of removing it from inventory. In this method's case you need to return null (At least I think so, you are seriously outdated). 4. Yeah, and also by people. I will just point out why you should use it: * Because Java conventions. * Because it's more readable, following: * Because without superclass I/We can't tell if this method is ACTUALLY overriding (has super) something or not. - Why can't we just look into code ouselves? Well - as said, 1.7 is super outdated, for one the method Item#onUpdate in 1.9 looks like this: /** * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and * update it's contents. */ public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) { } So yeah... My 1st thought was that you are not actually overriding super method when I looked at it (your code), and I am still not quite sure if you do. Aside from all that: Yes. Now the real problem appears in design part. I would alredy tell you step by step how-to, but since you are outdated I need to ask - does #onUpdate have ANY params (if not, you will have to use client evensts to spawn particles on per-tick basis)? Why would I want to swap == with %? * --itemStack.stackSize; twice was a copy and paste accident. * Blank lines do not effect the code in any way. * Checking for the size of the stack is not necessary (At least in 1.7.10). Take a look at the itemSnowball, I copied the code from there. As for onUpdate: /** * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and * update it's contents. */ public void onUpdate(ItemStack p_77663_1_, World p_77663_2_, Entity p_77663_3_, int p_77663_4_, boolean p_77663_5_) {} Um, you may as well say "I want my car to go places, so why would I need brakes?" Coding an exact match to achieve an override is tricky enough that it's one of the most common sources of error brought to this forum. Also, because a flawed override may leave a parental method running in place of what you expect, the runtime effects can be unpredictable and subtle, making them difficult to diagnose, especially at a distance when we try to help. Finally, and perhaps most important, Minecraft's code does shift with each new version. When you port a mod to a new MC version, there will often be methods in your extended classes that were correctly overriding their parents in the prior version but are not proper matches in the new version. Believe me when I say that it is a blessing to have the Eclipse IDE call them all out in bright red rather than having to diagnose a whole bunch of subtle misbehavior at runtime. Therefore, always always always put the @Override annotation on absolutely every method that you as designer intend as an override. Do not ever skimp on any of them, not even one, not ever. Alright
-
Should I even be doing this through NBT? Maybe I should make some other handler class or something of the sort? Because I think that doing this through NBT maybe not be very stable (eg. someone uses the item and immediately throws it away then will the rest of particles work? or some other similar scenario)