Капа выдает ошибку

Версия Minecraft
1.12.2
516
11
39
Всем привет.Сделал что-то типо крита через капу.Когда наношу урон выдает ошибку.
Java:
    @SubscribeEvent
    public void CritHurt(LivingHurtEvent e) {
        Entity from = e.getSource().getImmediateSource();
        EntityLivingBase to = e.getEntityLiving();
        if(from instanceof EntityPlayer) {
            IStatsHandler capa = (IStatsHandler)e.getEntity().getCapability(StatsProvider.STATS_CAP, null);
            if(Math.random()<=capa.getChanceCrit()) {//32 строчка
                float am = e.getAmount()*capa.getDamageCrit();
                e.setAmount(am);
                System.out.println(am);
                }
        }
            }
Java:
Caused by: java.lang.NullPointerException
    at ru.lnti.ElterionRPG.events.eventStats.CritHurt(eventStats.java:32) ~[eventStats.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_22_eventStats_CritHurt_LivingHurtEvent.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182) ~[EventBus.class:?]
    at net.minecraftforge.common.ForgeHooks.onLivingHurt(ForgeHooks.java:590) ~[ForgeHooks.class:?]
    at net.minecraft.entity.EntityLivingBase.damageEntity(EntityLivingBase.java:1565) ~[EntityLivingBase.class:?]
    at net.minecraft.entity.EntityLivingBase.attackEntityFrom(EntityLivingBase.java:1032) ~[EntityLivingBase.class:?]
    at net.minecraft.entity.monster.EntityMob.attackEntityFrom(EntityMob.java:80) ~[EntityMob.class:?]
    at net.minecraft.entity.monster.EntityZombie.attackEntityFrom(EntityZombie.java:259) ~[EntityZombie.class:?]
    at net.minecraft.entity.player.EntityPlayer.attackTargetEntityWithCurrentItem(EntityPlayer.java:1438) ~[EntityPlayer.class:?]
    at net.minecraft.entity.player.EntityPlayerMP.attackTargetEntityWithCurrentItem(EntityPlayerMP.java:1572) ~[EntityPlayerMP.class:?]
    at net.minecraft.network.NetHandlerPlayServer.processUseEntity(NetHandlerPlayServer.java:1140) ~[NetHandlerPlayServer.class:?]
    at net.minecraft.network.play.client.CPacketUseEntity.processPacket(CPacketUseEntity.java:94) ~[CPacketUseEntity.class:?]
    at net.minecraft.network.play.client.CPacketUseEntity.processPacket(CPacketUseEntity.java:15) ~[CPacketUseEntity.class:?]
    at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_201]
    at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_201]
    at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
    ... 5 more
 
7,099
324
1,510
Капа может быть null. Убедись, что в обработчике AttachCapabilitiesEvent провайдер капы добавляется.
Если она добавляется опционально, то при получении также воспринимай ее опционально: юзай Optional или if( !=null)
 
516
11
39
Убедись, что в обработчике AttachCapabilitiesEvent провайдер капы добавляется.
Вроде добавляется
Если она добавляется опционально, то при получении также воспринимай ее опционально
Нет,я использую начальное число
Типо проверить капу не нул?
 
7,099
324
1,510
516
11
39
Не должно быть вроде)
Все работает.
У меня в этой капе есть другая переменная которая отлично работает через эвент

Java:
    @SubscribeEvent
    public void EvasionHurt(LivingHurtEvent e) {
        if (e.getEntity() instanceof EntityPlayer) {
            IStatsHandler capa = (IStatsHandler)e.getEntity().getCapability(StatsProvider.STATS_CAP, null);
            if(Math.random()<=capa.getChanceEvasion()) {
            e.setCanceled(true);
            }
            
        }
    }
 
516
11
39
Покажи IStatsHandler
Java:
public interface IStatsHandler {

    float getChanceCrit();
    void setChanceCrti(float chanceCrit);
    void addChanceCrit(float chanceCrit);
    void removeChanceCrit(float chanceCrit);
    
    float getDamageCrit();
    void setDamageCrti(float damageCrit);
    void addDamageCrit(float damageCrit);
    void removeDamageCrit(float damageCrit);

    float getChanceEvasion();
    void setChanceEvasion(float chanceEvasion);
    void addChanceEvasion(float chanceEvasion);
    void removeChanceEvasion(float chanceEvasion);

    String[] getAllNames();
    float[] getAllStats();
    void setAllStats(float[] arr);

}
Java:
public class DefaultStatsHandler implements IStatsHandler{
    
    public float
            chanceCrit = 0.5F,
            damageCrit = 1.5F,
            chanceEvasion = 0.0F;

    @Override
    public float getChanceCrit() {
        return this.chanceCrit;
    }

    @Override
    public void setChanceCrti(float chanceCrit) {
        this.chanceCrit = chanceCrit;
    }

    @Override
    public void addChanceCrit(float chanceCrit) {
        this.chanceCrit += chanceCrit;
    }

    @Override
    public void removeChanceCrit(float chanceCrit) {
        this.chanceCrit -= chanceCrit;
    }

    @Override
    public float getDamageCrit() {
        return this.damageCrit;
    }

    @Override
    public void setDamageCrti(float damageCrit) {
        this.damageCrit = damageCrit;
        
    }

    @Override
    public void addDamageCrit(float damageCrit) {
        this.damageCrit += damageCrit;
    }

    @Override
    public void removeDamageCrit(float damageCrit) {
        this.damageCrit -= damageCrit;
    }

    @Override
    public float getChanceEvasion() {
        return this.chanceEvasion;
    }

    @Override
    public void setChanceEvasion(float chanceEvasion) {
        this.chanceEvasion = chanceEvasion;
    }

    @Override
    public void addChanceEvasion(float chanceEvasion) {
        this.chanceEvasion += chanceEvasion;
    }

    @Override
    public void removeChanceEvasion(float chanceEvasion) {
        this.chanceEvasion -= chanceEvasion;
    }
    
     @Override
     public float[] getAllStats() {
     return new float[] { chanceCrit, damageCrit, chanceEvasion };
        }

      @Override
      public void setAllStats(float[] arr) {
        this.chanceCrit = arr[0];
        this.damageCrit = arr[1];
        this.chanceEvasion = arr[2];
        }

        @Override
        public String[] getAllNames() {
        return new String[] { "chanceCrit", "damageCrit", "chanceEvasion" };
        }   
}
 
7,099
324
1,510
Хорошо. Покажи обработчик AttachCapabilitiesEvent.

Разница в том, что в первом случае игрок - это жертва, а во втором - источник урона. Игрок из источника почему-то не имеет капы :unsure: Можно попробовать обрабатывать событие AttackEntityEvent
 
7,099
324
1,510
Вроде все ок, хотя Resource Location лучше делать в lower case
AttackEntityEvent пашет?
 
7,099
324
1,510
без использовании капы работает
А с ней не работает?

Эти две штуки могут работать одновременно? Например, выполнить первое, потом второе, потом опять первое, потом опять второе? Подебажь, выясни, один и тот же ли экземпляр игрока в обоих обработчиках

IStatsHandler capa = (IStatsHandler)e.getEntity().getCapability(StatsProvider.STATS_CAP, null); if(Math.random()<=capa.getChanceCrit()) {//32 строчка
вставь if!capa!=null)

Кажется, я понял) Капа на клиенте и сервере отличается и на стороне клиента она почему-то отсутствует. Т.к. тестируешь в одиночке, то это не сразу заметно
 
516
11
39
Эти две штуки могут работать одновременно? Например, выполнить первое, потом второе, потом опять первое, потом опять второе? Подебажь, выясни, один и тот же ли экземпляр игрока в обоих обработчиках
Убрал первый метод,оставил только тот ,который не работает
Все равно не работает.
вставь if!capa!=null)
Полностью пропускает действие,так как capa равна null
Кажется, я понял) Капа на клиенте и сервере отличается и на стороне клиента она почему-то отсутствует. Т.к. тестируешь в одиночке, то это не сразу заметно
Что можно сделать с этим?
 
7,099
324
1,510
Убрал первый метод,оставил только тот ,который не работает
Все равно не работает.
Я имел ввиду попробовать заставить выполняться сначала тот, что пашет, потом тот, что не пашет, потом опять пашуший. Все за одну сессию игры.
Что можно сделать с этим?
На сервере это все равно выполняется, если нет, то вызываю пояснительную бригаду
1584120735079.png
 
7,099
324
1,510
Вот эта штука по идее должна на клиенте тоже вызываться, просто не быть синхронизированной. Тестируешь в одиночке или нет? Сколько игроков в тесте участвуют?
 
Сверху