- 437
- 41
- 111
Столкнулся с такой нестандартной проблемой.
В общем, у меня есть шаблон класса моба, который я хочу скомпилировать на лету, во время запуска мода.
Когда я, компилирую это ,,по обычному,, (подставив в %MOB_CLASS% нормальное имя, и переместив из папки с ресурсами в папку с кодом) - оно все работает, ровно так как мне и нужно (монстрик прыгает, бегает, имеет модель, ИИ, и т.д)
Когда я решил скомпилировать и загрузить на ходу - оно нормально проходит процесс компиляции, и загрузки, однако, при попытке зарегистрировать такого моба, мне выскакивает, что конструктора
(Отвечу на возможные вопросы - статичные поля я заполняю с помощью рефлексии, а 3д модель и анимации поставляет GeckoLib, я практически в 1-м шаге от создания кастомных мобов, без использования Java-кода, вытащив все необходимое в 1 жирный Tson (почти как Json)-конфиг-файл)
В общем, у меня есть шаблон класса моба, который я хочу скомпилировать на лету, во время запуска мода.
Когда я, компилирую это ,,по обычному,, (подставив в %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;
}
}
Последнее редактирование: