July 7, 20205 yr Author 4 hours ago, Draco18s said: Well, you registered a new keybinding. Did you create a static reference to hold it? Did you do anything to make sure that reference had a value? I had this before in the mod class... but diesieben07 told me that KeyBinding was a Client-Only class so I removed it.
July 7, 20205 yr Author 51 minutes ago, diesieben07 said: You cannot put it in your mod class, because your mod class is loaded on client and server. You must put it in a client-only class (or rather: By putting this in a class, that class by proxy becomes client-only as well. If you put it in your main mod class, your main mod class becomes client only, which makes your whole mod client-only). I believe I have to put some sort of annotation on top of the class/variable to specify its only a client class/variable. But from what I read from the Javadoc, this wouldn't work with initializers I think, right? What do I have to put to specify that this class/variable only runs in client, if this isn't it? Or no annotation at all, like you said here? 1 hour ago, diesieben07 said: By putting this in a class, that class by proxy becomes client-only as well
July 7, 20205 yr Author 45 minutes ago, diesieben07 said: Do not use @OnlyIn. To access client-only classes (such as KeyBinding or your now created InitKeys class, which is client-only because it has a reference to KeyBinding in it) either use @EventBusSubscriber with a Dist.CLIENT parameter or use DistExecutor (somewhat awkward to use correctly). Previously I was calling the key variable from 2 places: 1.A client event from the client-side only event-handler like you said now. 53 minutes ago, diesieben07 said: @EventBusSubscriber with a Dist.CLIENT Quote @Mod.EventBusSubscriber(modid = CustomGunsMod.MOD_ID, bus = Bus.FORGE, value = Dist.CLIENT) public class ClientGunEvents { /** * Displays the Gun Ammo in the gun held by the player * @param event */ @SubscribeEvent public static void displayGunStatus(RenderGameOverlayEvent.Text event) { PlayerEntity player = Minecraft.getInstance().player; int yd = event.getWindow().getScaledHeight(); int xd = event.getWindow().getScaledWidth(); int x=(int) (xd*0.01); int y=(int) (yd*0.65); int x2=(int) (xd*0.42); int y2=(int) (yd*0.7); if(Minecraft.getInstance().player.getHeldItemMainhand().getItem() instanceof Gun) { Gun gun = (Gun) player.getHeldItemMainhand().getItem(); FontRenderer TextRenderer = Minecraft.getInstance().fontRenderer; String text = "Gun AMMO: "; String textAmmo = "["+(gun.gun_mag-player.getHeldItemMainhand().getDamage())+"/"+gun.gun_mag+"]"; if(!player.isCreative()) { if(!((gun.gun_mag-player.getHeldItemMainhand().getDamage())>0)) { String text1="No AMMO!"; String text2="Press "+InitKeys.KEY_RELOAD_GUN.getLocalizedName().toUpperCase()+" to reload!"; TextRenderer.drawStringWithShadow(text1, x+10, y+20, 16730698); TextRenderer.drawStringWithShadow(text2, x+10, y+30, 16777215); } if(player.getCooldownTracker().hasCooldown(gun)) { String text3="Reloading!"; System.out.println(text3); TextRenderer.drawStringWithShadow(text3, x2+10, y2, 61256); } } else { textAmmo = "[oo/"+gun.gun_mag+"]"; } TextRenderer.drawStringWithShadow(text, x+10, y, 16777215); TextRenderer.drawStringWithShadow(textAmmo, x+10, y+10, 16245549); } } ........................... 2.A private method (reload) in the Gun class. Quote private boolean ReloadHandler(World worldIn, PlayerEntity player) { int ammo_left = (this.gun_mag-player.getHeldItemMainhand().getDamage()); boolean cock_reload = false; if(InitKeys.KEY_RELOAD_GUN.isKeyDown()) { ....................... I guess I'll have to make that reload method (2.) an event in the same event-handler as (1.), right?
July 10, 20205 yr Author On 7/7/2020 at 12:59 PM, diesieben07 said: Reloading is a server-side operation... so you need to send packets informing the server that you want to reload. After reading a few posts and wikis etc etc, I started with the packet thing, but when I tried to make the Message class, it appears I cant implement from IMessage. Is this a bug? or does this interface doesnt exist anymore?
July 10, 20205 yr 22 minutes ago, xanderindalzone said: or does this interface doesnt exist anymore? It doesn't exist anymore, you have to make the methods manually, it looks a bit like this: public class MyMessage { int value; public MyMessage(int value) { this.value = value; } public static void encode(MyMessage msg, PacketBuffer buffer) { buffer.writeInt(msg.value); } public static MyMessage decode(PacketBuffer buffer) { return new MyMessage(buffer.readInt()); //Remember to read in the same oreder you wrote! } public static void handle(MyMessage msg, Supplier<NetworkEvent.Context> ctx) { if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER) { //Checks if the packet's direction is to the server ctx.get().enqueueWork(() -> { //Your code goes here }); } ctx.get().setPacketHandled(true); } } I'm 99% sure that's correct, kinda freestyled it though. To send it use SimpleChannel#sendToServer, don't forget to register it with SimpleChannel#registerMessage, and don't worry if you don't understand it right away, it took me a while to fully understand packets in 1.15. Edited July 10, 20205 yr by Novârch It's sad how much time mods spend saying "x is no longer supported on this forum. Please update to a modern version of Minecraft to receive support".
July 10, 20205 yr Author 3 minutes ago, Novârch said: It doesn't exist anymore, you have to make the methods manually, it looks a bit like this: public class MyMessage { int value; public MyMessage(int value) { this.value = value; } public static void encode(MyMessage msg, PacketBuffer buffer) { buffer.writeInt(msg.value); } public static MyMessage decode(PacketBuffer buffer) { return new MyMessage(buffer.readInt()); //Remember to read in the same oreder you wrote! } public static void handle(MyMessage msg, Supplier<NetworkEvent.Context> ctx) { if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER) { //Checks if the packet's direction is to the server ctx.get().enqueueWork(() -> { //Your code goes here }); } ctx.get().setPacketHandled(true); } } I'm 99% sure that's correct, kinda freestyled it though. To send it use SimpleChannel#sendToServer, don't forget to register it with SimpleChannel#registerMessage, Thx a lot 4 minutes ago, Novârch said: and don't worry if you don't understand it right away, it took me a while to fully understand packets in 1.15. This is my first time with packets anyway XD, I'll give it a try this afternoon. 5 minutes ago, Novârch said: To send it use SimpleChannel#sendToServer, don't forget to register it with SimpleChannel#registerMessage Yeah, I'm aware of this, I just needed the message class.
July 11, 20205 yr Author On 7/7/2020 at 12:59 PM, diesieben07 said: Reloading is a server-side operation... so you need to send packets informing the server that you want to reload. Ok so I've now finished the packet implementation, its working as expected but I wanted to know your thoughts to know if its fine. Mod class packet handler registration Quote private void setup(final FMLCommonSetupEvent event) { PacketHandler.registerPackets(); } PacketHandler: Quote public class PacketHandler { private static int MESSAGE_ID = 0; private static final String PROTOCOL_VERSION = "1"; public static SimpleChannel channel = NetworkRegistry.newSimpleChannel( new ResourceLocation(CustomGunsMod.MOD_ID, "cgmchannel"), //"main" () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void registerPackets() { int id = 0; channel.registerMessage(id++, KeyReloadPressedMessage.class, KeyReloadPressedMessage::encode, KeyReloadPressedMessage::decode, KeyReloadPressedMessage::handle); id++; } Client-Side Event: Quote @SubscribeEvent public static void ReloadGunPacketToServer(InputEvent event) { if(InitKeys.KEY_RELOAD_GUN.isPressed()) { //SEND PACKET TO SERVER PacketHandler.channel.sendToServer(new KeyReloadPressedMessage()); } } Message Class: Quote public class KeyReloadPressedMessage { public KeyReloadPressedMessage() {} public static void encode(KeyReloadPressedMessage msg, PacketBuffer buffer) {//buffer.writeBoolean(msg.key_pressed); } public static KeyReloadPressedMessage decode(PacketBuffer buffer) { return new KeyReloadPressedMessage(); //Remember to read in the same order you wrote! } public static void handle(KeyReloadPressedMessage msg, Supplier<NetworkEvent.Context> ctx) { if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER) { //Checks if the packet's direction is to the server ctx.get().enqueueWork(() -> { //Your code goes here ServerPlayerEntity player = ctx.get().getSender(); // the client that sent this packet World world = player.world; if(player.getHeldItemMainhand().getItem() instanceof Gun) { Gun gun = (Gun) player.getHeldItemMainhand().getItem(); gun.ReloadGun(world, player); } }); } ctx.get().setPacketHandled(true); } } Gun Reload Method: Quote public boolean ReloadGun(World worldIn, PlayerEntity player) { int ammo_left = (this.gun_mag-player.getHeldItemMainhand().getDamage()); boolean cock_reload = false; //COMPRUEBA SI EL CARGADOR SE PUEDE RECARGAR if(ammo_left!=this.gun_mag&&!player.isCreative()) { if(ammo_left==0) {cock_reload=true;} //COMPRUEBA SI EL JUGADOR TIENE MUNICION EN EL INVENTARIO if(player.inventory.hasItemStack(new ItemStack(this.ammo_used))) { for(int slotIndex=0; slotIndex<player.inventory.mainInventory.size(); slotIndex++) { int ammo_needed = this.gun_mag-ammo_left; ItemStack item = player.inventory.getStackInSlot(slotIndex).copy(); if(item.getItem() == this.ammo_used) { if(!worldIn.isRemote) { ammo_left=removeAmmo(player, ammo_needed, ammo_left, item, slotIndex); } else { ammo_left=removeAmmo(player, ammo_needed, ammo_left, item, slotIndex); } reloadingGunSound(worldIn, player, this, cock_reload); is_reloading=true; } } return true; } } return false; }
July 11, 20205 yr 4 hours ago, xanderindalzone said: Ok so I've now finished the packet implementation, its working as expected but I wanted to know your thoughts to know if its fine. Mod class packet handler registration PacketHandler: Client-Side Event: Message Class: Gun Reload Method: That's fine, all I would change is use ClientTickEvent instead of InputEvent. It's sad how much time mods spend saying "x is no longer supported on this forum. Please update to a modern version of Minecraft to receive support".
July 11, 20205 yr Author 41 minutes ago, Novârch said: That's fine, all I would change is use ClientTickEvent instead of InputEvent. Does that run in every tick? if it does, wouldn't that be more spammy than the InputEvent that runs when the player presses any controls? I could be wrong, it's the first time I heard of ClientTickEvent XD
July 11, 20205 yr 12 minutes ago, xanderindalzone said: Does that run in every tick? if it does, wouldn't that be more spammy than the InputEvent that runs when the player presses any controls? I could be wrong, it's the first time I heard of ClientTickEvent XD I have no idea why it's better, but I've seen people recommend it a lot on these forums, maybe someone else could clarify why. It's sad how much time mods spend saying "x is no longer supported on this forum. Please update to a modern version of Minecraft to receive support".
July 11, 20205 yr Input event only gets called once when pressed, which if you use TickEvent you can check if the mouse is down manually, and allows you to “fire while having the mouse pressed” instead of constantly clicking the mouse to fire Edited July 12, 20205 yr by poopoodice
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.