Пачка говнокода для паблик мода, нужна помощь.

Версия Minecraft
1.7.10

deleted.user

Мошенник
321
43
Всем вечер добрый или день, или что там у вас..
В общем, возникла идея сделать отдачу. Хоть я и пилю аналог старого доброго бразильского дэйзи, да только на версии поновее, решено было, что без отдачи не торт.
Запара в том, что оптимальнее всего делать отдачу каждый выстрел, что и делается в методе Shoot, но метод этот вызывается на сервере, что не дает работать с камерой игрока соответственно. Может я чего-то не знаю или не помню, но работать с камерой от сервера напрямую нельзя (?). Да и по итогу все это работает в onUpdate, что вызывает обновление предмета каждый выстрел и он "вытаскивается" заново, чего быть не должно. Как исправить это и что можете сказать по данному поводу? Я знаю, что это лютый говнокод, но он есть и я пытаюсь с ним бороться. Прошу нормальных советов по исправлению, а не "удоле, не пешы моды ы ы ы".
В итоге, вот такой класс оружия имеем сейчас:
Java:
public class ItemWeapon extends ItemDayZ {

    public static final Random rand = new Random();
    EntityClientPlayerMP clientPlayerMP = FMLClientHandler.instance().getClient().thePlayer; //То, что дропает сервер, естественно.
    public static Minecraft mc = Minecraft.getMinecraft();

    private static boolean mouseHeld = false;
    private static boolean lastMouseHeld;
    public Item Magi;
    public int ReloadTimei;
    private int FireRatei;
    private int Damagei;
    private int Rangei;
    private String Desc;
    private String ShotSound;
    private boolean Autoi = false;
    private boolean Primary = false;
    private int cooldi = 0;
    private boolean canShooti = true;
    private boolean WantShooti = false;
    public int reloading = 0;

    /**
     * Отдача за один выстрел.
     */
    private float recoilPitch;
    private float recoilYaw;
    private float rndRecoilPitchRange;
    private float rndRecoilYawRange;
    public float decreaseRecoilPitch;
    public float decreaseRecoilYaw;

    float recoil;


    public ItemWeapon(String texture, Item Mag, int reloadTime, int firerate, int maxDmg, int maxRange, String desc, String sound, float f1) {
        super(texture);
        this.Magi = Mag;
        this.ReloadTimei = reloadTime;
        this.FireRatei = firerate;
        this.Damagei = maxDmg;
        this.Rangei = maxRange;
        this.Desc = desc;
        this.ShotSound = sound;
        this.setMaxDamage(Mag.getMaxDamage());
        this.setMaxStackSize(1);
        this.setCreativeTab(DayZMod.tabGuns);
        recoil = f1;
    }

    public ItemWeapon setAutomatic() {
        this.Autoi = true;
        return this;
    }

    public ItemWeapon setPrimary() {
        this.Primary = true;
        return this;
    }

    @SideOnly(Side.CLIENT)
    public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
        if (stack.getItem() == this) {
            list.add("Damage: " + this.Damagei);
            list.add("Range: " + this.Rangei);
            list.add("Fire Rate: " + this.FireRatei);
            list.add("Ammo: " + this.Magi.getItemStackDisplayName(stack));
            list.add("Description: " + this.Desc);
        }
    }

    public boolean isPrimary() {
        return this.Primary;
    }

    public void wantShoot(boolean par1) {
        this.WantShooti = par1;
    }

    //TODO: пофиксить выстрел, что бы он не обновлял предмет каждый раз.
    public void onUpdate(ItemStack itemstack, World world, Entity entity, int i, boolean flag) {
        if (entity instanceof EntityPlayer && ((EntityPlayer) entity).getHeldItem() == itemstack) {
            if (world.isRemote) {
                this.UpdateClient(itemstack, world, entity, i, flag);
            } else {
                this.UpdateServer(itemstack, world, entity, i, flag);
            }
        }

    }

    @SideOnly(Side.CLIENT)
    public void UpdateClient(ItemStack itemstack, World world, Entity entity, int i, boolean flag) {
        if (entity instanceof EntityPlayer && ((EntityPlayer) entity).inventory.getCurrentItem() == itemstack) {
            Minecraft mc = Minecraft.getMinecraft();
            lastMouseHeld = mouseHeld;
            mouseHeld = false;

            GameSettings var100001 = mc.gameSettings;
            if (GameSettings.isKeyDown(mc.gameSettings.keyBindAttack) && mc.currentScreen == null) {
                mouseHeld = true;
            }

            if (mouseHeld && !lastMouseHeld) {
                DayZMod.DISPATCHER.sendToServer(PacketShoot.send(true));
            }

            if (!mouseHeld && lastMouseHeld) {
                DayZMod.DISPATCHER.sendToServer(PacketShoot.send(false));
            }

            var100001 = mc.gameSettings;
            if (GameSettings.isKeyDown(ClientProxy.Reload) && mc.currentScreen == null && itemstack.getItemDamage() == itemstack.getMaxDamage() && (((EntityPlayer) entity).capabilities.isCreativeMode || ((EntityPlayer) entity).inventory.hasItem(this.Magi)) && !((EntityPlayer) entity).isInWater() && !((EntityPlayer) entity).isSprinting()) {
                if (this.reloading == this.ReloadTimei) {
                    DayZMod.DISPATCHER.sendToServer(PacketReload.send(this.reloading));
                    ++this.reloading;
                } else {
                    ++this.reloading;
                }
            } else {
                this.reloading = 0;
            }
        }

    }

    public void UpdateServer(ItemStack itemstack, World world, Entity entity, int i, boolean flag) {
        if (entity instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) entity;
            if (player.getHeldItem() == itemstack) {
                if (!this.WantShooti) {
                    this.canShooti = true;
                } else {
                    this.Shoot(world, player, itemstack);
                }

                if (this.cooldi > 0) {
                    --this.cooldi;
                }
            }
        }

    }

    //TODO: добавить кастомные звуки
    public void Shoot(World world, EntityPlayer entity, ItemStack itemstack) {
        if (!world.isRemote && this.cooldi <= 0 && this.canShooti && this.WantShooti && itemstack.getItemDamage() != this.getMaxDamage()) {
            world.spawnEntityInWorld(new EntityBullet(world, entity, this.Damagei, this.Rangei));
            entity.worldObj.playSoundAtEntity(entity, "dayzmod:" + this.ShotSound, 1.0F, 0.0F);
            //if(this.canShooti = true) {
                //TODO: костыльная отдача, пофиксить.
                Random rand = new Random();
                int recoilRandInt = rand.nextInt(1);
                recoil += recoilRandInt;


                float stackRecoilPitch = this.recoilPitch + (rand.nextFloat() * this.rndRecoilPitchRange);
                float stackRecoilYaw = this.recoilYaw + ((rand.nextFloat() - 0.5F) * this.rndRecoilYawRange);

                if (rand.nextInt(4) == 0) {
                    mc.thePlayer.rotationPitch -= recoil * 2.0F;
                    mc.thePlayer.cameraPitch = this.recoil;
                    mc.thePlayer.prevCameraPitch += (float) (this.recoil / 2);
                } else {
                    mc.thePlayer.rotationPitch -= recoil * 2.0F;
                    mc.thePlayer.cameraPitch = this.recoil;
                    mc.thePlayer.prevCameraPitch += (float) (this.recoil / 2);
                }

                if (rand.nextBoolean()) {
                    if (rand.nextInt(3) == 0) {
                        clientPlayerMP.rotationPitch -= recoil * 2.0F;
                        clientPlayerMP.cameraPitch = this.recoil;
                        clientPlayerMP.prevCameraPitch += (float) (this.recoil / 2);
                    } else {
                        clientPlayerMP.rotationPitch -= recoil * 2.0F;
                        clientPlayerMP.cameraPitch = this.recoil;
                        clientPlayerMP.prevCameraPitch += (float) (this.recoil / 2);
                    }
                } else if (rand.nextInt(3) == 0) {
                    clientPlayerMP.rotationPitch -= recoil * 2.0F;
                    clientPlayerMP.cameraPitch = this.recoil;
                    clientPlayerMP.prevCameraPitch += (float) (this.recoil / 2);
                } else {
                    clientPlayerMP.rotationPitch -= recoil * 2.0F;
                    clientPlayerMP.cameraPitch = this.recoil;
                    clientPlayerMP.prevCameraPitch += (float) (this.recoil / 2);
                }
            //}
            itemstack.damageItem(1, entity);
            this.cooldi = this.FireRatei;
            if (!this.Autoi) {
                this.canShooti = false;
            }

        } else if (!world.isRemote && this.cooldi <= 0 && this.canShooti && this.WantShooti && itemstack.getItemDamage() == this.getMaxDamage()) {
            entity.worldObj.playSoundAtEntity(entity, "DayZMod:empty", 1.0F, 0.0F);
            this.cooldi = this.FireRatei;
            if (!this.Autoi) {
                this.canShooti = false;
            }
        }
    }

    public void Reload(ItemStack current, EntityPlayer entity) {
        if (entity.inventory.hasItem(this.Magi) || entity.capabilities.isCreativeMode) {
            entity.worldObj.playSoundAtEntity(entity, "DayZMod:reload", 1.0F, 0.0F);
            current.setItemDamage(0);
            if (!entity.capabilities.isCreativeMode) {
                entity.inventory.consumeInventoryItem(this.Magi);
            }
        }

    }

    public void onPlayerStoppedUsing(ItemStack itemstack, World world, EntityPlayer entityplayer, int i) {
    //TODO
    }

    public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) {
        return true;
    }

    public float getRecoilPitch(ItemStack stack) {
        float stackRecoil = this.recoilPitch + (rand.nextFloat() * this.rndRecoilPitchRange);
        return stackRecoil;
    }

    public float getRecoilYaw(ItemStack stack) {
        float stackRecoilYaw = this.recoilYaw + ((rand.nextFloat() - 0.5F) * this.rndRecoilYawRange);
        return stackRecoilYaw;
    }
 
Последнее редактирование:
167
3
23
1) EntityClientPlayerMP clientPlayerMP = FMLClientHandler.instance().getClient().thePlayer; <- при повторном заходе в мир будет неиспользуемый игрок
2) Незя хранить что-то относящееся к разным игрокам в экземпляре одного класса(итема в данном случае)(нбт стака в помощь)
3) if (!world.isRemote <= Проверка сервер ли это, а потом вызовы с класса Minecraft?
4) На сервере без SideOnly всё крашнется
5) Да, говнокод....
а не легче обрабатывать камеру при ловле пакета о выстреле на клиенте?
 

deleted.user

Мошенник
321
43
Поля и методы с большой буквы я еще могу понять. Но int урон ... Ты рофлишь что-ли? Это нечитабельно даже с тазиком.
Это была временная мера)
а не легче обрабатывать камеру при ловле пакета о выстреле на клиенте?
Каким образом? Я думал об этом, но не придумал как.
 

deleted.user

Мошенник
321
43
Честно говоря - мало представляю себе, как это сделать. Либо голова уже не работает, либо я признаю, что я баран и не умею работать с пакетами. Был где то на форуме гайд от анти, то ли cmtv, черт их разберет, где описывалось все о пакетах еще на 1.7, но гайд проетерялся.

Попробовал это дело в пакет сунуть, эффекта ноль, собсно.
Java:
public class PacketShoot {

   public static final byte pID = 1;


   public byte getPacketID() {
      return (byte)1;
   }

   public static FMLProxyPacket send(boolean v) {
      C17PacketCustomPayload packet = null;
      ByteArrayOutputStream bytes = new ByteArrayOutputStream();
      DataOutputStream data = new DataOutputStream(bytes);

      try {
         data.write(1);
         data.writeBoolean(v);
         packet = new C17PacketCustomPayload("DayZPackets", bytes.toByteArray());
         data.close();
         bytes.close();
      } catch (Exception var5) {
         var5.printStackTrace();
      }

      return new FMLProxyPacket(packet);
   }

   public void receive(DataInputStream stream, Object[] extradata, Side side) {}

   public void receiveS(ByteBufInputStream bbis, Object[] extradata) {
      try {
         EntityPlayer e = (EntityPlayer)extradata[0];
         World world = (World)extradata[1];
         boolean hihi = bbis.readBoolean();
         ItemStack current = e.getHeldItem();
         if(current != null && current.getItem() != null && current.getItem() instanceof ItemWeapon) {
            ((ItemWeapon)current.getItem()).wantShoot(hihi);
         }
         //TODO: костыльная отдача, пофиксить.
         Random rand = new Random();
         int recoilRandInt = rand.nextInt(1);
         ItemWeapon.recoil += recoilRandInt;

         if (rand.nextInt(4) == 0) {
            e.rotationPitch -= ItemWeapon.recoil * 2.0F;
            e.cameraPitch = ItemWeapon.recoil;
            e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
            DayZLogger.log("RECOIL TEST", DayZLogger.DEBUG);
         } else {
            e.rotationPitch -= ItemWeapon.recoil * 2.0F;
            e.cameraPitch = ItemWeapon.recoil;
            e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
         }

         if (rand.nextBoolean()) {
            if (rand.nextInt(3) == 0) {
               e.rotationPitch -= ItemWeapon.recoil * 2.0F;
               e.cameraPitch = ItemWeapon.recoil;
               e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
            } else {
               e.rotationPitch -= ItemWeapon.recoil * 2.0F;
               e.cameraPitch = ItemWeapon.recoil;
               e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
            }
         } else if (rand.nextInt(3) == 0) {
            e.rotationPitch -= ItemWeapon.recoil * 2.0F;
            e.cameraPitch = ItemWeapon.recoil;
            e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
         } else {
            e.rotationPitch -= ItemWeapon.recoil * 2.0F;
            e.cameraPitch = ItemWeapon.recoil;
            e.prevCameraPitch += (float) (ItemWeapon.recoil / 2);
         }
      } catch (IOException var7) {
         var7.printStackTrace();
      }

   }
}

Upd: на сервере в лог то пишется, что отдача есть :^
На клиенте естесно ее нет.

Как выяснилось дальше - снова те же грабли, только в другом месте. Я не знаю как ето исправить, а лить пушки без отдачи - кал. :mc_e_120:

Ну, кто нибудь? Или каким образом ее двигать через эвент?
 
476
9
39
Переменные всегда с маленькой, геттеры, сеттеры тоже, как и часть ивентов аля onColliage...
Чтобы код проще было эдитить попробуй юзать открывающие скобки с новой строки
Java:
private static int getStarColor()
{
if(exists)
{
for(int i=0; i<stars.size();i++)
{
//to do something
}
}
//method body
}
Читать станет приятно. И методы называй, чтоб понятно было. А то я знаю привычку форджевцев все булы называть flag.
Когда кодстайл будет готов можешь себе сказать, что реально крут. И найдешь проблему логически подумав и почитав пару туториалов.
 
476
9
39
И юзай "идею" -> Intellij Idea.
Не ide, а имба(codestyle там тоже есть. т.е она пофиксит косяки очень топовая фича, для ленивых или для меньшего гемора потом.)
Если интересно могу пару труплагинов подкинуть)
 
Сверху