diff --git a/pom.xml b/pom.xml index 7ebde91..5d05f34 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 4.0.0 eu.phiwa DragonTravel - 01.007.06 + 01.007.07 @@ -135,11 +135,12 @@ + + + + org.spigotmc + spigot-v1_16_R1 + v1_16_R1 + org.spigotmc diff --git a/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/CustomEntityRegistry.java b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/CustomEntityRegistry.java new file mode 100644 index 0000000..543abed --- /dev/null +++ b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/CustomEntityRegistry.java @@ -0,0 +1,219 @@ +/* +SOURCE : +https://github.com/CitizensDev/Citizens2/blob/master/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/CustomEntityRegistry.java + +Yes, I admit, I'm a super lazy person ! +*/ + +package eu.phiwa.dragontravel.nms.v1_16_R1; + +import java.util.Iterator; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Maps; + +import net.minecraft.server.v1_16_R1.*; + +@SuppressWarnings("rawtypes") +public class CustomEntityRegistry extends RegistryBlocks { + private final BiMap entities = HashBiMap.create(); + private final BiMap entityClasses = this.entities.inverse(); + private final Map entityIds = Maps.newHashMap(); + private final RegistryMaterials> wrapped; + + public CustomEntityRegistry(RegistryBlocks> original) { + //super(original.a().getNamespace()); + super(original.a().getNamespace(), null, null); + this.wrapped = original; + } + + @Override + public int a(Object key) { + if (entityIds.containsKey(key)) { + return entityIds.get(key); + } + + return wrapped.a((EntityTypes) key); + } + + @Override + public Object a(Random paramRandom) { + return wrapped.a(paramRandom); + } + + public EntityTypes findType(Class search) { + return minecraftClassMap.inverse().get(search); + /* + for (Object type : wrapped) { + if (minecraftClassMap.get(type) == search) { + return (EntityTypes) type; + } + } + return null; + */ + } + + @Override + public Object fromId(int var0) { + return this.wrapped.fromId(var0); + } + + @Override + public EntityTypes get(MinecraftKey key) { + if (entities.containsKey(key)) { + return entities.get(key); + } + + return wrapped.get(key); + } + + @Override + public MinecraftKey getKey(Object value) { + if (entityClasses.containsKey(value)) { + return entityClasses.get(value); + } + + return wrapped.getKey((EntityTypes) value); + } + + @Override + public Optional getOptional(MinecraftKey var0) { + if (entities.containsKey(var0)) { + return Optional.of(entities.get(var0)); + } + + return this.wrapped.getOptional(var0); + } + + public RegistryMaterials> getWrapped() { + return wrapped; + } + + @Override + public Iterator iterator() { + return (Iterator) wrapped.iterator(); + } + + @Override + public Set keySet() { + return (Set) wrapped.keySet(); + } + + public void put(int entityId, MinecraftKey key, EntityTypes entityClass) { + entities.put(key, entityClass); + entityIds.put(entityClass, entityId); + } + + // replace regex + // ([A-Z_]+).*?a\(E(.*?)::new.*?$ + // minecraftClassMap.put(EntityTypes.\1, E\2.class); + private static final BiMap> minecraftClassMap = HashBiMap.create(); + static { + minecraftClassMap.put(EntityTypes.AREA_EFFECT_CLOUD, EntityAreaEffectCloud.class); + minecraftClassMap.put(EntityTypes.ARMOR_STAND, EntityArmorStand.class); + minecraftClassMap.put(EntityTypes.ARROW, EntityTippedArrow.class); + minecraftClassMap.put(EntityTypes.BAT, EntityBat.class); + minecraftClassMap.put(EntityTypes.BEE, EntityBee.class); + minecraftClassMap.put(EntityTypes.BLAZE, EntityBlaze.class); + minecraftClassMap.put(EntityTypes.BOAT, EntityBoat.class); + minecraftClassMap.put(EntityTypes.CAT, EntityCat.class); + minecraftClassMap.put(EntityTypes.CAVE_SPIDER, EntityCaveSpider.class); + minecraftClassMap.put(EntityTypes.CHICKEN, EntityChicken.class); + minecraftClassMap.put(EntityTypes.COD, EntityCod.class); + minecraftClassMap.put(EntityTypes.COW, EntityCow.class); + minecraftClassMap.put(EntityTypes.CREEPER, EntityCreeper.class); + minecraftClassMap.put(EntityTypes.DONKEY, EntityHorseDonkey.class); + minecraftClassMap.put(EntityTypes.DOLPHIN, EntityDolphin.class); + minecraftClassMap.put(EntityTypes.DRAGON_FIREBALL, EntityDragonFireball.class); + minecraftClassMap.put(EntityTypes.DROWNED, EntityDrowned.class); + minecraftClassMap.put(EntityTypes.ELDER_GUARDIAN, EntityGuardianElder.class); + minecraftClassMap.put(EntityTypes.END_CRYSTAL, EntityEnderCrystal.class); + minecraftClassMap.put(EntityTypes.ENDER_DRAGON, EntityEnderDragon.class); + minecraftClassMap.put(EntityTypes.ENDERMAN, EntityEnderman.class); + minecraftClassMap.put(EntityTypes.ENDERMITE, EntityEndermite.class); + minecraftClassMap.put(EntityTypes.EVOKER_FANGS, EntityEvokerFangs.class); + minecraftClassMap.put(EntityTypes.EVOKER, EntityEvoker.class); + minecraftClassMap.put(EntityTypes.EXPERIENCE_ORB, EntityExperienceOrb.class); + minecraftClassMap.put(EntityTypes.EYE_OF_ENDER, EntityEnderSignal.class); + minecraftClassMap.put(EntityTypes.FALLING_BLOCK, EntityFallingBlock.class); + minecraftClassMap.put(EntityTypes.FIREWORK_ROCKET, EntityFireworks.class); + minecraftClassMap.put(EntityTypes.FOX, EntityFox.class); + minecraftClassMap.put(EntityTypes.GHAST, EntityGhast.class); + minecraftClassMap.put(EntityTypes.GIANT, EntityGiantZombie.class); + minecraftClassMap.put(EntityTypes.GUARDIAN, EntityGuardian.class); + minecraftClassMap.put(EntityTypes.HORSE, EntityHorse.class); + minecraftClassMap.put(EntityTypes.HUSK, EntityZombieHusk.class); + minecraftClassMap.put(EntityTypes.ILLUSIONER, EntityIllagerIllusioner.class); + minecraftClassMap.put(EntityTypes.ITEM, EntityItem.class); + minecraftClassMap.put(EntityTypes.ITEM_FRAME, EntityItemFrame.class); + minecraftClassMap.put(EntityTypes.FIREBALL, EntityLargeFireball.class); + minecraftClassMap.put(EntityTypes.LEASH_KNOT, EntityLeash.class); + minecraftClassMap.put(EntityTypes.LLAMA, EntityLlama.class); + minecraftClassMap.put(EntityTypes.LLAMA_SPIT, EntityLlamaSpit.class); + minecraftClassMap.put(EntityTypes.MAGMA_CUBE, EntityMagmaCube.class); + minecraftClassMap.put(EntityTypes.MINECART, EntityMinecartRideable.class); + minecraftClassMap.put(EntityTypes.CHEST_MINECART, EntityMinecartChest.class); + minecraftClassMap.put(EntityTypes.COMMAND_BLOCK_MINECART, EntityMinecartCommandBlock.class); + minecraftClassMap.put(EntityTypes.FURNACE_MINECART, EntityMinecartFurnace.class); + minecraftClassMap.put(EntityTypes.HOPPER_MINECART, EntityMinecartHopper.class); + minecraftClassMap.put(EntityTypes.SPAWNER_MINECART, EntityMinecartMobSpawner.class); + minecraftClassMap.put(EntityTypes.TNT_MINECART, EntityMinecartTNT.class); + minecraftClassMap.put(EntityTypes.MULE, EntityHorseMule.class); + minecraftClassMap.put(EntityTypes.MOOSHROOM, EntityMushroomCow.class); + minecraftClassMap.put(EntityTypes.OCELOT, EntityOcelot.class); + minecraftClassMap.put(EntityTypes.PAINTING, EntityPainting.class); + minecraftClassMap.put(EntityTypes.PANDA, EntityPanda.class); + minecraftClassMap.put(EntityTypes.PARROT, EntityParrot.class); + minecraftClassMap.put(EntityTypes.PIG, EntityPig.class); + minecraftClassMap.put(EntityTypes.PUFFERFISH, EntityPufferFish.class); + //minecraftClassMap.put(EntityTypes.ZOMBIE_PIGMAN, EntityPigZombie.class); + minecraftClassMap.put(EntityTypes.POLAR_BEAR, EntityPolarBear.class); + minecraftClassMap.put(EntityTypes.TNT, EntityTNTPrimed.class); + minecraftClassMap.put(EntityTypes.RABBIT, EntityRabbit.class); + minecraftClassMap.put(EntityTypes.SALMON, EntitySalmon.class); + minecraftClassMap.put(EntityTypes.SHEEP, EntitySheep.class); + minecraftClassMap.put(EntityTypes.SHULKER, EntityShulker.class); + minecraftClassMap.put(EntityTypes.SHULKER_BULLET, EntityShulkerBullet.class); + minecraftClassMap.put(EntityTypes.SILVERFISH, EntitySilverfish.class); + minecraftClassMap.put(EntityTypes.SKELETON, EntitySkeleton.class); + minecraftClassMap.put(EntityTypes.SKELETON_HORSE, EntityHorseSkeleton.class); + minecraftClassMap.put(EntityTypes.SLIME, EntitySlime.class); + minecraftClassMap.put(EntityTypes.SMALL_FIREBALL, EntitySmallFireball.class); + minecraftClassMap.put(EntityTypes.SNOW_GOLEM, EntitySnowman.class); + minecraftClassMap.put(EntityTypes.SNOWBALL, EntitySnowball.class); + minecraftClassMap.put(EntityTypes.SPECTRAL_ARROW, EntitySpectralArrow.class); + minecraftClassMap.put(EntityTypes.SPIDER, EntitySpider.class); + minecraftClassMap.put(EntityTypes.SQUID, EntitySquid.class); + minecraftClassMap.put(EntityTypes.STRAY, EntitySkeletonStray.class); + minecraftClassMap.put(EntityTypes.TRADER_LLAMA, EntityLlamaTrader.class); + minecraftClassMap.put(EntityTypes.TROPICAL_FISH, EntityTropicalFish.class); + minecraftClassMap.put(EntityTypes.TURTLE, EntityTurtle.class); + minecraftClassMap.put(EntityTypes.EGG, EntityEgg.class); + minecraftClassMap.put(EntityTypes.ENDER_PEARL, EntityEnderPearl.class); + minecraftClassMap.put(EntityTypes.EXPERIENCE_BOTTLE, EntityThrownExpBottle.class); + minecraftClassMap.put(EntityTypes.POTION, EntityPotion.class); + minecraftClassMap.put(EntityTypes.TRIDENT, EntityThrownTrident.class); + minecraftClassMap.put(EntityTypes.VEX, EntityVex.class); + minecraftClassMap.put(EntityTypes.VILLAGER, EntityVillager.class); + minecraftClassMap.put(EntityTypes.IRON_GOLEM, EntityIronGolem.class); + minecraftClassMap.put(EntityTypes.VINDICATOR, EntityVindicator.class); + minecraftClassMap.put(EntityTypes.PILLAGER, EntityPillager.class); + minecraftClassMap.put(EntityTypes.WANDERING_TRADER, EntityVillagerTrader.class); + minecraftClassMap.put(EntityTypes.WITCH, EntityWitch.class); + minecraftClassMap.put(EntityTypes.WITHER, EntityWither.class); + minecraftClassMap.put(EntityTypes.WITHER_SKELETON, EntitySkeletonWither.class); + minecraftClassMap.put(EntityTypes.WITHER_SKULL, EntityWitherSkull.class); + minecraftClassMap.put(EntityTypes.WOLF, EntityWolf.class); + minecraftClassMap.put(EntityTypes.ZOMBIE, EntityZombie.class); + minecraftClassMap.put(EntityTypes.ZOMBIE_HORSE, EntityHorseZombie.class); + minecraftClassMap.put(EntityTypes.ZOMBIE_VILLAGER, EntityZombieVillager.class); + minecraftClassMap.put(EntityTypes.PHANTOM, EntityPhantom.class); + minecraftClassMap.put(EntityTypes.RAVAGER, EntityRavager.class); + minecraftClassMap.put(EntityTypes.FISHING_BOBBER, EntityFishingHook.class); + } +} \ No newline at end of file diff --git a/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/EntityRegister.java b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/EntityRegister.java new file mode 100644 index 0000000..1d62484 --- /dev/null +++ b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/EntityRegister.java @@ -0,0 +1,53 @@ +package eu.phiwa.dragontravel.nms.v1_16_R1; + +import eu.phiwa.dragontravel.core.DragonTravel; +import eu.phiwa.dragontravel.core.hooks.server.IEntityRegister; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; + +import net.minecraft.server.v1_16_R1.Entity; +import net.minecraft.server.v1_16_R1.EntityTypes; +import net.minecraft.server.v1_16_R1.MinecraftKey; + +public class EntityRegister implements IEntityRegister { + private static CustomEntityRegistry ENTITY_REGISTRY; + private static final Map, EntityTypes> DRAGONTRAVEL_ENTITY_TYPES = new HashMap, EntityTypes>(); + + /* + SOURCE : + https://github.com/CitizensDev/Citizens2/blob/master/v1_16_R1/src/main/java/net/citizensnpcs/nms/v1_16_R1/util/NMSImpl.java + */ + public void registerEntityClass(Class clazz) { + if (ENTITY_REGISTRY == null) + return; + + Class search = clazz; + while ((search = search.getSuperclass()) != null && Entity.class.isAssignableFrom(search)) { + EntityTypes type = ENTITY_REGISTRY.findType(search); + MinecraftKey key = ENTITY_REGISTRY.getKey(type); + if (key == null || type == null) + continue; + DRAGONTRAVEL_ENTITY_TYPES.put(clazz, type); + int code = ENTITY_REGISTRY.a(type); + ENTITY_REGISTRY.put(code, key, type); + return; + } + throw new IllegalArgumentException("unable to find valid entity superclass for class " + clazz.toString()); + } + + @Override + public boolean registerEntity() { + try { + registerEntityClass( RyeDragon.class ); + return true; + } catch (Exception e) { + Bukkit.getLogger().info("[DragonTravel] [Error] Could not register the RyeDragon-entity!"); + e.printStackTrace(); + Bukkit.getPluginManager().disablePlugin(DragonTravel.getInstance()); + } + return false; + } +} diff --git a/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/RyeDragon.java b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/RyeDragon.java new file mode 100644 index 0000000..9b4d6e9 --- /dev/null +++ b/src/main/java/eu/phiwa/dragontravel/nms/v1_16_R1/RyeDragon.java @@ -0,0 +1,517 @@ +package eu.phiwa.dragontravel.nms.v1_16_R1; + +import eu.phiwa.dragontravel.core.DragonTravel; +import eu.phiwa.dragontravel.core.hooks.server.IRyeDragon; +import eu.phiwa.dragontravel.core.movement.DragonType; +import eu.phiwa.dragontravel.core.movement.flight.Flight; +import net.minecraft.server.v1_16_R1.EntityEnderDragon; +import net.minecraft.server.v1_16_R1.World; +import net.minecraft.server.v1_16_R1.WorldServer; +import net.minecraft.server.v1_16_R1.EntityTypes; +import net.minecraft.server.v1_16_R1.BlockPosition; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_16_R1.util.CraftChatMessage; +import org.bukkit.craftbukkit.v1_16_R1.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.material.MaterialData; +import org.bukkit.util.Vector; + +public class RyeDragon extends EntityEnderDragon implements IRyeDragon { + + private final int wingCoolDown = 10; + private final int travelY = DragonTravel.getInstance().getConfigHandler().getTravelHeight(); + + private DragonType dragonType = DragonType.STATIONARY; + + private Player rider; + + // Source location + private Location fromLoc; + + // Target location + private Location toLoc; + + // Flight + private Flight flight; + private int currentWayPointIndex; + + // Travel + private Location midLocA; // Middle location source world + private Location midLocB; // Middle location target world + private boolean finalMove = false; + + private double xPerTick; + private double yPerTick; + private double zPerTick; + + public RyeDragon(Location loc) { + this(loc, ((CraftWorld) loc.getWorld()).getHandle()); + } + + public RyeDragon(Location loc, World notchWorld) { + super(EntityTypes.ENDER_DRAGON, notchWorld); + setPosition(loc.getX(), loc.getY(), loc.getZ()); + yaw = loc.getYaw() + 180; + pitch = 0f; + while (yaw > 360) + yaw -= 360; + while (yaw < 0) + yaw += 360; + notchWorld.addEntity(this); + } + + public RyeDragon(World notchWorld) { + super(EntityTypes.ENDER_DRAGON, notchWorld); + } + + + /** + * This method is a natural method of the Enderdragon extended by the RyeDragon. + * It's fired when the dragon moves and fires the travel-method again to keep the dragon flying. + */ + @Override + public void tick() { + if (getEntity() != null && rider != null) { + if (getEntity().getPassenger() != null) { + //getEntity().setPassenger(rider); //TODO: Reenable + } + rider.teleport(getEntity()); + } + + if (midLocA != null || toLoc != null) { + Vector a = fromLoc.toVector(); + Vector b = midLocA != null ? midLocA.toVector() : toLoc.toVector(); + double distX = b.getX() - a.getX(); + double distY = b.getY() - a.getY(); + double distZ = b.getZ() - a.getZ(); + + //vector trig functions have to be in rads... + float yaw = 0f, pitch = (float) -Math.atan(distY / Math.sqrt(distX * distX + distZ * distZ)); + + if (distX != 0) { + if (distX < 0) { + yaw = (float) (1.5 * Math.PI); + } else { + yaw = (float) (0.5 * Math.PI); + } + yaw = yaw - (float) Math.atan(distZ / distX); + } else if (distZ < 0) { + yaw = (float) Math.PI; + } + //back to degrees + setYawPitch(-yaw * 180F / (float) Math.PI - 180F, pitch * 180F / (float) Math.PI - 180F); + } + + switch (dragonType) { + case LOC_TRAVEL: + case HOME_TRAVEL: + case FACTION_TRAVEL: + case PLAYER_TRAVEL: + case STATION_TRAVEL: + travel(); + break; + case MANNED_FLIGHT: + case TIMED_FLIGHT: + flight(); + break; + default: + break; + } + } + + private void setX( double x ) { setPosition( x, locY(), locZ() ); } + private void setY( double y ) { setPosition( locX(), y, locZ() ); } + private void setZ( double z ) { setPosition( locX(), locY(), z ); } + + /** + * Controls the dragon + */ + @Override + public void flight() { + if ((int) locX() != flight.getWaypoints().get(currentWayPointIndex).getX()) + if (locX() < flight.getWaypoints().get(currentWayPointIndex).getX()) + setX( locX() + xPerTick ); + else + setX( locX() - xPerTick ); + if ((int) locY() != flight.getWaypoints().get(currentWayPointIndex).getY()) + if ((int) locY() < flight.getWaypoints().get(currentWayPointIndex).getY()) + setY( locY() + yPerTick ); + else + setY( locY() - yPerTick ); + if ((int) locZ() != flight.getWaypoints().get(currentWayPointIndex).getZ()) + if (locZ() < flight.getWaypoints().get(currentWayPointIndex).getZ()) + setZ( locZ() + zPerTick ); + else + setZ( locZ() - zPerTick ); + + if ((Math.abs((int) locZ() - flight.getWaypoints().get(currentWayPointIndex).getZ()) <= 3) && Math.abs((int) locX() - flight.getWaypoints().get(currentWayPointIndex).getX()) <= 3 && (Math.abs((int) locY() - flight.getWaypoints().get(currentWayPointIndex).getY()) <= 5)) { + if (currentWayPointIndex == flight.getWaypoints().size() - 1) { + DragonTravel.getInstance().getDragonManager().removeRiderAndDragon(getEntity(), flight.getWaypoints().get(currentWayPointIndex).getAsLocation()); + return; + } + + this.currentWayPointIndex++; + + this.fromLoc = getEntity().getLocation(); + this.toLoc = flight.getWaypoints().get(currentWayPointIndex).getAsLocation(); + + if (!flight.getWaypoints().get(currentWayPointIndex).getWorldName().equals(this.getEntity().getWorld().getName())) { + Location loc = flight.getWaypoints().get(currentWayPointIndex).getAsLocation(); + BlockPosition pos = new BlockPosition( loc.getX(), loc.getY(), loc.getZ() ); + // [1.15] this.teleportTo(this.dimension, pos); + // [1.16 (1)] this.teleportTo(this.world.getDimensionManager(), pos); + // [1.16 (2)] this.teleportTo((WorldServer)this.world), pos); + this.currentWayPointIndex++; + } + + setMoveFlight(); + } + } + + /** + * Sets the x,y,z move for each tick + */ + @Override + public void setMoveFlight() { + double distX = fromLoc.getX() - flight.getWaypoints().get(currentWayPointIndex).getX(); + double distY = fromLoc.getY() - flight.getWaypoints().get(currentWayPointIndex).getY(); + double distZ = fromLoc.getZ() - flight.getWaypoints().get(currentWayPointIndex).getZ(); + double tick = Math.sqrt((distX * distX) + (distY * distY) + + (distZ * distZ)) / DragonTravel.getInstance().getConfigHandler().getSpeed(); + this.xPerTick = Math.abs(distX) / tick; + this.yPerTick = Math.abs(distY) / tick; + this.zPerTick = Math.abs(distZ) / tick; + } + + /** + * Starts the specified flight + * + * @param flight Flight to start + */ + @Override + public void startFlight(Flight flight, DragonType dragonType) { + this.flight = flight; + this.currentWayPointIndex = 0; + this.dragonType = dragonType; + + this.toLoc = flight.getWaypoints().get(currentWayPointIndex).getAsLocation(); + this.fromLoc = getEntity().getLocation(); + + setMoveFlight(); + } + + /** + * Normal Travel + */ + @Override + public void travel() { + if (getEntity().getPassenger() == null) + return; + + double myX = locX(); + double myY = locY(); + double myZ = locZ(); + + if (finalMove) { + // Go down to destination + if ((int) locY() > (int) toLoc.getY()) + myY -= DragonTravel.getInstance().getConfigHandler().getSpeed(); + // Go up to destination + else if ((int) locY() < (int) toLoc.getY()) + myY += DragonTravel.getInstance().getConfigHandler().getSpeed(); + // Reached destination + else { + // Interworld travel, dragon reached temporary destination in target world + if (!getEntity().getWorld().getName().equals(toLoc.getWorld().getName())) { + this.rider = (Player) getEntity().getPassenger(); + midLocB.getChunk().load(); + + Bukkit.getScheduler().runTaskLater(DragonTravel.getInstance(), new Runnable() { + @Override + public void run() { + DragonTravel.getInstance().getDragonManager().dismount(rider, true); + if (midLocB.getZ() < toLoc.getZ()) + midLocB.setYaw((float) (-Math.toDegrees(Math.atan((midLocB.getX() - toLoc.getX()) / (midLocB.getZ() - toLoc.getZ()))))); + else if (midLocB.getZ() > toLoc.getZ()) + midLocB.setYaw((float) (-Math.toDegrees(Math.atan((midLocB.getX() - toLoc.getX()) / (midLocB.getZ() - toLoc.getZ())))) + 180.0F); + rider.teleport(midLocB); + if (!DragonTravel.getInstance().getDragonManager().mount(rider, false, dragonType)) + return; + if (!DragonTravel.getInstance().getDragonManager().getRiderDragons().containsKey(rider)) + return; + IRyeDragon dragon = DragonTravel.getInstance().getDragonManager().getRiderDragons().get(rider); + dragon.startTravel(toLoc, false, dragonType); + getEntity().remove(); + } + }, 1L); + } + // Dragon reached final destination + else { + DragonTravel.getInstance().getDragonManager().removeRiderAndDragon(getEntity(), true); + return; + } + } + + // Move player to new location on tick + setPosition(myX, myY, myZ); + + return; + } + + if ((int) locY() < travelY) + myY += DragonTravel.getInstance().getConfigHandler().getSpeed(); + + if (myX < toLoc.getX()) + myX += xPerTick; + else + myX -= xPerTick; + + if (myZ < toLoc.getZ()) + myZ += zPerTick; + else + myZ -= zPerTick; + + // For higher travel speeds the accuracy for dismounts needs + // to be decreased to prevent dragons from getting stuck + double maxDiff = DragonTravel.getInstance().getConfigHandler().getSpeed() + 1; + if (Math.abs(myZ - (int) toLoc.getZ()) <= maxDiff + && Math.abs(myX - (int) toLoc.getX()) <= maxDiff) { + finalMove = true; + } + setPosition(myX, myY, myZ); + } + + /** + * Sets the x,z move for each tick + */ + @Override + public void setMoveTravel() { + double dist; + double distX; + double distY; + double distZ; + if (midLocA != null) { + dist = fromLoc.distance(midLocA); + distX = fromLoc.getX() - midLocA.getX(); + distY = fromLoc.getY() - midLocA.getY(); + distZ = fromLoc.getZ() - midLocA.getZ(); + } else { + dist = fromLoc.distance(toLoc); + distX = fromLoc.getX() - toLoc.getX(); + distY = fromLoc.getY() - toLoc.getY(); + distZ = fromLoc.getZ() - toLoc.getZ(); + } + double tick = dist / DragonTravel.getInstance().getConfigHandler().getSpeed(); + xPerTick = Math.abs(distX) / tick; + zPerTick = Math.abs(distZ) / tick; + yPerTick = Math.abs(distY) / tick; + } + + /** + * Starts a travel to the specified location + * + * @param destLoc Location to start a travel to + */ + @Override + public void startTravel(Location destLoc, boolean interWorld, DragonType dragonType) { + this.dragonType = dragonType; + this.rider = (Player) getEntity().getPassenger(); + this.fromLoc = getEntity().getLocation(); + if (interWorld) { + this.midLocA = new Location(getEntity().getWorld(), locX() + 50 + Math.random() * 100, travelY, locZ() + 50 + Math.random() * 100); + int scatter = 80; + this.midLocB = destLoc.clone().add(scatter, scatter, scatter); + this.toLoc = destLoc; + } else { + this.toLoc = destLoc; + } + setMoveTravel(); + } + + @Override + public DragonType getDragonType() { + return dragonType; + } + + @Override + public Entity getEntity() { + if (getBukkitEntity() != null) + return getBukkitEntity(); + return null; + } + + /* + public double x_() { + return 3; + } + */ + + public void fixWings() { + // Artifact of old workaround for wings flipping really fast. + // Method stub is required for interface. + } + + public void setDragonType(DragonType dragonType) { + this.dragonType = dragonType; + } + + public int getWingCoolDown() { + return wingCoolDown; + } + + public Player getRider() { + return rider; + } + + public void setRider(Player rider) { + this.rider = rider; + } + + public Flight getFlight() { + return flight; + } + + public void setFlight(Flight flight) { + this.flight = flight; + } + + public int getCurrentWayPointIndex() { + return currentWayPointIndex; + } + + public void setCurrentWayPointIndex(int currentWayPointIndex) { + this.currentWayPointIndex = currentWayPointIndex; + } + + public boolean isFinalMove() { + return finalMove; + } + + public void setFinalMove(boolean finalMove) { + this.finalMove = finalMove; + } + + public int getTravelY() { + return travelY; + } + + public double getxPerTick() { + return xPerTick; + } + + public void setxPerTick(double xPerTick) { + this.xPerTick = xPerTick; + } + + public double getyPerTick() { + return yPerTick; + } + + public void setyPerTick(double yPerTick) { + this.yPerTick = yPerTick; + } + + public double getzPerTick() { + return zPerTick; + } + + public void setzPerTick(double zPerTick) { + this.zPerTick = zPerTick; + } + + private class WingFixerTask implements Runnable { + + private int id; + private int cooldown; + + public void setId(int id) { + this.id = id; + this.cooldown = wingCoolDown; + } + + @Override + public void run() { + cooldown -= 1; + if (cooldown <= 0) + Bukkit.getScheduler().cancelTask(id); + final Location loc = getEntity().getLocation().add(0, 2, 0); + final Material m[] = new Material[15]; + final MaterialData md[] = new MaterialData[15]; + + int counter = 0; + for (int y = 0; y <= 2; y++) { + for (int x = -1; x <= 1; x++) { + m[counter] = loc.clone().add(x, -y, 0).getBlock().getType(); + md[counter] = loc.clone().add(x, -y, 0).getBlock().getState().getData(); + loc.clone().add(x, -y, 0).getBlock().setType(Material.BARRIER); + counter++; + } + for (int z = -1; z <= 1; z++) { + if (z == 0 && y == 0) continue; + m[counter] = loc.clone().add(0, -y, z).getBlock().getType(); + md[counter] = loc.clone().add(0, -y, z).getBlock().getState().getData(); + loc.clone().add(0, -y, z).getBlock().setType(Material.BARRIER); + counter++; + } + if (y == 0) { + loc.getBlock().setType(Material.WATER); + } + if (y == 1) { + loc.clone().add(0, -1, 0).getBlock().setType(Material.AIR); + } + } + + Bukkit.getScheduler().runTaskLater(DragonTravel.getInstance(), new Runnable() { + @Override + public void run() { + int count = 0; + for (int y = 0; y <= 2; y++) { + for (int x = -1; x <= 1; x++) { + loc.clone().add(x, -y, 0).getBlock().setType(m[count]); + loc.clone().add(x, -y, 0).getBlock().getState().setData(md[count]); + count++; + } + for (int z = -1; z <= 1; z++) { + if (z == 0) continue; + loc.clone().add(0, -y, z).getBlock().setType(m[count]); + loc.clone().add(0, -y, z).getBlock().getState().setData(md[count]); + count++; + } + } + } + }, 20L); + } + } + + // Old (until CB 1_12_R1), now only a compatibility-wrapper for our code + public void setCustomDragonName(String name) { + net.minecraft.server.v1_16_R1.IChatBaseComponent nameInNewType = CraftChatMessage.fromString(name)[0]; // convert from "name" + + // Call new method + setCustomName(nameInNewType); + } + + // New (in CB 1_13_R1) + public void setCustomName(net.minecraft.server.v1_16_R1.IChatBaseComponent name) { + super.setCustomName(name); + } + + // Old (until CB 1_12_R1), now only a compatibility-wrapper for our code + public String getCustomDragonName() { + // Call new method + net.minecraft.server.v1_16_R1.IChatBaseComponent nameInNewType = getCustomName(); + String nameAsString = CraftChatMessage.fromComponent(nameInNewType); // convert from "nameInNewType" + return nameAsString; + } + + // New (in CB 1_13_R1) + public net.minecraft.server.v1_16_R1.IChatBaseComponent getCustomName() { + return super.getCustomName(); + } + +}