Компиляция части мода непосредственно перед стартом

Версия Minecraft
1.12.2
API
Forge
437
41
111
Столкнулся с такой нестандартной проблемой.
В общем, у меня есть шаблон класса моба, который я хочу скомпилировать на лету, во время запуска мода.

Когда я, компилирую это ,,по обычному,, (подставив в %MOB_CLASS% нормальное имя, и переместив из папки с ресурсами в папку с кодом) - оно все работает, ровно так как мне и нужно (монстрик прыгает, бегает, имеет модель, ИИ, и т.д)
Когда я решил скомпилировать и загрузить на ходу - оно нормально проходит процесс компиляции, и загрузки, однако, при попытке зарегистрировать такого моба, мне выскакивает, что конструктора public %MOB_CLASS%(World worldIn) не существует вовсе, а при попытке создать ему ,,мировой спавнер,, мне выбрасывает, что этот класс не является наследником EntityLiving, хотя AbcMob - его прямой наследник

(Отвечу на возможные вопросы - статичные поля я заполняю с помощью рефлексии, а 3д модель и анимации поставляет GeckoLib, я практически в 1-м шаге от создания кастомных мобов, без использования Java-кода, вытащив все необходимое в 1 жирный Tson (почти как Json)-конфиг-файл)
Java:
package exmob;

import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import plus.mobs.frame.AbcMob;
import plus.mobs.utl.AnimationFolder;


public class %MOB_CLASS% extends AbcMob{
    public static final DataParameter<Byte> STATE =
            EntityDataManager.createKey(%MOB_CLASS%.class, DataSerializers.BYTE);

    public static IEntityApplicator MODEL = AI_DEFAULT_MODEL;
    public static IEntityApplicator ATTRIBUTES;
    public static MobHitbox HITBOX;
    @SideOnly(Side.CLIENT)
    public static AnimationFolder ANIM_FOLDER;

    public %MOB_CLASS%(World worldIn) {
        super(worldIn);
        this.setSize(HITBOX.width, HITBOX.height);
    }


    @Override
    protected void entityInit() {
        super.entityInit();
        this.getDataManager().register(STATE, (byte)-1);
    }


    @Override
    public float getEyeHeight() {
        return HITBOX.eyeHeight;
    }


    @Override
    protected void initEntityAI() {
        MODEL.apply(this);
    }


    @Override
    public void setState(byte state) {
        this.getDataManager().set(STATE, state);
    }


    @Override
    protected void applyEntityAttributes() {
        super.applyEntityAttributes();
        ATTRIBUTES.apply(this);
    }


    @SideOnly(Side.CLIENT)
    public byte getState() {
        return this.dataManager.get(STATE);
    }


    @Override
    @SideOnly(Side.CLIENT)
    public AnimationFolder getAnimFolder() {
        return ANIM_FOLDER;
    }
}
Java:
public class MobCompiler {
    public static Class<?> load(Path path, String name){
        try {
            URLClassLoader urlClassLoader = URLClassLoader.newInstance(
                    new URL[]{path.toUri().toURL()}
            );
            return urlClassLoader.loadClass(name);
        } catch (Exception e){
            throw new RuntimeException(e);
        }
    }


    public static Path compile(String className, String code){
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler
                .getStandardFileManager(null, null, null);
        File file = new File("temp");
        if(!file.exists()){
            file.mkdirs();
        }
        Path output = file.toPath();
 
        JavaCompiler.CompilationTask task = compiler.getTask(
                null,fileManager,null,
                Arrays.asList("-d", output.toAbsolutePath().toString()),
                null,
                singletonList(
                        new SimpleJavaFileObject(
                                URI.create("string:///" + className.replace('.', '/') +
                                        JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE) {

                            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
                                return code;
                            }
                        })
        );

        boolean result = task.call();
        if (!result) throw new RuntimeException("Compilation error!");
        return output;
    }
}
 
Последнее редактирование:
Сверху