TimeHundler - дни, месяцы, года.

Версия Minecraft
1.12.2
5,149
49
899
Как вы знаете в ванили есть тотальное время жизни мира, время жизни мира при заходе в него, а также смена дня и ночи. Было бы неплохо до конца систематизировать это и сделать не только день\ночь, но и полноценный календарь. С помощью @Dahaka мне удалось слепить что то такое, и этот код работает на версии 1.7.10. То есть счетчик крутится, нбтшки сохраняются.
На версии 1.12.2 это не работает - я проверил, просто не вызываются методы ни write, ни соотвественно, read. В чем может быть проблема, кто подскажет?

Java:
public class TimeHundler {
    private static class TimeTicker extends WorldSavedData {
        private static String name = Realism.MODID + "wsdName";

        public TimeTicker(String name) {
            super(name);
        }

        public TimeTicker() {
            super(name);
        }

        public int year  = 0;
        public int month = 0;
        public int day   = 0;

        @Override
        public void readFromNBT(NBTTagCompound nbt) {
            day = nbt.getInteger("day");
            month = nbt.getInteger("month");
            year = nbt.getInteger("year");
            System.out.println("readFromNBT");
        }

        @Override
        public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
            nbt.setInteger("day", day);
            nbt.setInteger("month", month);
            nbt.setInteger("year", year);
            System.out.println("writeToNBT");
            return nbt;
        }

        private static boolean IS_GLOBAL = true;

        private static TimeTicker get(World world) {

            MapStorage storage = IS_GLOBAL ? world.getMapStorage() : world.getPerWorldStorage();
            TimeTicker instance = (TimeTicker) storage.getOrLoadData(TimeTicker.class, name);
            if (instance == null) {
                instance = new TimeTicker(name);
                storage.setData(name, instance);
                instance.markDirty();
            }
            return instance;
        }
    }
    
    private static TimeTicker tt;

    @SubscribeEvent
    public void converterTime(TickEvent.WorldTickEvent event) {
      
        if (event.phase != event.phase.END) {
            return;
        }
        
        if (tt == null) {
            tt = TimeTicker.get(event.world);
        }

        tt.day++;
        tt.markDirty();
        
        System.out.println(tt.day);
    }
    @SubscribeEvent
    public void loadWorld(WorldEvent.Load event) {
        tt = TimeTicker.get(event.getWorld());
    }
}
 
Решение
Этот кусок у меня работает.
Java:
@Mod(modid = MyMod.MODID, version = MyMod.VERSION)
public class MyMod {
    public static final String MODID = "mymod";
    public static final String VERSION = "1.0";
 
    @EventHandler
    public void init(FMLInitializationEvent e) {
        MinecraftForge.EVENT_BUS.register(this);
    }
 
    @SubscribeEvent
    public void onWorldTick(TickEvent.WorldTickEvent e) {
        if (e.phase != e.phase.END) {
            return;
        }
     
        MyWsd wsd = MyWsd.get(e.world);
        wsd.myValue++;
        wsd.markDirty();
    }
 
    public static class MyWsd extends WorldSavedData {
        private static final String name = "mywsd";
     
        public int myValue = 0;
     
        public...
Раз я такую штуку написал, значит наверное, надо именно так, а не иначе. Твой вариант не удобен в плане дальнейшего использования
 
Хочу сделать специальную удобную настройку разных дат через конфиг. Также хочу дать возможность администраторам сбрасывать счетчики. Также, счетчик должен обнулятся когда пройдет 30 дней, когда пройдет 365 дней и т д
 
Так где ж он неудобен-то?
Нбт так и так придется использовать - новоиспеченные переменные не сохраняются, так как приходится обнулять мировое время. Без обнуления мирового времени чет не получается сделать((
Java:
      @SubscribeEvent
        public void converterTime(TickEvent.WorldTickEvent event) {
             
          secund = (event.world.getTotalWorldTime() / 20);
        //  minute = secund/60;
    //      hour = minute/60;
        //  day = hour/24;
        //  month = day/30;
        //  year = month/12;
         
       
          if(secund == 20) {
              minute++;
              event.world.setTotalWorldTime(0);
              System.out.println(minute);
              System.out.println(secund);
          }
          if(minute == 2) {
              hour++;
              minute = 0;
              System.out.println(hour);
          }
         
          /*
           year - 1,2,3 - winter
                     3,4,5 - spring
                  7,8,9 - summer
                  10,11,12 - autumn
           */
            if (event.phase != event.phase.END) {
                return;
            }
           
         
        }
 
Последнее редактирование:
Вопрос актуален - почему не работают NBT?
 
Handler, second.
Да и вообще, странная у тебя система. Ведь даже время на ПК сделано через 1 переменную целого числа(64-битную, вроде). А всё остальное считается от неё. Я про UNIX-время.
 
Handler, second.
Да и вообще, странная у тебя система. Ведь даже время на ПК сделано через 1 переменную целого числа(64-битную, вроде). А всё остальное считается от неё. Я про UNIX-время.
:mad:
Я не спрашивал твоего мнения про мою систему. Вопрос - почему не работают нбт в 1.12(в 1.7.10 - таким же образом - работают)
 
:mad:
Я не спрашивал твоего мнения про мою систему. Вопрос - почему не работают нбт в 1.12(в 1.7.10 - таким же образом - работают)
А я и не сказал своего мнения. Твоя система - высшей степени дерьмо, написание которой будет настолько мучительным, насколько не может быть мучительным тромбоз конечности от употребления коаксила.
 
Если не знаешь ответа - не засоряй тему, пож.
 
Вопрос актуален, неужели нету никого, разбирающегося в WSD и нбт?
 
Этот кусок у меня работает.
Java:
@Mod(modid = MyMod.MODID, version = MyMod.VERSION)
public class MyMod {
    public static final String MODID = "mymod";
    public static final String VERSION = "1.0";
 
    @EventHandler
    public void init(FMLInitializationEvent e) {
        MinecraftForge.EVENT_BUS.register(this);
    }
 
    @SubscribeEvent
    public void onWorldTick(TickEvent.WorldTickEvent e) {
        if (e.phase != e.phase.END) {
            return;
        }
     
        MyWsd wsd = MyWsd.get(e.world);
        wsd.myValue++;
        wsd.markDirty();
    }
 
    public static class MyWsd extends WorldSavedData {
        private static final String name = "mywsd";
     
        public int myValue = 0;
     
        public MyWsd(String name) {
            super(name);
        }

        @Override
        public void readFromNBT(NBTTagCompound nbt) {
            myValue = nbt.getInteger("myValue");
        }

        @Override
        public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
            nbt.setInteger("myValue", myValue);
            return nbt;
        }

        public static MyWsd get(World world) {
            MapStorage storage = world.getMapStorage();
            MyWsd instance = (MyWsd) storage.getOrLoadData(MyWsd.class, name);
            if (instance == null) {
                instance = new MyWsd(name);
                storage.setData(name, instance);
                instance.markDirty();
            }
            return instance;
        }
    }
}
 
Этот кусок у меня работает.
Java:
@Mod(modid = MyMod.MODID, version = MyMod.VERSION)
public class MyMod {
    public static final String MODID = "mymod";
    public static final String VERSION = "1.0";

    @EventHandler
    public void init(FMLInitializationEvent e) {
        MinecraftForge.EVENT_BUS.register(this);
    }

    @SubscribeEvent
    public void onWorldTick(TickEvent.WorldTickEvent e) {
        if (e.phase != e.phase.END) {
            return;
        }
  
        MyWsd wsd = MyWsd.get(e.world);
        wsd.myValue++;
        wsd.markDirty();
    }

    public static class MyWsd extends WorldSavedData {
        private static final String name = "mywsd";
  
        public int myValue = 0;
  
        public MyWsd(String name) {
            super(name);
        }

        @Override
        public void readFromNBT(NBTTagCompound nbt) {
            myValue = nbt.getInteger("myValue");
        }

        @Override
        public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
            nbt.setInteger("myValue", myValue);
            return nbt;
        }

        public static MyWsd get(World world) {
            MapStorage storage = world.getMapStorage();
            MyWsd instance = (MyWsd) storage.getOrLoadData(MyWsd.class, name);
            if (instance == null) {
                instance = new MyWsd(name);
                storage.setData(name, instance);
                instance.markDirty();
            }
            return instance;
        }
    }
}
Кажется у меня появилась идея...
На 1.7 работает? Или на 1.12?
 
Я не знаю, как ты смотрел. У меня твой код выбрасывал ексепшн из-за того, что класс приватный, и ему рефлексией не дотянуться до конструктора.
так ты сам посоветовал приватным сделать :D
 
Назад
Сверху