本帖最后由 隔壁老吕 于 2020-2-14 11:21 编辑
生成后无法看见实体,但是AI工作正常。(没有给它隐形药水效果)
在spigot1.13.2中,它是可见的。
在1.12.1中,它是看不见的
用EntitySpawnEvent替换原版僵尸。
生成代码:
复制代码
实体代码:
复制代码
生成后无法看见实体,但是AI工作正常。(没有给它隐形药水效果)
在spigot1.13.2中,它是可见的。
在1.12.1中,它是看不见的
用EntitySpawnEvent替换原版僵尸。
生成代码:
- public DoomsdayZombie spawnDoomsdayZombie(Location loc) {
- DoomsdayZombie dz = new DoomsdayZombie(loc);
- CraftWorld craftWorld = (CraftWorld) loc.getWorld();
- craftWorld.addEntity(dz, CreatureSpawnEvent.SpawnReason.CUSTOM);
- return dz;
- }
实体代码:
- public class DoomsdayZombie extends EntityZombie {
- public ZombieTaskHandleStack taskHandle;
- public static Double movementSpeed;
- public ZombieAction action = ZombieAction.Avaiable;
- public DoomsdaySurvival plugin;
- public int stopCount = 0;
- public double last_X, last_Z;
- static {
- movementSpeed = Config.DOOMSDAY_ZOMBIE_SPEED;
- }
- public DoomsdayZombie(Location loc) {
- super(((CraftWorld) loc.getWorld()).getHandle());
- this.plugin = DoomsdaySurvival.plugin;
- setPosition(loc.getX(), loc.getY(), loc.getZ());
- taskHandle = new ZombieTaskHandleStack(plugin, this);
- }
- @Override
- protected void initAttributes() {
- super.initAttributes();
- getAttributeInstance(GenericAttributes.maxHealth).setValue(Config.DOOMSDAY_ZOMBIE_HEALTH);
- getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(movementSpeed);
- getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(Config.DOOMSDAY_ZOMBIE_FOLLOWRANGE);
- getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(Config.DOOMSDAY_ZOMBIE_DAMAGE);
- }
- public boolean isSameWorldWithTarget() {
- return getBukkitEntity().getWorld().getName().equals(getTarget().getWorld().getName());
- }
- public Location getLocation() {
- return ((org.bukkit.entity.Zombie) getBukkitEntity()).getLocation().clone();
- }
- public ZombieAction getAction() {
- return action;
- }
- public boolean isSameHeightWithTarget() {
- return hasTarget() && Math.abs(getTarget().getLocation().getY() - locY) <= 0.5;
- }
- public void ifStop() {
- if (stopCount == 0) {
- last_X = locX;
- last_Z = locZ;
- }
- stopCount++;
- if (stopCount == 60) {
- stopCount = 0;
- if (getXZDistance(last_X, last_Z, locX, locZ) < 0.5 && action == ZombieAction.Avaiable) {
- stop();
- } else {
- avaiable();
- }
- }
- }
- public void stop() {
- action = ZombieAction.Stop;
- goalSelector = new PathfinderGoalSelector((world != null) && (world.methodProfiler != null) ? world.methodProfiler : null);
- goalSelector.a(0, new PathfinderGoalFloat(this));
- targetSelector = new PathfinderGoalSelector((world != null) && (world.methodProfiler != null) ? world.methodProfiler : null);
- }
- public void avaiable() {
- action = ZombieAction.Avaiable;
- goalSelector = new PathfinderGoalSelector((world != null) && (world.methodProfiler != null) ? world.methodProfiler : null);
- goalSelector.a(0, new PathfinderGoalFloat(this));
- goalSelector.a(1, new PathfinderGoalZombieAttack(this, 1.0D, false));
- goalSelector.a(1, new DoomsdayZombieBreakPathfinderGoal(this));
- goalSelector.a(1, new DoomsdayZombiePlacePathfinderGoal(this));
- targetSelector = new PathfinderGoalSelector((world != null) && (world.methodProfiler != null) ? world.methodProfiler : null);
- targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true));
- if (world.spigotConfig.zombieAggressiveTowardsVillager) {
- targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false));
- }
- }
- @Override
- public void B_() {
- if (hasTarget()) {
- ifStop();
- if (!isBlockPassable(taskHandle.getHeadBlock().getRelative(BlockFace.DOWN))) {
- taskHandle.push(new BlockTask(taskHandle.getHeadBlock().getRelative(BlockFace.DOWN)));
- }
- if (!isBlockPassable(taskHandle.getHeadBlock())) {
- taskHandle.push(new BlockTask(taskHandle.getHeadBlock()));
- }
- if (getTarget().getLocation().getY() - locY > 0.5 && (action == ZombieAction.Stop || getXZDistance(getTarget().getLocation(), this.getBukkitEntity().getLocation()) < 7)) {
- stop();
- Location loc = getLocation();
- setPosition(loc.getBlockX() + 0.5, locY, loc.getBlockZ() + 0.5);
- if (!isBlockPassable(taskHandle.getBlockOnHead())) {
- taskHandle.push(new BlockTask(taskHandle.getBlockOnHead()));
- } else {
- BlockTask task = new BlockTask(loc, 1);
- task.isUp = true;
- taskHandle.push(task);
- }
- } else {
- if (locY - getTarget().getLocation().getY() > 1 && getXZDistance(bukkitEntity.getLocation(), getTarget().getLocation()) < 5 && isInWater()) {
- Location loc = getLocation().subtract(0, 1, 0);
- taskHandle.push(new BlockTask(loc.getBlock()));
- motY = -movementSpeed;
- avaiable();
- } else if (locY - getTarget().getLocation().getY() > 1 && getXZDistance(bukkitEntity.getLocation(), getTarget().getLocation()) < 0.3) {
- Location loc = getLocation().subtract(0, 1, 0);
- taskHandle.push(new BlockTask(loc.getBlock()));
- avaiable();
- } else if (isSameHeightWithTarget() || getTarget().getLocation().getY() - locY > 1 && action == ZombieAction.Stop) {
- avaiable();
- }
- }
- } else {
- avaiable();
- foundTarget();
- }
- taskHandle.doTick();
- super.B_();
- }
- public static Block getNMSBlock(CraftBlock b) {
- return (Block) NBT.doMethod(b, "getNMSBlock");
- }
- public static IBlockData getBlockNMS(CraftBlock b) {
- return (IBlockData) NBT.doMethod(b, "getData0");
- }
- public static boolean isBlockPassable(org.bukkit.block.Block b) {
- return b.isEmpty();
- }
- public void foundTarget() {
- if (!hasTarget()) {
- for (org.bukkit.entity.Entity en : bukkitEntity.getNearbyEntities(Config.DOOMSDAY_ZOMBIE_FOLLOWRANGE, Config.DOOMSDAY_ZOMBIE_FOLLOWRANGE, Config.DOOMSDAY_ZOMBIE_FOLLOWRANGE)) {
- if (en instanceof org.bukkit.entity.LivingEntity) {
- if (en instanceof org.bukkit.entity.Player) {
- if (((org.bukkit.entity.Player) en).getGameMode() != GameMode.CREATIVE) {
- setTarget((LivingEntity) en);
- return;
- }
- }
- if (en instanceof org.bukkit.entity.Villager || en instanceof org.bukkit.entity.IronGolem) {
- setTarget((LivingEntity) en);
- return;
- }
- }
- }
- }
- }
- public static double getXZDistance(double x1, double z1, double x2, double z2) {
- return Math.sqrt((x1 - x2) * (x1 - x2)
- + (z1 - z2) * (z1 - z2));
- }
- public static double getXZDistance(Location loc1, Location loc2) {
- return Math.sqrt((loc1.getX() - loc2.getX()) * (loc1.getX() - loc2.getX())
- + (loc1.getZ() - loc2.getZ()) * (loc1.getZ() - loc2.getZ()));
- }
- public org.bukkit.entity.LivingEntity getTarget() {
- return ((org.bukkit.entity.Zombie) getBukkitEntity()).getTarget();
- }
- public boolean hasTarget() {
- if (((org.bukkit.entity.Zombie) getBukkitEntity()).getTarget() != null) {
- if (!((org.bukkit.entity.Zombie) getBukkitEntity()).getTarget().isDead() && isSameWorldWithTarget()) {
- return true;
- }
- }
- return false;
- }
- public void setTarget(org.bukkit.entity.LivingEntity le) {
- ((org.bukkit.entity.Zombie) getBukkitEntity()).setTarget(le);
- }
- @Override
- public void n() {
- goalSelector.a(0, new PathfinderGoalFloat(this));
- goalSelector.a(1, new PathfinderGoalZombieAttack(this, 1.0D, false));
- targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true));
- if (world.spigotConfig.zombieAggressiveTowardsVillager) {
- targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false));
- }
- goalSelector.a(1, new DoomsdayZombieBreakPathfinderGoal(this));
- goalSelector.a(1, new DoomsdayZombiePlacePathfinderGoal(this));
- }
- public enum ZombieAction {
- Avaiable,
- Stop;
- }
- }
https://www.mcbbs.net/thread-811096-1-1.html
请观看 自定义生物的教程
如果对有生命的实体进行开发
需要注册实体 否则就会看不见
1.11为分界线 注册方法不同
[img]%5Burl=https://sm.ms/image/642kJDQAVemgYwN%5D
[/url][/img]
以上代码均来自教程
详情可前往观看
请观看 自定义生物的教程
如果对有生命的实体进行开发
需要注册实体 否则就会看不见
1.11为分界线 注册方法不同
[img]%5Burl=https://sm.ms/image/642kJDQAVemgYwN%5D
[/url][/img]以上代码均来自教程
详情可前往观看
凉拌凑字凑字还好还好
正好是我需要的,太感谢了