001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.bukkit.entity; 020 021import com.plotsquared.core.configuration.Settings; 022import org.apache.logging.log4j.LogManager; 023import org.apache.logging.log4j.Logger; 024import org.bukkit.Art; 025import org.bukkit.DyeColor; 026import org.bukkit.Location; 027import org.bukkit.Rotation; 028import org.bukkit.TreeSpecies; 029import org.bukkit.World; 030import org.bukkit.block.BlockFace; 031import org.bukkit.entity.AbstractHorse; 032import org.bukkit.entity.Ageable; 033import org.bukkit.entity.ArmorStand; 034import org.bukkit.entity.Bat; 035import org.bukkit.entity.Boat; 036import org.bukkit.entity.ChestedHorse; 037import org.bukkit.entity.EnderDragon; 038import org.bukkit.entity.Entity; 039import org.bukkit.entity.IronGolem; 040import org.bukkit.entity.Item; 041import org.bukkit.entity.ItemFrame; 042import org.bukkit.entity.LivingEntity; 043import org.bukkit.entity.Painting; 044import org.bukkit.entity.Rabbit; 045import org.bukkit.entity.Sheep; 046import org.bukkit.entity.Slime; 047import org.bukkit.entity.Tameable; 048import org.bukkit.inventory.EntityEquipment; 049import org.bukkit.inventory.InventoryHolder; 050import org.bukkit.inventory.ItemStack; 051import org.bukkit.util.EulerAngle; 052import org.bukkit.util.Vector; 053 054import java.util.List; 055 056public final class ReplicatingEntityWrapper extends EntityWrapper { 057 058 private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + ReplicatingEntityWrapper.class.getSimpleName()); 059 060 private final short depth; 061 private final int hash; 062 private final EntityBaseStats base = new EntityBaseStats(); 063 064 private ItemStack[] inventory; 065 // Extended 066 private ItemStack stack; 067 private byte dataByte; 068 private byte dataByte2; 069 private String dataString; 070 private LivingEntityStats lived; 071 private AgeableStats aged; 072 private TameableStats tamed; 073 private ArmorStandStats stand; 074 private HorseStats horse; 075 private boolean noGravity; 076 077 public ReplicatingEntityWrapper(Entity entity, short depth) { 078 super(entity); 079 080 this.hash = entity.getEntityId(); 081 this.depth = depth; 082 083 if (depth == 0) { 084 return; 085 } 086 List<Entity> passengers = entity.getPassengers(); 087 if (passengers.size() > 0) { 088 this.base.passenger = new ReplicatingEntityWrapper(passengers.get(0), depth); 089 } 090 this.base.fall = entity.getFallDistance(); 091 this.base.fire = (short) entity.getFireTicks(); 092 this.base.age = entity.getTicksLived(); 093 Vector velocity = entity.getVelocity(); 094 this.base.vX = velocity.getX(); 095 this.base.vY = velocity.getY(); 096 this.base.vZ = velocity.getZ(); 097 if (depth == 1) { 098 return; 099 } 100 if (!entity.hasGravity()) { 101 this.noGravity = true; 102 } 103 switch (entity.getType().toString()) { 104 case "BOAT": 105 Boat boat = (Boat) entity; 106 this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); 107 return; 108 case "ARROW": 109 case "EGG": 110 case "ENDER_CRYSTAL": 111 case "ENDER_PEARL": 112 case "ENDER_SIGNAL": 113 case "EXPERIENCE_ORB": 114 case "FALLING_BLOCK": 115 case "FIREBALL": 116 case "FIREWORK": 117 case "FISHING_HOOK": 118 case "LEASH_HITCH": 119 case "LIGHTNING": 120 case "MINECART": 121 case "MINECART_COMMAND": 122 case "MINECART_MOB_SPAWNER": 123 case "MINECART_TNT": 124 case "PLAYER": 125 case "PRIMED_TNT": 126 case "SLIME": 127 case "SMALL_FIREBALL": 128 case "SNOWBALL": 129 case "MINECART_FURNACE": 130 case "SPLASH_POTION": 131 case "THROWN_EXP_BOTTLE": 132 case "WITHER_SKULL": 133 case "UNKNOWN": 134 case "SPECTRAL_ARROW": 135 case "SHULKER_BULLET": 136 case "DRAGON_FIREBALL": 137 case "AREA_EFFECT_CLOUD": 138 case "TRIDENT": 139 case "LLAMA_SPIT": 140 // Do this stuff later 141 return; 142 // MISC // 143 case "DROPPED_ITEM": 144 Item item = (Item) entity; 145 this.stack = item.getItemStack(); 146 return; 147 case "ITEM_FRAME": 148 this.x = Math.floor(this.getX()); 149 this.y = Math.floor(this.getY()); 150 this.z = Math.floor(this.getZ()); 151 ItemFrame itemFrame = (ItemFrame) entity; 152 this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation()); 153 this.stack = itemFrame.getItem().clone(); 154 return; 155 case "PAINTING": 156 this.x = Math.floor(this.getX()); 157 this.y = Math.floor(this.getY()); 158 this.z = Math.floor(this.getZ()); 159 Painting painting = (Painting) entity; 160 Art art = painting.getArt(); 161 this.dataByte = getOrdinal(BlockFace.values(), painting.getFacing()); 162 int h = art.getBlockHeight(); 163 if (h % 2 == 0) { 164 this.y -= 1; 165 } 166 this.dataString = art.name(); 167 return; 168 // END MISC // 169 // INVENTORY HOLDER // 170 case "MINECART_CHEST": 171 case "MINECART_HOPPER": 172 storeInventory((InventoryHolder) entity); 173 return; 174 // START LIVING ENTITY // 175 // START AGEABLE // 176 // START TAMEABLE // 177 case "HORSE": 178 case "DONKEY": 179 case "LLAMA": 180 case "MULE": 181 case "SKELETON_HORSE": 182 AbstractHorse horse = (AbstractHorse) entity; 183 this.horse = new HorseStats(); 184 this.horse.jump = horse.getJumpStrength(); 185 if (horse instanceof ChestedHorse horse1) { 186 this.horse.chest = horse1.isCarryingChest(); 187 } 188 //todo these horse features need fixing 189 //this.horse.variant = horse.getVariant(); 190 //this.horse.style = horse.getStyle(); 191 //this.horse.color = horse.getColor(); 192 storeTameable(horse); 193 storeAgeable(horse); 194 storeLiving(horse); 195 storeInventory(horse); 196 return; 197 // END INVENTORY HOLDER // 198 case "WOLF": 199 case "OCELOT": 200 storeTameable((Tameable) entity); 201 storeAgeable((Ageable) entity); 202 storeLiving((LivingEntity) entity); 203 return; 204 // END TAMEABLE // 205 //todo fix sheep 206 case "SHEEP": 207 Sheep sheep = (Sheep) entity; 208 if (sheep.isSheared()) { 209 this.dataByte = (byte) 1; 210 } else { 211 this.dataByte = (byte) 0; 212 } 213 this.dataByte2 = sheep.getColor().getDyeData(); 214 storeAgeable(sheep); 215 storeLiving(sheep); 216 return; 217 case "VILLAGER": 218 case "CHICKEN": 219 case "COW": 220 case "MUSHROOM_COW": 221 case "PIG": 222 case "TURTLE": 223 case "POLAR_BEAR": 224 storeAgeable((Ageable) entity); 225 storeLiving((LivingEntity) entity); 226 return; 227 case "RABBIT": 228 this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); 229 storeAgeable((Ageable) entity); 230 storeLiving((LivingEntity) entity); 231 return; 232 // END AGEABLE // 233 case "ARMOR_STAND": 234 ArmorStand stand = (ArmorStand) entity; 235 this.inventory = 236 new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(), 237 stand.getChestplate().clone(), stand.getLeggings().clone(), 238 stand.getBoots().clone()}; 239 storeLiving(stand); 240 this.stand = new ArmorStandStats(); 241 242 EulerAngle head = stand.getHeadPose(); 243 this.stand.head[0] = (float) head.getX(); 244 this.stand.head[1] = (float) head.getY(); 245 this.stand.head[2] = (float) head.getZ(); 246 247 EulerAngle body = stand.getBodyPose(); 248 this.stand.body[0] = (float) body.getX(); 249 this.stand.body[1] = (float) body.getY(); 250 this.stand.body[2] = (float) body.getZ(); 251 252 EulerAngle leftLeg = stand.getLeftLegPose(); 253 this.stand.leftLeg[0] = (float) leftLeg.getX(); 254 this.stand.leftLeg[1] = (float) leftLeg.getY(); 255 this.stand.leftLeg[2] = (float) leftLeg.getZ(); 256 257 EulerAngle rightLeg = stand.getRightLegPose(); 258 this.stand.rightLeg[0] = (float) rightLeg.getX(); 259 this.stand.rightLeg[1] = (float) rightLeg.getY(); 260 this.stand.rightLeg[2] = (float) rightLeg.getZ(); 261 262 EulerAngle leftArm = stand.getLeftArmPose(); 263 this.stand.leftArm[0] = (float) leftArm.getX(); 264 this.stand.leftArm[1] = (float) leftArm.getY(); 265 this.stand.leftArm[2] = (float) leftArm.getZ(); 266 267 EulerAngle rightArm = stand.getRightArmPose(); 268 this.stand.rightArm[0] = (float) rightArm.getX(); 269 this.stand.rightArm[1] = (float) rightArm.getY(); 270 this.stand.rightArm[2] = (float) rightArm.getZ(); 271 272 if (stand.hasArms()) { 273 this.stand.arms = true; 274 } 275 if (!stand.hasBasePlate()) { 276 this.stand.noPlate = true; 277 } 278 if (!stand.isVisible()) { 279 this.stand.invisible = true; 280 } 281 if (stand.isSmall()) { 282 this.stand.small = true; 283 } 284 return; 285 case "ENDERMITE": 286 return; 287 case "BAT": 288 if (((Bat) entity).isAwake()) { 289 this.dataByte = (byte) 1; 290 } else { 291 this.dataByte = (byte) 0; 292 } 293 return; 294 case "ENDER_DRAGON": 295 EnderDragon entity1 = (EnderDragon) entity; 296 this.dataByte = (byte) entity1.getPhase().ordinal(); 297 return; 298 case "SKELETON": 299 case "WITHER_SKELETON": 300 case "GUARDIAN": 301 case "ELDER_GUARDIAN": 302 case "GHAST": 303 case "MAGMA_CUBE": 304 case "SQUID": 305 case "PIG_ZOMBIE": 306 case "HOGLIN": 307 case "ZOMBIFIED_PIGLIN": 308 case "PIGLIN": 309 case "PIGLIN_BRUTE": 310 case "ZOMBIE": 311 case "WITHER": 312 case "WITCH": 313 case "SPIDER": 314 case "CAVE_SPIDER": 315 case "SILVERFISH": 316 case "GIANT": 317 case "ENDERMAN": 318 case "CREEPER": 319 case "BLAZE": 320 case "SHULKER": 321 case "SNOWMAN": 322 storeLiving((LivingEntity) entity); 323 return; 324 case "IRON_GOLEM": 325 if (((IronGolem) entity).isPlayerCreated()) { 326 this.dataByte = (byte) 1; 327 } else { 328 this.dataByte = (byte) 0; 329 } 330 storeLiving((LivingEntity) entity); 331 // END LIVING // 332 } 333 } 334 335 @Override 336 public boolean equals(Object obj) { 337 return this.hash == obj.hashCode(); 338 } 339 340 @Override 341 public int hashCode() { 342 return this.hash; 343 } 344 345 public void storeInventory(InventoryHolder held) { 346 this.inventory = held.getInventory().getContents().clone(); 347 } 348 349 void restoreLiving(LivingEntity entity) { 350 entity.setCanPickupItems(this.lived.loot); 351 if (this.lived.name != null) { 352 entity.setCustomName(this.lived.name); 353 entity.setCustomNameVisible(this.lived.visible); 354 } 355 if (this.lived.potions != null && !this.lived.potions.isEmpty()) { 356 entity.addPotionEffects(this.lived.potions); 357 } 358 entity.setRemainingAir(this.lived.air); 359 entity.setRemoveWhenFarAway(this.lived.persistent); 360 if (this.lived.equipped) { 361 this.restoreEquipment(entity); 362 } 363 if (this.lived.leashed) { 364 // TODO leashes 365 // World world = entity.getWorld(); 366 // Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + 367 // lived.leashX, Math.floor(y) + lived.leashY, Math.floor(z) + lived.leashZ), 368 // EntityType.LEASH_HITCH); 369 // entity.setLeashHolder(leash); 370 } 371 } 372 373 void restoreEquipment(LivingEntity entity) { 374 EntityEquipment equipment = entity.getEquipment(); 375 if (equipment != null) { 376 equipment.setItemInMainHand(this.lived.mainHand); 377 equipment.setItemInOffHand(this.lived.offHand); 378 equipment.setHelmet(this.lived.helmet); 379 equipment.setChestplate(this.lived.chestplate); 380 equipment.setLeggings(this.lived.leggings); 381 equipment.setBoots(this.lived.boots); 382 } 383 } 384 385 private void restoreInventory(InventoryHolder entity) { 386 try { 387 entity.getInventory().setContents(this.inventory); 388 } catch (IllegalArgumentException e) { 389 LOGGER.error("Failed to restore inventory", e); 390 } 391 } 392 393 private void storeLiving(LivingEntity lived) { 394 this.lived = new LivingEntityStats(); 395 this.lived.potions = lived.getActivePotionEffects(); 396 this.lived.loot = lived.getCanPickupItems(); 397 this.lived.name = lived.getCustomName(); 398 this.lived.visible = lived.isCustomNameVisible(); 399 this.lived.health = (float) lived.getHealth(); 400 this.lived.air = (short) lived.getRemainingAir(); 401 this.lived.persistent = lived.getRemoveWhenFarAway(); 402 this.lived.leashed = lived.isLeashed(); 403 if (this.lived.leashed) { 404 Location location = lived.getLeashHolder().getLocation(); 405 this.lived.leashX = (short) (this.getX() - location.getBlockX()); 406 this.lived.leashY = (short) (this.getY() - location.getBlockY()); 407 this.lived.leashZ = (short) (this.getZ() - location.getBlockZ()); 408 } 409 EntityEquipment equipment = lived.getEquipment(); 410 this.lived.equipped = equipment != null; 411 if (this.lived.equipped) { 412 storeEquipment(equipment); 413 } 414 } 415 416 void storeEquipment(EntityEquipment equipment) { 417 this.lived.mainHand = equipment.getItemInMainHand().clone(); 418 this.lived.offHand = equipment.getItemInOffHand().clone(); 419 this.lived.boots = equipment.getBoots().clone(); 420 this.lived.leggings = equipment.getLeggings().clone(); 421 this.lived.chestplate = equipment.getChestplate().clone(); 422 this.lived.helmet = equipment.getHelmet().clone(); 423 } 424 425 private void restoreTameable(Tameable entity) { 426 if (this.tamed.tamed) { 427 if (this.tamed.owner != null) { 428 entity.setTamed(true); 429 entity.setOwner(this.tamed.owner); 430 } 431 } 432 } 433 434 private void restoreAgeable(Ageable entity) { 435 if (!this.aged.adult) { 436 entity.setBaby(); 437 } 438 entity.setAgeLock(this.aged.locked); 439 if (this.aged.age > 0) { 440 entity.setAge(this.aged.age); 441 } 442 } 443 444 public void storeAgeable(Ageable aged) { 445 this.aged = new AgeableStats(); 446 this.aged.age = aged.getAge(); 447 this.aged.locked = aged.getAgeLock(); 448 this.aged.adult = aged.isAdult(); 449 } 450 451 public void storeTameable(Tameable tamed) { 452 this.tamed = new TameableStats(); 453 this.tamed.owner = tamed.getOwner(); 454 this.tamed.tamed = tamed.isTamed(); 455 } 456 457 @SuppressWarnings("deprecation") // Paper deprecation 458 @Override 459 public Entity spawn(World world, int xOffset, int zOffset) { 460 Location location = new Location(world, this.getX() + xOffset, this.getY(), this.z + zOffset); 461 location.setYaw(this.yaw); 462 location.setPitch(this.pitch); 463 if (!this.getType().isSpawnable()) { 464 return null; 465 } 466 Entity entity; 467 switch (this.getType().toString()) { 468 case "DROPPED_ITEM": 469 return world.dropItem(location, this.stack); 470 case "PLAYER": 471 case "LEASH_HITCH": 472 return null; 473 case "ITEM_FRAME": 474 entity = world.spawn(location, ItemFrame.class); 475 break; 476 case "PAINTING": 477 entity = world.spawn(location, Painting.class); 478 break; 479 default: 480 entity = world.spawnEntity(location, this.getType()); 481 break; 482 } 483 if (this.depth == 0) { 484 return entity; 485 } 486 if (this.base.passenger != null) { 487 try { 488 entity.addPassenger(this.base.passenger.spawn(world, xOffset, zOffset)); 489 } catch (Exception ignored) { 490 } 491 } 492 if (this.base.fall != 0) { 493 entity.setFallDistance(this.base.fall); 494 } 495 if (this.base.fire != 0) { 496 entity.setFireTicks(this.base.fire); 497 } 498 if (this.base.age != 0) { 499 entity.setTicksLived(this.base.age); 500 } 501 entity.setVelocity(new Vector(this.base.vX, this.base.vY, this.base.vZ)); 502 if (this.depth == 1) { 503 return entity; 504 } 505 if (this.noGravity) { 506 entity.setGravity(false); 507 } 508 switch (entity.getType().toString()) { 509 case "BOAT": 510 Boat boat = (Boat) entity; 511 boat.setWoodType(TreeSpecies.values()[dataByte]); 512 return entity; 513 case "SLIME": 514 ((Slime) entity).setSize(this.dataByte); 515 return entity; 516 case "ARROW": 517 case "EGG": 518 case "ENDER_CRYSTAL": 519 case "ENDER_PEARL": 520 case "ENDER_SIGNAL": 521 case "DROPPED_ITEM": 522 case "EXPERIENCE_ORB": 523 case "FALLING_BLOCK": 524 case "FIREBALL": 525 case "FIREWORK": 526 case "FISHING_HOOK": 527 case "LEASH_HITCH": 528 case "LIGHTNING": 529 case "MINECART": 530 case "MINECART_COMMAND": 531 case "MINECART_MOB_SPAWNER": 532 case "MINECART_TNT": 533 case "PLAYER": 534 case "PRIMED_TNT": 535 case "SMALL_FIREBALL": 536 case "SNOWBALL": 537 case "SPLASH_POTION": 538 case "THROWN_EXP_BOTTLE": 539 case "SPECTRAL_ARROW": 540 case "SHULKER_BULLET": 541 case "AREA_EFFECT_CLOUD": 542 case "DRAGON_FIREBALL": 543 case "WITHER_SKULL": 544 case "MINECART_FURNACE": 545 case "LLAMA_SPIT": 546 case "TRIDENT": 547 case "UNKNOWN": 548 // Do this stuff later 549 return entity; 550 // MISC // 551 case "ITEM_FRAME": 552 ItemFrame itemframe = (ItemFrame) entity; 553 itemframe.setRotation(Rotation.values()[this.dataByte]); 554 itemframe.setItem(this.stack); 555 return entity; 556 case "PAINTING": 557 Painting painting = (Painting) entity; 558 painting.setFacingDirection(BlockFace.values()[this.dataByte], true); 559 painting.setArt(Art.getByName(this.dataString), true); 560 return entity; 561 // END MISC // 562 // INVENTORY HOLDER // 563 case "MINECART_CHEST": 564 case "MINECART_HOPPER": 565 restoreInventory((InventoryHolder) entity); 566 return entity; 567 // START LIVING ENTITY // 568 // START AGEABLE // 569 // START TAMEABLE // 570 case "HORSE": 571 case "LLAMA": 572 case "SKELETON_HORSE": 573 case "DONKEY": 574 case "MULE": 575 AbstractHorse horse = (AbstractHorse) entity; 576 horse.setJumpStrength(this.horse.jump); 577 if (horse instanceof ChestedHorse) { 578 ((ChestedHorse) horse).setCarryingChest(this.horse.chest); 579 } 580 //todo broken as of 1.13 581 //horse.setVariant(this.horse.variant); 582 //horse.setStyle(this.horse.style); 583 //horse.setColor(this.horse.color); 584 restoreTameable(horse); 585 restoreAgeable(horse); 586 restoreLiving(horse); 587 restoreInventory(horse); 588 return entity; 589 // END INVENTORY HOLDER // 590 case "WOLF": 591 case "OCELOT": 592 restoreTameable((Tameable) entity); 593 restoreAgeable((Ageable) entity); 594 restoreLiving((LivingEntity) entity); 595 return entity; 596 // END AGEABLE // 597 case "SHEEP": 598 Sheep sheep = (Sheep) entity; 599 if (this.dataByte == 1) { 600 sheep.setSheared(true); 601 } 602 if (this.dataByte2 != 0) { 603 sheep.setColor(DyeColor.getByDyeData(this.dataByte2)); 604 } 605 restoreAgeable(sheep); 606 restoreLiving(sheep); 607 return sheep; 608 case "VILLAGER": 609 case "CHICKEN": 610 case "COW": 611 case "TURTLE": 612 case "POLAR_BEAR": 613 case "MUSHROOM_COW": 614 case "PIG": 615 restoreAgeable((Ageable) entity); 616 restoreLiving((LivingEntity) entity); 617 return entity; 618 // END AGEABLE // 619 case "RABBIT": 620 if (this.dataByte != 0) { 621 ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); 622 } 623 restoreAgeable((Ageable) entity); 624 restoreLiving((LivingEntity) entity); 625 return entity; 626 case "ARMOR_STAND": 627 // CHECK positions 628 ArmorStand stand = (ArmorStand) entity; 629 if (this.inventory[0] != null) { 630 stand.setItemInHand(this.inventory[0]); 631 } 632 if (this.inventory[1] != null) { 633 stand.setHelmet(this.inventory[1]); 634 } 635 if (this.inventory[2] != null) { 636 stand.setChestplate(this.inventory[2]); 637 } 638 if (this.inventory[3] != null) { 639 stand.setLeggings(this.inventory[3]); 640 } 641 if (this.inventory[4] != null) { 642 stand.setBoots(this.inventory[4]); 643 } 644 if (this.stand.head[0] != 0 || this.stand.head[1] != 0 || this.stand.head[2] != 0) { 645 EulerAngle pose = 646 new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]); 647 stand.setHeadPose(pose); 648 } 649 if (this.stand.body[0] != 0 || this.stand.body[1] != 0 || this.stand.body[2] != 0) { 650 EulerAngle pose = 651 new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]); 652 stand.setBodyPose(pose); 653 } 654 if (this.stand.leftLeg[0] != 0 || this.stand.leftLeg[1] != 0 655 || this.stand.leftLeg[2] != 0) { 656 EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1], 657 this.stand.leftLeg[2] 658 ); 659 stand.setLeftLegPose(pose); 660 } 661 if (this.stand.rightLeg[0] != 0 || this.stand.rightLeg[1] != 0 662 || this.stand.rightLeg[2] != 0) { 663 EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1], 664 this.stand.rightLeg[2] 665 ); 666 stand.setRightLegPose(pose); 667 } 668 if (this.stand.leftArm[0] != 0 || this.stand.leftArm[1] != 0 669 || this.stand.leftArm[2] != 0) { 670 EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1], 671 this.stand.leftArm[2] 672 ); 673 stand.setLeftArmPose(pose); 674 } 675 if (this.stand.rightArm[0] != 0 || this.stand.rightArm[1] != 0 676 || this.stand.rightArm[2] != 0) { 677 EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1], 678 this.stand.rightArm[2] 679 ); 680 stand.setRightArmPose(pose); 681 } 682 if (this.stand.invisible) { 683 stand.setVisible(false); 684 } 685 if (this.stand.arms) { 686 stand.setArms(true); 687 } 688 if (this.stand.noPlate) { 689 stand.setBasePlate(false); 690 } 691 if (this.stand.small) { 692 stand.setSmall(true); 693 } 694 restoreLiving(stand); 695 return stand; 696 case "BAT": 697 if (this.dataByte != 0) { 698 ((Bat) entity).setAwake(true); 699 } 700 restoreLiving((LivingEntity) entity); 701 return entity; 702 case "ENDER_DRAGON": 703 if (this.dataByte != 0) { 704 ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]); 705 } 706 restoreLiving((LivingEntity) entity); 707 return entity; 708 case "ENDERMITE": 709 case "GHAST": 710 case "MAGMA_CUBE": 711 case "SQUID": 712 case "PIG_ZOMBIE": 713 case "HOGLIN": 714 case "PIGLIN": 715 case "ZOMBIFIED_PIGLIN": 716 case "PIGLIN_BRUTE": 717 case "ZOMBIE": 718 case "WITHER": 719 case "WITCH": 720 case "SPIDER": 721 case "CAVE_SPIDER": 722 case "SILVERFISH": 723 case "GIANT": 724 case "ENDERMAN": 725 case "CREEPER": 726 case "BLAZE": 727 case "SNOWMAN": 728 case "SHULKER": 729 case "GUARDIAN": 730 case "ELDER_GUARDIAN": 731 case "SKELETON": 732 case "WITHER_SKELETON": 733 restoreLiving((LivingEntity) entity); 734 return entity; 735 case "IRON_GOLEM": 736 if (this.dataByte != 0) { 737 ((IronGolem) entity).setPlayerCreated(true); 738 } 739 restoreLiving((LivingEntity) entity); 740 return entity; 741 default: 742 if (Settings.DEBUG) { 743 LOGGER.info("Could not identify entity: {}", entity.getType()); 744 } 745 return entity; 746 // END LIVING 747 } 748 } 749 750 public void saveEntity() { 751 } 752 753 private byte getOrdinal(Object[] list, Object value) { 754 for (byte i = 0; i < list.length; i++) { 755 if (list[i].equals(value)) { 756 return i; 757 } 758 } 759 return 0; 760 } 761 762 763}