Jump to content

Prevent FULL AUTO item use


xanderindalzone

Recommended Posts

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?

c36ec67dae09751cd36d1812e8e2d07e.png

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

 

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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?

fb4c073533deaaed3067d8f8115be575.png

Link to comment
Share on other sites

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 by Novârch
  • Thanks 1

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".

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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;
    }

 

 

 

Link to comment
Share on other sites

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".

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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".

Link to comment
Share on other sites

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 by poopoodice
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.