- Баллы
- 98
- Имя в Minecraft
- BlackTrojan
Сабж в названии собственно.
Следуйте инструкциям в видео ниже, чтобы узнать, как установить наш сайт как веб-приложение на главный экран вашего устройства.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
Правда тогда не моб будет передвигаться, а игрок его тащить.Ну с посадкой на игрока вариант сразу не подходит.Ну можно, посадить его на игрокаПравда тогда не моб будет передвигаться, а игрок его тащить.
А можно каждый тик синхронизировать движения.
Ну с посадкой на игрока вариант сразу не подходит.
Вот только как?
Как я понял, добавлять к вектору моба значения таким образом направляя в сторону игрока или что то вроде того.А можно каждый тик синхронизировать движения.
Если каждый тик - то можно его просто телепортировать.Как я понял, добавлять к вектору моба значения таким образом направляя в сторону игрока или что то вроде того.
К сожалению с английским дело обстоят плохо.Может так?
К сожалению с английским дело обстоят плохо.
public class PathfinderGoalWalktoTile extends PathfinderGoal {
@Override
public boolean a() {
//Выполняем валидацию
}
@Override
public void c(){
//Выполняем перемещение
}
}
public class PathfinderGoalWalktoTile extends PathfinderGoal {
float speed;
private EntityCreature entitycreature;
public PathfinderGoalWalktoTile(EntityCreature entitycreature, float speed) {
this.speed = speed;
this.entitycreature = entitycreature;
}
@Override
public boolean a() {
if (this.entitycreature.aI() >= 100) {
return false;
} else if (<shoudwalk?>) {
return true;
} else {
return false;
}
}
@Override
public void c(){
this.entitycreature.getNavigation().a(x, y, z, speed);
}
}
public class BloodMoonEntityZombie extends net.minecraft.server.EntityZombie {
public BloodMoonEntityZombie(World world) {
super(world);
try {
Field gsa = net.minecraft.server.v1_5_R2.PathfinderGoalSelector.class.getDeclaredField("a");
gsa.setAccessible(true);
gsa.set(this.goalSelector, new UnsafeList());
gsa.set(this.targetSelector, new UnsafeList());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
this.goalSelector.a(0, new PathfinderGoalFloat(this));
this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
this.goalSelector.a(1, new PathfinderGoalWalktoTile(this, (float) this.bw));//this.bw можно заменить на свою скорость
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, this.bI, false));
this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityVillager.class, this.bI, true));
this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bI));
this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bI, false));
this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bI));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, true));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 16.0F, 0, false));
}
}
Ну что ж спасибо огромноеПо просьбе многих людей, вот пример кода, который позволяет контролировать перемещение LivingEntity к tile(По-моему tile это те энтити, которые обновляются каждый тик). Я настоятельно рекомендую вам сперва прочитать урок сделанный Jacek что бы знать как создать обычное существо. ПОСЛЕ прочтения того урока и его усвоения, конкретно - понимание того как происходит наследование существ, вы можете продолжить читать этот урок.
Во-первых нам нужно создать PathfinderGoal, которые будет указывать на конкретную tile. Мы не будем писть всю реализацию PathfinderGoal, а переопределим только те методы, которые отвечают за навигацию существа. Глядя на PathfinderGoalRandomStroll.java (это простейший "искатель путей", что я нашел) вы можете наблюдать метод a(), который используется для валидации пути и c() для реализации перемещения. После просмотра этого кода мы можем создать нашу собственную цель перемещения, переопределив PathfinderGoal. Я назвал свой переопредленный класс PathfinderGoalWalktoTile и перекрыл в нем два важнейших метода (a и c).
Java:public class PathfinderGoalWalktoTile extends PathfinderGoal { @Override public boolean a() { //Выполняем валидацию } @Override public void c(){ //Выполняем перемещение } }
Теперь я собираюсь скопировать большую часть кода из другого Pathfinder'а (искателя пути/цели) и настрить его в соответствии со своими потребностями, добавив конструктор и переименованием нескольких переменных.
Переменные x, y и z можно заменить на нужные вам цифры или брать текущие координаты из другого класса.Java:public class PathfinderGoalWalktoTile extends PathfinderGoal { float speed; private EntityCreature entitycreature; public PathfinderGoalWalktoTile(EntityCreature entitycreature, float speed) { this.speed = speed; this.entitycreature = entitycreature; } @Override public boolean a() { if (this.entitycreature.aI() >= 100) { return false; } else if (<shoudwalk?>) { return true; } else { return false; } } @Override public void c(){ this.entitycreature.getNavigation().a(x, y, z, speed); } }
Теперь у нас есть PathfinderGoal и мы можем добавить ему цель используя рефлексию. Вы должны будете получить первоначальные PathfinderGoal существа из NMS (net.minecraft.server) кода, которые вы можете найти здесь. Я использовал PathfinderGoal зомби, из урока Jacek.
Java:public class BloodMoonEntityZombie extends net.minecraft.server.EntityZombie { public BloodMoonEntityZombie(World world) { super(world); try { Field gsa = net.minecraft.server.v1_5_R2.PathfinderGoalSelector.class.getDeclaredField("a"); gsa.setAccessible(true); gsa.set(this.goalSelector, new UnsafeList()); gsa.set(this.targetSelector, new UnsafeList()); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalBreakDoor(this)); this.goalSelector.a(1, new PathfinderGoalWalktoTile(this, (float) this.bw));//this.bw можно заменить на свою скорость this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, this.bI, false)); this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityVillager.class, this.bI, true)); this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bI)); this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bI, false)); this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bI)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, true)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 16.0F, 0, false)); } }
Если вы хотите удалить такую черту зомби, как ломание дверей, то вы можете просто удалить эту строку из кода. Я надеюсь, что помог вам. Если вы обнаружите какие-либо ошибки в том коде, не стесняйтесь исправлять их. Я еще только осваиваю NMS.
Немного криво, но зато бесплатно.

Ну есть игрок и моб, игрок передвигается и моб должен пойти за ним же, как питомец.Нужно чтобы моб преследовал игрока или копировал его движения?
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (/* Необходимые вам проверки */) {
LivingEntity pet = /* Получаем питомца */;
// Я делал это так: (InventoryWrapper и InventoryManager - мои классы)
//InventoryWrapper inventoryWrapper = InventoryManager.get(player);
//LivingEntity pet = inventoryWrapper.getPet();
EntityUtils.goToPlayer(player, pet);
}
}
public static void goToPlayer(final Player player, final LivingEntity entity) {
// Всякие проверки
if (!player.isOnline() || entity.isDead()) {
return;
}
Location target = player.getLocation();
if (target.distance(entity.getLocation()) > 20) {
// Тут телепортируем Entity к игроку, т.к. пет слишком далеко, чтобы следовать за ним
entity.teleport(target);
// или entity.teleport(target, PlayerTeleportEvent.TeleportCause.PLUGIN);
return;
}
Class<?> entityInsentientClass = MinecraftReflection.getMinecraftClass("EntityInsentient");
Class<?> navigationAbstractClass = MinecraftReflection.getMinecraftClass("NavigationAbstract");
try {
Object insentient = entityInsentientClass.cast(MinecraftReflection.getCraftEntityClass().getDeclaredMethod("getHandle").invoke(entity));
Object navigation = entityInsentientClass.getDeclaredMethod("getNavigation").invoke(insentient);
navigationAbstractClass.getDeclaredMethod("a", double.class, double.class, double.class, double.class)
.invoke(navigation, target.getX(), target.getY(), target.getZ(), 1.75D);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}